From: george anzinger <george@mvista.com>
To: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: Linus <torvalds@transmeta.com>,
LKML <linux-kernel@vger.kernel.org>,
anton@samba.org, "David S. Miller" <davem@redhat.com>,
ak@muc.de, davidm@hpl.hp.com, schwidefsky@de.ibm.com,
ralf@gnu.org, willy@debian.org
Subject: Re: [PATCH] compatibility syscall layer (lets try again)
Date: Wed, 04 Dec 2002 11:56:17 -0800 [thread overview]
Message-ID: <3DEE5DE1.762699E3@mvista.com> (raw)
In-Reply-To: 20021204180224.406d143c.sfr@canb.auug.org.au
Stephen Rothwell wrote:
>
> Hi Linus,
>
> Below is the generic part of the start of the compatibility syscall layer.
> I think I have made it generic enough that each architecture can define
> what compatibility means.
>
> To use this,an architecture must create asm/compat.h and provide typedefs
> for (currently) compat_time_t, compat_suseconds_t, struct compat_timespec.
>
> Hopefully, this is what you had in mind - ohterwise back to the drawing
> board.
>
> I will follow this posting with the architecture specific patches that I
> have done but not tested.
The standard for POSIX nano_sleep() says that it should not
return on a signal UNLESS the signal is delivered to the
user. (I.e. not on SIGSTOP, SIGTRACE, etc. or any signal
that does not invoke a user handler.) To do this sort of
thing the do_signal() function returns true in this case and
otherwise false. The reason this is not in nano_sleep()
today seems to be that do_signal() requires ®s which
differs from arch to arch in how it is passed to a system
call handler. The common code does not need or use regs
except to pass it to do_signal().
As a suggestion for a solution for this, is it true that
regs, on a system call, will ALWAYS be at the end of the
stack? Lets assume, at least for nano_sleep, that it will
not be called from the kernel. Even if it is, what should
signal behavior be in this case? Should it not use the user
regs?
Here is a suggested function to get the regs:
struct pt_regs *get_task_registers(struct task_struct* task)
{
return (struct pt_regs *)((unsigned char
*)task->thread.esp0 -
sizeof(struct pt_regs));
}
comments?
>
> --
> Cheers,
> Stephen Rothwell sfr@canb.auug.org.au
> http://www.canb.auug.org.au/~sfr/
>
> diff -ruN 2.5.50-BK.2/fs/open.c 2.5.50-BK.2-32bit.1/fs/open.c
> --- 2.5.50-BK.2/fs/open.c 2002-12-04 12:07:36.000000000 +1100
> +++ 2.5.50-BK.2-32bit.1/fs/open.c 2002-12-04 12:01:36.000000000 +1100
> @@ -280,7 +280,7 @@
> * must be owner or have write permission.
> * Else, update from *times, must be owner or super user.
> */
> -asmlinkage long sys_utimes(char * filename, struct timeval * utimes)
> +long do_utimes(char * filename, struct timeval * times)
> {
> int error;
> struct nameidata nd;
> @@ -299,11 +299,7 @@
>
> /* Don't worry, the checks are done in inode_change_ok() */
> newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
> - if (utimes) {
> - struct timeval times[2];
> - error = -EFAULT;
> - if (copy_from_user(×, utimes, sizeof(times)))
> - goto dput_and_out;
> + if (times) {
> newattrs.ia_atime.tv_sec = times[0].tv_sec;
> newattrs.ia_atime.tv_nsec = times[0].tv_usec * 1000;
> newattrs.ia_mtime.tv_sec = times[1].tv_sec;
> @@ -323,6 +319,16 @@
> return error;
> }
>
> +asmlinkage long sys_utimes(char * filename, struct timeval * utimes)
> +{
> + struct timeval times[2];
> +
> + if (utimes && copy_from_user(×, utimes, sizeof(times)))
> + return -EFAULT;
> + return do_utimes(filename, utimes ? times : NULL);
> +}
> +
> +
> /*
> * access() needs to use the real uid/gid, not the effective uid/gid.
> * We do this by temporarily clearing all FS-related capabilities and
> diff -ruN 2.5.50-BK.2/include/linux/compat.h 2.5.50-BK.2-32bit.1/include/linux/compat.h
> --- 2.5.50-BK.2/include/linux/compat.h 1970-01-01 10:00:00.000000000 +1000
> +++ 2.5.50-BK.2-32bit.1/include/linux/compat.h 2002-12-04 15:42:36.000000000 +1100
> @@ -0,0 +1,29 @@
> +#ifndef _LINUX_COMPAT_H
> +#define _LINUX_COMPAT_H
> +/*
> + * These are the type definitions for the arhitecure sepcific
> + * compatibility layer.
> + */
> +#include <linux/config.h>
> +
> +#ifdef CONFIG_COMPAT
> +
> +#include <asm/compat.h>
> +
> +struct compat_timeval {
> + compat_time_t tv_sec;
> + compat_suseconds_t tv_usec;
> +};
> +
> +struct compat_utimbuf {
> + compat_time_t actime;
> + compat_time_t modtime;
> +};
> +
> +struct compat_itimerval {
> + struct compat_timeval it_interval;
> + struct compat_timeval it_value;
> +};
> +
> +#endif /* CONFIG_COMPAT */
> +#endif /* _LINUX_COMPAT_H */
> diff -ruN 2.5.50-BK.2/include/linux/time.h 2.5.50-BK.2-32bit.1/include/linux/time.h
> --- 2.5.50-BK.2/include/linux/time.h 2002-11-18 15:47:56.000000000 +1100
> +++ 2.5.50-BK.2-32bit.1/include/linux/time.h 2002-12-03 15:47:26.000000000 +1100
> @@ -138,6 +138,8 @@
> #ifdef __KERNEL__
> extern void do_gettimeofday(struct timeval *tv);
> extern void do_settimeofday(struct timeval *tv);
> +extern long do_nanosleep(struct timespec *t);
> +extern long do_utimes(char * filename, struct timeval * times);
> #endif
>
> #define FD_SETSIZE __FD_SETSIZE
> diff -ruN 2.5.50-BK.2/kernel/Makefile 2.5.50-BK.2-32bit.1/kernel/Makefile
> --- 2.5.50-BK.2/kernel/Makefile 2002-11-28 10:34:59.000000000 +1100
> +++ 2.5.50-BK.2-32bit.1/kernel/Makefile 2002-12-03 15:42:28.000000000 +1100
> @@ -21,6 +21,7 @@
> obj-$(CONFIG_CPU_FREQ) += cpufreq.o
> obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
> obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o
> +obj-$(CONFIG_COMPAT) += compat.o
>
> ifneq ($(CONFIG_IA64),y)
> # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
> diff -ruN 2.5.50-BK.2/kernel/compat.c 2.5.50-BK.2-32bit.1/kernel/compat.c
> --- 2.5.50-BK.2/kernel/compat.c 1970-01-01 10:00:00.000000000 +1000
> +++ 2.5.50-BK.2-32bit.1/kernel/compat.c 2002-12-04 17:40:08.000000000 +1100
> @@ -0,0 +1,114 @@
> +/*
> + * linux/kernel/compat.c
> + *
> + * Kernel compatibililty routines for e.g. 32 bit syscall support
> + * on 64 bit kernels.
> + *
> + * Copyright (C) 2002 Stephen Rothwell, IBM Corporation
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/linkage.h>
> +#include <linux/compat.h>
> +#include <linux/errno.h>
> +#include <linux/time.h>
> +
> +#include <asm/uaccess.h>
> +
> +asmlinkage long compat_sys_nanosleep(struct compat_timespec *rqtp,
> + struct compat_timespec *rmtp)
> +{
> + struct timespec t;
> + struct compat_timespec ct;
> + s32 ret;
> +
> + if (copy_from_user(&ct, rqtp, sizeof(ct)))
> + return -EFAULT;
> + t.tv_sec = ct.tv_sec;
> + t.tv_nsec = ct.tv_nsec;
> + ret = do_nanosleep(&t);
> + if (rmtp && (ret == -EINTR)) {
> + ct.tv_sec = t.tv_sec;
> + ct.tv_nsec = t.tv_nsec;
> + if (copy_to_user(rmtp, &ct, sizeof(ct)))
> + return -EFAULT;
> + }
> + return ret;
> +}
> +
> +/*
> + * Not all architectures have sys_utime, so implement this in terms
> + * of sys_utimes.
> + */
> +asmlinkage long compat_sys_utime(char *filename, struct compat_utimbuf *t)
> +{
> + struct timeval tv[2];
> +
> + if (t) {
> + if (get_user(tv[0].tv_sec, &t->actime) ||
> + get_user(tv[1].tv_sec, &t->modtime))
> + return -EFAULT;
> + tv[0].tv_usec = 0;
> + tv[1].tv_usec = 0;
> + }
> + return do_utimes(filename, t ? tv : NULL);
> +}
> +
> +
> +static inline long get_compat_itimerval(struct itimerval *o,
> + struct compat_itimerval *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_compat_itimerval(struct compat_itimerval *o,
> + struct itimerval *i)
> +{
> + return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
> + (__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)));
> +}
> +
> +extern int do_getitimer(int which, struct itimerval *value);
> +
> +asmlinkage long compat_sys_getitimer(int which, struct compat_itimerval *it)
> +{
> + struct itimerval kit;
> + int error;
> +
> + error = do_getitimer(which, &kit);
> + if (!error && put_compat_itimerval(it, &kit))
> + error = -EFAULT;
> + return error;
> +}
> +
> +extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
> +
> +asmlinkage long compat_sys_setitimer(int which, struct compat_itimerval *in,
> + struct compat_itimerval *out)
> +{
> + struct itimerval kin, kout;
> + int error;
> +
> + if (in) {
> + if (get_compat_itimerval(&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_compat_itimerval(out, &kout))
> + return -EFAULT;
> + return 0;
> +}
> diff -ruN 2.5.50-BK.2/kernel/timer.c 2.5.50-BK.2-32bit.1/kernel/timer.c
> --- 2.5.50-BK.2/kernel/timer.c 2002-12-04 12:07:39.000000000 +1100
> +++ 2.5.50-BK.2-32bit.1/kernel/timer.c 2002-12-04 12:03:23.000000000 +1100
> @@ -1020,33 +1020,41 @@
> return current->pid;
> }
>
> -asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp)
> +long do_nanosleep(struct timespec *t)
> {
> - struct timespec t;
> unsigned long expire;
>
> - if(copy_from_user(&t, rqtp, sizeof(struct timespec)))
> - return -EFAULT;
> -
> - if (t.tv_nsec >= 1000000000L || t.tv_nsec < 0 || t.tv_sec < 0)
> + if ((t->tv_nsec >= 1000000000L) || (t->tv_nsec < 0) || (t->tv_sec < 0))
> return -EINVAL;
>
> - expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
> + expire = timespec_to_jiffies(t) + (t->tv_sec || t->tv_nsec);
>
> current->state = TASK_INTERRUPTIBLE;
> expire = schedule_timeout(expire);
>
> if (expire) {
> - if (rmtp) {
> - jiffies_to_timespec(expire, &t);
> - if (copy_to_user(rmtp, &t, sizeof(struct timespec)))
> - return -EFAULT;
> - }
> + jiffies_to_timespec(expire, t);
> return -EINTR;
> }
> return 0;
> }
>
> +asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp)
> +{
> + struct timespec t;
> + long ret;
> +
> + if (copy_from_user(&t, rqtp, sizeof(t)))
> + return -EFAULT;
> +
> + ret = do_nanosleep(&t);
> + if (rmtp && (ret == -EINTR)) {
> + if (copy_to_user(rmtp, &t, sizeof(t)))
> + return -EFAULT;
> + }
> + return ret;
> +}
> +
> /*
> * sys_sysinfo - fill in sysinfo struct
> */
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
--
George Anzinger george@mvista.com
High-res-timers:
http://sourceforge.net/projects/high-res-timers/
Preemption patch:
http://www.kernel.org/pub/linux/kernel/people/rml
next prev parent reply other threads:[~2002-12-04 19:51 UTC|newest]
Thread overview: 78+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-12-04 7:02 [PATCH] compatibility syscall layer (lets try again) Stephen Rothwell
2002-12-04 7:07 ` [PATCH] compatibility syscall layer - PPC64 Stephen Rothwell
2002-12-06 23:03 ` Anton Blanchard
2002-12-04 7:16 ` [PATCH] compatibility syscall layer - SPARC64 Stephen Rothwell
2002-12-04 7:18 ` [PATCH] compatibility syscall layer - X86_64 Stephen Rothwell
2002-12-04 11:29 ` Andi Kleen
2002-12-04 7:26 ` [PATCH] compatibility syscall layer - IA64 Stephen Rothwell
2002-12-04 7:37 ` David Mosberger
2002-12-04 7:28 ` [PATCH] compatibility syscall layer (lets try again) Stephen Rothwell
2002-12-04 7:29 ` [PATCH] compatibility syscall layer - PARISC Stephen Rothwell
2002-12-04 7:30 ` [PATCH] compatibility syscall layer (lets try again) Stephen Rothwell
2002-12-04 7:33 ` Stephen Rothwell
2002-12-04 11:57 ` Pavel Machek
2002-12-04 16:54 ` Linus Torvalds
2002-12-04 16:54 ` David S. Miller
2002-12-04 17:05 ` Linus Torvalds
2002-12-04 19:56 ` george anzinger [this message]
2002-12-04 20:07 ` Linus Torvalds
2002-12-04 20:56 ` Daniel Jacobowitz
2002-12-04 22:09 ` David S. Miller
2002-12-04 22:31 ` george anzinger
2002-12-04 22:39 ` David S. Miller
2002-12-04 22:42 ` Linus Torvalds
2002-12-04 23:42 ` Jim Houston
2002-12-05 0:18 ` Linus Torvalds
2002-12-05 2:01 ` george anzinger
2002-12-05 2:51 ` Linus Torvalds
2002-12-05 3:10 ` Andi Kleen
2002-12-05 3:46 ` george anzinger
2002-12-05 4:11 ` Linus Torvalds
2002-12-05 7:10 ` george anzinger
2002-12-05 9:48 ` george anzinger
2002-12-05 15:24 ` Jim Houston
2002-12-05 16:35 ` george anzinger
2002-12-06 0:03 ` Richard Henderson
2002-12-05 17:03 ` Linus Torvalds
2002-12-06 9:17 ` george anzinger
2002-12-06 17:57 ` Linus Torvalds
2002-12-06 19:20 ` Linus Torvalds
2002-12-06 20:09 ` [PATCH] compatibility syscall layer (let's " Jim Houston
2002-12-06 20:33 ` george anzinger
2002-12-06 20:18 ` [PATCH] compatibility syscall layer (lets " george anzinger
2002-12-06 21:12 ` Linus Torvalds
2002-12-06 21:56 ` Jim Houston
2002-12-06 22:58 ` Linus Torvalds
2002-12-07 2:25 ` george anzinger
2002-12-06 23:08 ` george anzinger
2002-12-08 20:41 ` David S. Miller
2002-12-09 6:18 ` Stephen Rothwell
2002-12-09 15:41 ` Daniel Jacobowitz
2002-12-09 16:48 ` Linus Torvalds
2002-12-09 17:27 ` David Mosberger
2002-12-09 20:22 ` David S. Miller
2002-12-09 17:49 ` Jim Houston
2002-12-09 17:57 ` Linus Torvalds
2002-12-09 23:30 ` Paul Mackerras
2002-12-10 23:07 ` george anzinger
2002-12-11 7:10 ` Daniel Jacobowitz
2002-12-11 8:11 ` george anzinger
2002-12-11 8:26 ` Daniel Jacobowitz
2002-12-10 11:08 ` Jamie Lokier
2002-12-05 2:27 ` Jim Houston
-- strict thread matches above, loose matches on Subject: below --
2002-12-09 16:58 Mikael Starvik
2002-12-09 17:35 ` Linus Torvalds
2002-12-09 18:46 ` David Mosberger
2002-12-10 0:13 ` Paul Mackerras
2002-12-10 23:11 ` george anzinger
2002-12-09 17:16 Martin Schwidefsky
2002-12-09 17:33 ` Linus Torvalds
2002-12-09 20:18 ` David S. Miller
2002-12-09 17:56 Martin Schwidefsky
2002-12-09 18:20 ` Linus Torvalds
2002-12-10 14:40 ` Keith Owens
2002-12-09 18:41 Martin Schwidefsky
2002-12-09 18:52 ` Linus Torvalds
2002-12-10 8:20 ` george anzinger
2002-12-10 8:42 Martin Schwidefsky
2002-12-10 17:17 Martin Schwidefsky
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3DEE5DE1.762699E3@mvista.com \
--to=george@mvista.com \
--cc=ak@muc.de \
--cc=anton@samba.org \
--cc=davem@redhat.com \
--cc=davidm@hpl.hp.com \
--cc=linux-kernel@vger.kernel.org \
--cc=ralf@gnu.org \
--cc=schwidefsky@de.ibm.com \
--cc=sfr@canb.auug.org.au \
--cc=torvalds@transmeta.com \
--cc=willy@debian.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.