Hi Linus,
How's this one :-)
This patch does:
introduces CONFIG_COMPAT32
introduces linux/compat32.h - which contains only struct timespec32
for now
creates an architecture independent version of sys32_nanosleep
in kernel/timer.c
I make the follwing assumptions:
returning s32 from a 32 bit compatibility system call is the same
as returning long or int.
int == s32 on all 64 bit architectures
How does this look? Should timespec32 be called compat32_timespec?
Should the new do_nanosleep function be inlined?
This patch has not even been compiled. Please have a look and comment.
--
Cheers,
Stephen Rothwell [email protected]
http://www.canb.auug.org.au/~sfr/
diff -ruN 2.5.49/arch/ia64/Kconfig 2.5.49-32bit.2/arch/ia64/Kconfig
--- 2.5.49/arch/ia64/Kconfig 2002-11-18 15:47:40.000000000 +1100
+++ 2.5.49-32bit.2/arch/ia64/Kconfig 2002-11-27 18:06:58.000000000 +1100
@@ -397,6 +397,11 @@
run IA-32 Linux binaries on an IA-64 Linux system.
If in doubt, say Y.
+config COMPAT32
+ bool
+ depends on IA32_SUPPORT
+ default y
+
config PERFMON
bool "Performance monitor support"
help
diff -ruN 2.5.49/arch/ia64/ia32/ia32_signal.c 2.5.49-32bit.2/arch/ia64/ia32/ia32_signal.c
--- 2.5.49/arch/ia64/ia32/ia32_signal.c 2002-10-31 14:05:10.000000000 +1100
+++ 2.5.49-32bit.2/arch/ia64/ia32/ia32_signal.c 2002-11-27 18:06:58.000000000 +1100
@@ -22,6 +22,7 @@
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/wait.h>
+#include <linux/compat32.h>
#include <asm/uaccess.h>
#include <asm/rse.h>
diff -ruN 2.5.49/arch/ia64/ia32/sys_ia32.c 2.5.49-32bit.2/arch/ia64/ia32/sys_ia32.c
--- 2.5.49/arch/ia64/ia32/sys_ia32.c 2002-11-18 15:47:40.000000000 +1100
+++ 2.5.49-32bit.2/arch/ia64/ia32/sys_ia32.c 2002-11-27 18:06:58.000000000 +1100
@@ -49,6 +49,7 @@
#include <linux/ptrace.h>
#include <linux/stat.h>
#include <linux/ipc.h>
+#include <linux/compat32.h>
#include <asm/types.h>
#include <asm/uaccess.h>
@@ -1113,27 +1114,6 @@
(struct timeval32 *) A(a.tvp));
}
-extern asmlinkage long sys_nanosleep (struct timespec *rqtp, struct timespec *rmtp);
-
-asmlinkage long
-sys32_nanosleep (struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
- struct timespec t;
- int ret;
- mm_segment_t old_fs = get_fs();
-
- if (get_user (t.tv_sec, &rqtp->tv_sec) || get_user (t.tv_nsec, &rqtp->tv_nsec))
- return -EFAULT;
- set_fs(KERNEL_DS);
- ret = sys_nanosleep(&t, rmtp ? &t : NULL);
- set_fs(old_fs);
- if (rmtp && ret == -EINTR) {
- if (put_user(t.tv_sec, &rmtp->tv_sec) || put_user(t.tv_nsec, &rmtp->tv_nsec))
- return -EFAULT;
- }
- return ret;
-}
-
struct iovec32 { unsigned int iov_base; int iov_len; };
asmlinkage ssize_t sys_readv (unsigned long,const struct iovec *,unsigned long);
asmlinkage ssize_t sys_writev (unsigned long,const struct iovec *,unsigned long);
diff -ruN 2.5.49/arch/mips64/Kconfig 2.5.49-32bit.2/arch/mips64/Kconfig
--- 2.5.49/arch/mips64/Kconfig 2002-11-18 15:47:40.000000000 +1100
+++ 2.5.49-32bit.2/arch/mips64/Kconfig 2002-11-27 18:06:58.000000000 +1100
@@ -371,6 +371,11 @@
compatibility. Since all software available for Linux/MIPS is
currently 32-bit you should say Y here.
+config COMPAT32
+ bool
+ depends on MIPS32_COMPAT
+ default y
+
config BINFMT_ELF32
bool
depends on MIPS32_COMPAT
diff -ruN 2.5.49/arch/mips64/kernel/linux32.c 2.5.49-32bit.2/arch/mips64/kernel/linux32.c
--- 2.5.49/arch/mips64/kernel/linux32.c 2002-10-21 01:02:44.000000000 +1000
+++ 2.5.49-32bit.2/arch/mips64/kernel/linux32.c 2002-11-27 18:06:58.000000000 +1100
@@ -27,6 +27,7 @@
#include <linux/personality.h>
#include <linux/timex.h>
#include <linux/dnotify.h>
+#include <linux/compat32.h>
#include <net/sock.h>
#include <asm/uaccess.h>
@@ -1205,11 +1206,6 @@
-struct timespec32 {
- int tv_sec;
- int tv_nsec;
-};
-
extern asmlinkage int sys_sched_rr_get_interval(pid_t pid,
struct timespec *interval);
@@ -1230,31 +1226,6 @@
}
-extern asmlinkage int sys_nanosleep(struct timespec *rqtp,
- struct timespec *rmtp);
-
-asmlinkage int
-sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
- struct timespec t;
- int ret;
- mm_segment_t old_fs = get_fs ();
-
- if (get_user (t.tv_sec, &rqtp->tv_sec) ||
- __get_user (t.tv_nsec, &rqtp->tv_nsec))
- return -EFAULT;
-
- set_fs (KERNEL_DS);
- ret = sys_nanosleep(&t, rmtp ? &t : NULL);
- set_fs (old_fs);
- if (rmtp && ret == -EINTR) {
- if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
- __put_user (t.tv_nsec, &rmtp->tv_nsec))
- return -EFAULT;
- }
- return ret;
-}
-
struct tms32 {
int tms_utime;
int tms_stime;
diff -ruN 2.5.49/arch/parisc/Kconfig 2.5.49-32bit.2/arch/parisc/Kconfig
--- 2.5.49/arch/parisc/Kconfig 2002-11-18 15:47:40.000000000 +1100
+++ 2.5.49-32bit.2/arch/parisc/Kconfig 2002-11-27 18:06:58.000000000 +1100
@@ -107,6 +107,11 @@
enable this option otherwise. The 64bit kernel is significantly bigger
and slower than the 32bit one.
+config COMPAT32
+ bool
+ depends PARISC64
+ default y
+
config PDC_NARROW
bool "32-bit firmware"
depends on PARISC64
diff -ruN 2.5.49/arch/parisc/kernel/sys_parisc32.c 2.5.49-32bit.2/arch/parisc/kernel/sys_parisc32.c
--- 2.5.49/arch/parisc/kernel/sys_parisc32.c 2002-11-18 15:47:40.000000000 +1100
+++ 2.5.49-32bit.2/arch/parisc/kernel/sys_parisc32.c 2002-11-27 18:06:58.000000000 +1100
@@ -52,6 +52,7 @@
#include <linux/mman.h>
#include <linux/binfmts.h>
#include <linux/namei.h>
+#include <linux/compat32.h>
#include <asm/types.h>
#include <asm/uaccess.h>
@@ -584,11 +585,6 @@
}
#endif /* CONFIG_SYSCTL */
-struct timespec32 {
- s32 tv_sec;
- s32 tv_nsec;
-};
-
static int
put_timespec32(struct timespec32 *u, struct timespec *t)
{
@@ -598,28 +594,6 @@
return copy_to_user(u, &t32, sizeof t32);
}
-asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
- struct timespec t;
- struct timespec32 t32;
- int ret;
- extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
-
- if (copy_from_user(&t32, rqtp, sizeof t32))
- return -EFAULT;
- t.tv_sec = t32.tv_sec;
- t.tv_nsec = t32.tv_nsec;
-
- DBG(("sys32_nanosleep({%d, %d})\n", t32.tv_sec, t32.tv_nsec));
-
- KERNEL_SYSCALL(ret, sys_nanosleep, &t, rmtp ? &t : NULL);
- if (rmtp && ret == -EINTR) {
- if (put_timespec32(rmtp, &t))
- return -EFAULT;
- }
- return ret;
-}
-
asmlinkage long sys32_sched_rr_get_interval(pid_t pid,
struct timespec32 *interval)
{
diff -ruN 2.5.49/arch/ppc64/Kconfig 2.5.49-32bit.2/arch/ppc64/Kconfig
--- 2.5.49/arch/ppc64/Kconfig 2002-11-18 15:47:40.000000000 +1100
+++ 2.5.49-32bit.2/arch/ppc64/Kconfig 2002-11-27 18:06:58.000000000 +1100
@@ -33,6 +33,10 @@
bool
default y
+config COMPAT32
+ bool
+ default y
+
source "init/Kconfig"
diff -ruN 2.5.49/arch/ppc64/kernel/signal32.c 2.5.49-32bit.2/arch/ppc64/kernel/signal32.c
--- 2.5.49/arch/ppc64/kernel/signal32.c 2002-10-21 01:02:45.000000000 +1000
+++ 2.5.49-32bit.2/arch/ppc64/kernel/signal32.c 2002-11-27 18:06:58.000000000 +1100
@@ -22,6 +22,7 @@
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/elf.h>
+#include <linux/compat32.h>
#include <asm/ppc32.h>
#include <asm/uaccess.h>
#include <asm/ppcdebug.h>
@@ -53,11 +54,6 @@
#define MSR_USERCHANGE 0
#endif
-struct timespec32 {
- s32 tv_sec;
- s32 tv_nsec;
-};
-
struct sigregs32 {
/*
* the gp_regs array is 32 bit representation of the pt_regs
diff -ruN 2.5.49/arch/ppc64/kernel/sys_ppc32.c 2.5.49-32bit.2/arch/ppc64/kernel/sys_ppc32.c
--- 2.5.49/arch/ppc64/kernel/sys_ppc32.c 2002-10-21 01:02:45.000000000 +1000
+++ 2.5.49-32bit.2/arch/ppc64/kernel/sys_ppc32.c 2002-11-27 18:06:58.000000000 +1100
@@ -53,6 +53,7 @@
#include <linux/mman.h>
#include <linux/sysctl.h>
#include <linux/binfmts.h>
+#include <linux/compat32.h>
#include <asm/types.h>
#include <asm/ipc.h>
@@ -1774,37 +1775,6 @@
-struct timespec32 {
- s32 tv_sec;
- s32 tv_nsec;
-};
-
-extern asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
-
-asmlinkage long sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
- struct timespec t;
- int ret;
- mm_segment_t old_fs = get_fs ();
-
- if (get_user (t.tv_sec, &rqtp->tv_sec) ||
- __get_user (t.tv_nsec, &rqtp->tv_nsec))
- return -EFAULT;
- set_fs (KERNEL_DS);
- ret = sys_nanosleep(&t, rmtp ? &t : NULL);
- set_fs (old_fs);
- if (rmtp && ret == -EINTR) {
- if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
- __put_user (t.tv_nsec, &rmtp->tv_nsec))
- return -EFAULT;
- }
-
- return ret;
-}
-
-
-
-
/* These are here just in case some old sparc32 binary calls it. */
asmlinkage long sys32_pause(void)
{
diff -ruN 2.5.49/arch/s390x/Kconfig 2.5.49-32bit.2/arch/s390x/Kconfig
--- 2.5.49/arch/s390x/Kconfig 2002-11-11 14:55:28.000000000 +1100
+++ 2.5.49-32bit.2/arch/s390x/Kconfig 2002-11-27 18:06:58.000000000 +1100
@@ -117,6 +117,11 @@
(and some other stuff like libraries and such) is needed for
executing 31 bit applications. It is safe to say "Y".
+config COMPAT32
+ bool
+ depends on S390_SUPPORT
+ default y
+
config BINFMT_ELF32
tristate "Kernel support for 31 bit ELF binaries"
depends on S390_SUPPORT
diff -ruN 2.5.49/arch/s390x/kernel/linux32.c 2.5.49-32bit.2/arch/s390x/kernel/linux32.c
--- 2.5.49/arch/s390x/kernel/linux32.c 2002-10-21 01:02:45.000000000 +1000
+++ 2.5.49-32bit.2/arch/s390x/kernel/linux32.c 2002-11-27 18:06:58.000000000 +1100
@@ -57,6 +57,7 @@
#include <linux/icmpv6.h>
#include <linux/sysctl.h>
#include <linux/binfmts.h>
+#include <linux/compat32.h>
#include <asm/types.h>
#include <asm/ipc.h>
@@ -1774,11 +1775,6 @@
return ret;
}
-struct timespec32 {
- s32 tv_sec;
- s32 tv_nsec;
-};
-
extern asmlinkage int sys_sched_rr_get_interval(pid_t pid, struct timespec *interval);
asmlinkage int sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
@@ -1796,28 +1792,6 @@
return ret;
}
-extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
-
-asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
- struct timespec t;
- int ret;
- mm_segment_t old_fs = get_fs ();
-
- if (get_user (t.tv_sec, &rqtp->tv_sec) ||
- __get_user (t.tv_nsec, &rqtp->tv_nsec))
- return -EFAULT;
- set_fs (KERNEL_DS);
- ret = sys_nanosleep(&t, rmtp ? &t : NULL);
- set_fs (old_fs);
- if (rmtp && ret == -EINTR) {
- if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
- __put_user (t.tv_nsec, &rmtp->tv_nsec))
- return -EFAULT;
- }
- return ret;
-}
-
extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset);
asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset)
diff -ruN 2.5.49/arch/s390x/kernel/wrapper32.S 2.5.49-32bit.2/arch/s390x/kernel/wrapper32.S
--- 2.5.49/arch/s390x/kernel/wrapper32.S 2002-10-08 12:02:40.000000000 +1000
+++ 2.5.49-32bit.2/arch/s390x/kernel/wrapper32.S 2002-11-27 18:06:58.000000000 +1100
@@ -759,8 +759,8 @@
.globl sys32_nanosleep_wrapper
sys32_nanosleep_wrapper:
- llgtr %r2,%r2 # struct timespec_emu31 *
- llgtr %r3,%r3 # struct timespec_emu31 *
+ llgtr %r2,%r2 # struct timespec32 *
+ llgtr %r3,%r3 # struct timespec32 *
jg sys32_nanosleep # branch to system call
.globl sys32_mremap_wrapper
diff -ruN 2.5.49/arch/sparc64/Kconfig 2.5.49-32bit.2/arch/sparc64/Kconfig
--- 2.5.49/arch/sparc64/Kconfig 2002-11-18 15:47:41.000000000 +1100
+++ 2.5.49-32bit.2/arch/sparc64/Kconfig 2002-11-27 18:06:58.000000000 +1100
@@ -352,6 +352,11 @@
This allows you to run 32-bit binaries on your Ultra.
Everybody wants this; say Y.
+config COMPAT32
+ bool
+ depends on SPARC32_COMPAT
+ default y
+
config BINFMT_ELF32
tristate "Kernel support for 32-bit ELF binaries"
depends on SPARC32_COMPAT
diff -ruN 2.5.49/arch/sparc64/kernel/sys_sparc32.c 2.5.49-32bit.2/arch/sparc64/kernel/sys_sparc32.c
--- 2.5.49/arch/sparc64/kernel/sys_sparc32.c 2002-11-18 15:47:41.000000000 +1100
+++ 2.5.49-32bit.2/arch/sparc64/kernel/sys_sparc32.c 2002-11-27 18:06:58.000000000 +1100
@@ -51,6 +51,7 @@
#include <linux/sysctl.h>
#include <linux/binfmts.h>
#include <linux/dnotify.h>
+#include <linux/compat32.h>
#include <asm/types.h>
#include <asm/ipc.h>
@@ -1794,11 +1795,6 @@
return ret;
}
-struct timespec32 {
- s32 tv_sec;
- s32 tv_nsec;
-};
-
extern asmlinkage int sys_sched_rr_get_interval(pid_t pid, struct timespec *interval);
asmlinkage int sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
@@ -1816,28 +1812,6 @@
return ret;
}
-extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
-
-asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
- struct timespec t;
- int ret;
- mm_segment_t old_fs = get_fs ();
-
- if (get_user (t.tv_sec, &rqtp->tv_sec) ||
- __get_user (t.tv_nsec, &rqtp->tv_nsec))
- return -EFAULT;
- set_fs (KERNEL_DS);
- ret = sys_nanosleep(&t, rmtp ? &t : NULL);
- set_fs (old_fs);
- if (rmtp && ret == -EINTR) {
- if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
- __put_user (t.tv_nsec, &rmtp->tv_nsec))
- return -EFAULT;
- }
- return ret;
-}
-
extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset);
asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset)
diff -ruN 2.5.49/arch/x86_64/Kconfig 2.5.49-32bit.2/arch/x86_64/Kconfig
--- 2.5.49/arch/x86_64/Kconfig 2002-11-18 15:47:41.000000000 +1100
+++ 2.5.49-32bit.2/arch/x86_64/Kconfig 2002-11-27 18:06:58.000000000 +1100
@@ -425,6 +425,11 @@
turn this on, unless you're 100% sure that you don't have any 32bit programs
left.
+config COMPAT32
+ bool
+ depends on IA32_EMULATION
+ default y
+
endmenu
source "drivers/mtd/Kconfig"
diff -ruN 2.5.49/arch/x86_64/ia32/sys_ia32.c 2.5.49-32bit.2/arch/x86_64/ia32/sys_ia32.c
--- 2.5.49/arch/x86_64/ia32/sys_ia32.c 2002-11-18 15:47:41.000000000 +1100
+++ 2.5.49-32bit.2/arch/x86_64/ia32/sys_ia32.c 2002-11-27 18:06:58.000000000 +1100
@@ -58,6 +58,7 @@
#include <linux/binfmts.h>
#include <linux/init.h>
#include <linux/aio_abi.h>
+#include <linux/compat32.h>
#include <asm/mman.h>
#include <asm/types.h>
#include <asm/uaccess.h>
@@ -934,36 +935,6 @@
(struct timeval32 *)A(a.tvp));
}
-struct timespec32 {
- int tv_sec;
- int tv_nsec;
-};
-
-extern asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
-
-asmlinkage long
-sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
- struct timespec t;
- int ret;
- mm_segment_t old_fs = get_fs ();
-
- if (verify_area(VERIFY_READ, rqtp, sizeof(struct timespec32)) ||
- __get_user (t.tv_sec, &rqtp->tv_sec) ||
- __get_user (t.tv_nsec, &rqtp->tv_nsec))
- return -EFAULT;
- set_fs (KERNEL_DS);
- ret = sys_nanosleep(&t, rmtp ? &t : NULL);
- set_fs (old_fs);
- if (rmtp && ret == -EINTR) {
- if (verify_area(VERIFY_WRITE, rmtp, sizeof(struct timespec32)) ||
- __put_user (t.tv_sec, &rmtp->tv_sec) ||
- __put_user (t.tv_nsec, &rmtp->tv_nsec))
- return -EFAULT;
- }
- return ret;
-}
-
asmlinkage ssize_t sys_readv(unsigned long,const struct iovec *,unsigned long);
asmlinkage ssize_t sys_writev(unsigned long,const struct iovec *,unsigned long);
diff -ruN 2.5.49/include/asm-ia64/ia32.h 2.5.49-32bit.2/include/asm-ia64/ia32.h
--- 2.5.49/include/asm-ia64/ia32.h 2002-10-31 14:06:05.000000000 +1100
+++ 2.5.49-32bit.2/include/asm-ia64/ia32.h 2002-11-27 18:06:58.000000000 +1100
@@ -41,11 +41,6 @@
#define IA32_CLOCKS_PER_SEC 100 /* Cast in stone for IA32 Linux */
#define IA32_TICK(tick) ((unsigned long long)(tick) * IA32_CLOCKS_PER_SEC / CLOCKS_PER_SEC)
-struct timespec32 {
- int tv_sec;
- int tv_nsec;
-};
-
/* fcntl.h */
struct flock32 {
short l_type;
diff -ruN 2.5.49/include/linux/compat32.h 2.5.49-32bit.2/include/linux/compat32.h
--- 2.5.49/include/linux/compat32.h 1970-01-01 10:00:00.000000000 +1000
+++ 2.5.49-32bit.2/include/linux/compat32.h 2002-11-27 18:06:58.000000000 +1100
@@ -0,0 +1,18 @@
+#ifndef _LINUX_COMPAT32_H
+#define _LINUX_COMPAT32_H
+/*
+ * These are the type definitions for the 32 compatibility
+ * layer on 64 bit architectures.
+ */
+
+#include <linux/config.h>
+
+#ifdef CONFIG_COMPAT32
+
+struct timespec32 {
+ s32 tv_sec;
+ s32 tv_nsec;
+};
+
+#endif /* CONFIG_COMPAT32 */
+#endif /* _LINUX_COMPAT32_H */
diff -ruN 2.5.49/kernel/timer.c 2.5.49-32bit.2/kernel/timer.c
--- 2.5.49/kernel/timer.c 2002-11-18 15:47:56.000000000 +1100
+++ 2.5.49-32bit.2/kernel/timer.c 2002-11-27 18:06:58.000000000 +1100
@@ -25,6 +25,7 @@
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/notifier.h>
+#include <linux/compat32.h>
#include <asm/uaccess.h>
@@ -1024,33 +1025,63 @@
return current->pid;
}
-asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp)
+static 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;
+}
+
+#ifdef CONFIG_COMPAT32
+asmlinkage s32 sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
+{
+ struct timespec t;
+ struct timespec32 t32;
+ long ret;
+
+ if (copy_from_user(&t32, rqtp, sizeof(t32)))
+ return -EFAULT;
+ t.tv_sec = t32.tv_sec;
+ t.tv_nsec = t32.tv_nsec;
+ ret = do_nanosleep(&t);
+ if (rmtp && (ret == -EINTR)) {
+ t32.tv_sec = t.tv_sec;
+ t32.tv_nsec = t.tv_nsec;
+ if (copy_to_user(rmtp, &t32, sizeof(t32)))
+ return -EFAULT;
+ }
+ return ret;
+}
+#endif /* CONFIG_COMPAT32 */
+
/*
* sys_sysinfo - fill in sysinfo struct
*/
From: Stephen Rothwell <[email protected]>
Date: Wed, 27 Nov 2002 18:42:28 +1100
How's this one :-)
I don't think this is the way to go.
I think we really need to give the 32-bit compatability
types names and allow 64-bit arches to define what their
32-bit counterparts use.
For example, nlink_t is going to need to be different
for sparc 32-bit compat vs. most other platforms because
we use a signed short there.
Linus what is you big beef with the names used before, the "__kernel"
part of the name? We can't just use "u32" for ino_t althroughout the
compat32 code or whatever your idea seems to be.
Please clarify.
>>>>> On Wed, 27 Nov 2002 18:42:28 +1100, Stephen Rothwell <[email protected]> said:
Stephen> I make the follwing assumptions: returning s32 from a 32
Stephen> bit compatibility system call is the same as returning long
Stephen> or int.
That is not a safe assumption. The ia64 ABI requires that a 32-bit
result is returned in the least-significant 32 bits only---the upper
32 bits may contain garbage. It should be safe to declare the syscall
return type always as "long", no?
--david
From: David Mosberger <[email protected]>
Date: Wed, 27 Nov 2002 00:00:53 -0800
It should be safe to declare the syscall
return type always as "long", no?
Sign extension is a rule of the architecture.
So if the platform says "int shall not be sign
extended to 64-bits", declaring as long is wrong.
On Wed, Nov 27, 2002 at 09:00:53AM +0100, David Mosberger wrote:
> >>>>> On Wed, 27 Nov 2002 18:42:28 +1100, Stephen Rothwell <[email protected]> said:
>
> Stephen> I make the follwing assumptions: returning s32 from a 32
> Stephen> bit compatibility system call is the same as returning long
> Stephen> or int.
>
> That is not a safe assumption. The ia64 ABI requires that a 32-bit
> result is returned in the least-significant 32 bits only---the upper
> 32 bits may contain garbage. It should be safe to declare the syscall
> return type always as "long", no?
But the 32bit user space surely doesn't care about any garbage in
the upper 32bits, no ?
64bit user space might, but that's not driven by a shared compat layer.
-Andi
>>>>> On Wed, 27 Nov 2002 09:29:18 +0100, Andi Kleen <[email protected]> said:
Andi> But the 32bit user space surely doesn't care about any garbage
Andi> in the upper 32bits, no ?
The user-space won't, but the kernel exit path might. Remember that
most compatibility syscalls go straight to the 64-bit syscall
handlers. You're probably hosed anyhow if a 64-bit syscall returns,
say, 0x1ffffffff, but on ia64 I'd still rather play it safe and
consistently have all compatibility syscalls return a 64-bit
sign-extended value like all other syscall handlers ("least surprise"
principle).
--david
On Wed, Nov 27, 2002 at 09:46:13AM +0100, David Mosberger wrote:
> >>>>> On Wed, 27 Nov 2002 09:29:18 +0100, Andi Kleen <[email protected]> said:
>
> Andi> But the 32bit user space surely doesn't care about any garbage
> Andi> in the upper 32bits, no ?
>
> The user-space won't, but the kernel exit path might. Remember that
True. The signal return path checking for the 5xx errnos expects
them to be 64bit extended. I now even vaguely remember an obscure bug I once
saw on x86-64 with an 32bit application actually seeing ERESTARTSYS that might
just have been caused by such an issue.
Thanks for pointing that out.
-Andi
From: David Mosberger <[email protected]>
Date: Wed, 27 Nov 2002 00:46:13 -0800
The user-space won't, but the kernel exit path might.
You need to have a different kernel exit path, you need
a different one to chop off the top 32-bits of all the
incoming arguments anyways David.
On Wed, 2002-11-27 at 08:29, Andi Kleen wrote:
> But the 32bit user space surely doesn't care about any garbage in
> the upper 32bits, no ?
Providing its garbage not leaked kernel data
Hi Dave,
On Tue, 26 Nov 2002 23:58:10 -0800 (PST) "David S. Miller" <[email protected]> wrote:
>
> From: Stephen Rothwell <[email protected]>
> Date: Wed, 27 Nov 2002 18:42:28 +1100
>
> How's this one :-)
>
> I don't think this is the way to go.
>
> I think we really need to give the 32-bit compatability
> types names and allow 64-bit arches to define what their
> 32-bit counterparts use.
OK, we can discuss that as well, but what do you think of the particular
patch that I supplied? It is independent of the naming of types. If I
can get linux/compat32.h and CONFIG_COMPAT32 started, the consolidation
will preceed fairly rapidly and I think that is far more important than
what the names look like ...
> For example, nlink_t is going to need to be different
> for sparc 32-bit compat vs. most other platforms because
> we use a signed short there.
This will be allowed for when linux/compat32.h includes asm/compat32.h
at a later stage. asm/compat32.h will be expected to have typedefs for
compat32_<type> (or __kernel_<type>32 whatever) for all the types that
vary between the architectures.
--
Cheers,
Stephen Rothwell [email protected]
http://www.canb.auug.org.au/~sfr/
>>>>> On Wed, 27 Nov 2002 01:57:17 -0800 (PST), "David S. Miller" <[email protected]> said:
DaveM> You need to have a different kernel exit path, you need a
DaveM> different one to chop off the top 32-bits of all the incoming
DaveM> arguments anyways David.
You conveniently cut of the important part of my message:
Remember that most compatibility syscalls go straight to the
64-bit syscall handlers. You're probably hosed anyhow if a
64-bit syscall returns, say, 0x1ffffffff, but on ia64 I'd
still rather play it safe and consistently have all
compatibility syscalls return a 64-bit sign-extended value
like all other syscall handlers ("least surprise" principle).
I have zero interest debugging subtle bugs of this sort. If "long"
isn't an option, we should add a platform-specific compat32_retval_t
or whatever.
--david
On Wed, 27 Nov 2002, Stephen Rothwell wrote:
>
> How's this one :-)
Better.
> This patch does:
> introduces CONFIG_COMPAT32
> introduces linux/compat32.h - which contains only struct timespec32
> for now
> creates an architecture independent version of sys32_nanosleep
> in kernel/timer.c
May I just suggest doing a
kernel/compat32.c
and doing most everything there? I think we're better off that way, even
if it means that "do_nanosleep()" etc cannot be static.
> I make the follwing assumptions:
> returning s32 from a 32 bit compatibility system call is the same
> as returning long or int.
You should make system call returns always be of type "long". Some
architectures may well require that (I know that the alpha calling
conventions do require it, even when using the 32-bit user land. I don't
think Linux has ever really supported the 32-bit stuff on alpha, but the
theory is the same).
And it means that the upper bits are well-defined.
In other words, instead of doing
s32 sys_xxx(..)
{
return xxxx
}
you should make them be
long sys_xxx(...)
{
s32 retval;
...
return retval;
}
> Should the new do_nanosleep function be inlined?
Well, since I want it used in another file, it can't be.
Linus
On Tue, 26 Nov 2002, David S. Miller wrote:
>
> Linus what is you big beef with the names used before, the "__kernel"
> part of the name? We can't just use "u32" for ino_t althroughout the
> compat32 code or whatever your idea seems to be.
I have two _big_ beefs with the
__kernel_xxx_t32
naming:
- the xxx_t naming is already ugly, but at least it's standard ("_t
stands for typedef"). No such case is true for _t32.
- the __kernel_ naming is already ugly, but at least it has a _reason_
for it, namely that we have to have __ to avoid polluting user-space
headers with the _one_ thing that the kernel exports, namely
architecture types. Again, this is _not_ true for the compat32 stuff,
since it's an ABI, not an API issue, and the types aren't exposed to
user space headers.
In short, it's f*cking ugly, for no good reason. That in itself is _way_
enough reason to say "No FRIGGING WAY!".
The original patch was worse by an order of magnitude for _another_
reason, which has nothing to do with naming:
Note that I'm not against having architecture-specific "compat32 types".
HOWEVER, if they are architecture-specific, then they had better not be in
a generic file. So it's just _fundamentally_ wrong to have a <linux/xxx.h>
file that then has "architecture-specific" stuff in it. That's just CRAP.
So the naming is just ugly (but ugly enough that I don't want to see it).
The real crap is having a architecture-independent file that defines
non-generic types.
I suspect that the correct way to do things is:
- have an <asm/compat32.h> for the types. The types _are_ different for
different architectures, even if 90% of them look really really
similar. It's just not worth it trying to share code that is not
fundamentally the same - and in this case it isn't.
This fixes the fundamental objection I had to <linux/compat32.h>
- use sane naming. Something like "compat32_nlink_t" is sane. Something
like "__kernel_nlink_t32" is not.
You might as well also discuss just dropping the "32" from "compat32"
while you're at it. As far as I can tell the code and the fundamental
issue has nothing to do with 32-bitness per se. It has everything to do
with compatibility with an older ABI. The 32-bitness is a implementation
detail, there's nothing that fundamentally says the same compat code might
not work with a 64(user)->128(kernel) bit (or a 16->32 bit) compatibility
layer.
Linus
From: Stephen Rothwell <[email protected]>
Date: Thu, 28 Nov 2002 16:22:31 +1100
On Wed, 27 Nov 2002 09:18:06 -0800 (PST) Linus Torvalds <[email protected]> wrote:
> May I just suggest doing a
>
> kernel/compat32.c
OK, new version.
Well, actually I disagree with this.
I envisioned moving the compat stuff right next to the "normal"
implementation.
A problem currently, is that when people change VFS stuff up one has
to pay attention to update all the compat syscall layers as well.
This often simply does not happen because the compat version is
"somewhere else" is some other file.
Now if we put the stuff next to the non-compat stuff, it likely won't
get missed.
Hi Linus,
On Wed, 27 Nov 2002 09:18:06 -0800 (PST) Linus Torvalds <[email protected]> wrote:
>
>
> On Wed, 27 Nov 2002, Stephen Rothwell wrote:
> >
> > How's this one :-)
>
> Better.
>
> > This patch does:
> > introduces CONFIG_COMPAT32
> > introduces linux/compat32.h - which contains only struct timespec32
> > for now
> > creates an architecture independent version of sys32_nanosleep
> > in kernel/timer.c
>
> May I just suggest doing a
>
> kernel/compat32.c
OK, new version. In addition to the old patch this one does:
creates kernel/compat32.c and put sys32_nanosleep there
sys32_nanosleep now returns long
creates asm-*/compat32.h
creates a typedef for compat32_time_t
uses compat32_time_t in timespec32
renames __kernel_time_t32 to compat32_time_t everywhere
Does this move in the right direction?
Dave, does this do more like what you want?
> and doing most everything there? I think we're better off that way, even
> if it means that "do_nanosleep()" etc cannot be static.
I was trying to keep the two versions close to each other, but fine.
This one has been built on PPC64. (Thanks, Anton)
--
Cheers,
Stephen Rothwell [email protected]
http://www.canb.auug.org.au/~sfr/
diff -ruN 2.5.50/arch/ia64/Kconfig 2.5.50-32bit.1/arch/ia64/Kconfig
--- 2.5.50/arch/ia64/Kconfig 2002-11-28 10:34:41.000000000 +1100
+++ 2.5.50-32bit.1/arch/ia64/Kconfig 2002-11-28 13:22:35.000000000 +1100
@@ -397,6 +397,11 @@
run IA-32 Linux binaries on an IA-64 Linux system.
If in doubt, say Y.
+config COMPAT32
+ bool
+ depends on IA32_SUPPORT
+ default y
+
config PERFMON
bool "Performance monitor support"
help
diff -ruN 2.5.50/arch/ia64/ia32/ia32_signal.c 2.5.50-32bit.1/arch/ia64/ia32/ia32_signal.c
--- 2.5.50/arch/ia64/ia32/ia32_signal.c 2002-10-31 14:05:10.000000000 +1100
+++ 2.5.50-32bit.1/arch/ia64/ia32/ia32_signal.c 2002-11-28 14:10:42.000000000 +1100
@@ -22,6 +22,7 @@
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/wait.h>
+#include <linux/compat32.h>
#include <asm/uaccess.h>
#include <asm/rse.h>
@@ -570,8 +571,8 @@
}
asmlinkage long
-sys32_rt_sigtimedwait (sigset32_t *uthese, siginfo_t32 *uinfo, struct timespec32 *uts,
- unsigned int sigsetsize)
+sys32_rt_sigtimedwait (sigset32_t *uthese, siginfo_t32 *uinfo,
+ struct timespec32 *uts, unsigned int sigsetsize)
{
extern asmlinkage long sys_rt_sigtimedwait (const sigset_t *, siginfo_t *,
const struct timespec *, size_t);
diff -ruN 2.5.50/arch/ia64/ia32/sys_ia32.c 2.5.50-32bit.1/arch/ia64/ia32/sys_ia32.c
--- 2.5.50/arch/ia64/ia32/sys_ia32.c 2002-11-18 15:47:40.000000000 +1100
+++ 2.5.50-32bit.1/arch/ia64/ia32/sys_ia32.c 2002-11-28 14:35:53.000000000 +1100
@@ -49,6 +49,7 @@
#include <linux/ptrace.h>
#include <linux/stat.h>
#include <linux/ipc.h>
+#include <linux/compat32.h>
#include <asm/types.h>
#include <asm/uaccess.h>
@@ -1113,27 +1114,6 @@
(struct timeval32 *) A(a.tvp));
}
-extern asmlinkage long sys_nanosleep (struct timespec *rqtp, struct timespec *rmtp);
-
-asmlinkage long
-sys32_nanosleep (struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
- struct timespec t;
- int ret;
- mm_segment_t old_fs = get_fs();
-
- if (get_user (t.tv_sec, &rqtp->tv_sec) || get_user (t.tv_nsec, &rqtp->tv_nsec))
- return -EFAULT;
- set_fs(KERNEL_DS);
- ret = sys_nanosleep(&t, rmtp ? &t : NULL);
- set_fs(old_fs);
- if (rmtp && ret == -EINTR) {
- if (put_user(t.tv_sec, &rmtp->tv_sec) || put_user(t.tv_nsec, &rmtp->tv_nsec))
- return -EFAULT;
- }
- return ret;
-}
-
struct iovec32 { unsigned int iov_base; int iov_len; };
asmlinkage ssize_t sys_readv (unsigned long,const struct iovec *,unsigned long);
asmlinkage ssize_t sys_writev (unsigned long,const struct iovec *,unsigned long);
@@ -2018,8 +1998,8 @@
struct semid_ds32 {
struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
- __kernel_time_t32 sem_otime; /* last semop time */
- __kernel_time_t32 sem_ctime; /* last change time */
+ compat32_time_t sem_otime; /* last semop time */
+ compat32_time_t sem_ctime; /* last change time */
u32 sem_base; /* ptr to first semaphore in array */
u32 sem_pending; /* pending operations to be processed */
u32 sem_pending_last; /* last pending operation */
@@ -2029,9 +2009,9 @@
struct semid64_ds32 {
struct ipc64_perm32 sem_perm;
- __kernel_time_t32 sem_otime;
+ compat32_time_t sem_otime;
unsigned int __unused1;
- __kernel_time_t32 sem_ctime;
+ compat32_time_t sem_ctime;
unsigned int __unused2;
unsigned int sem_nsems;
unsigned int __unused3;
@@ -2042,9 +2022,9 @@
struct ipc_perm32 msg_perm;
u32 msg_first;
u32 msg_last;
- __kernel_time_t32 msg_stime;
- __kernel_time_t32 msg_rtime;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_stime;
+ compat32_time_t msg_rtime;
+ compat32_time_t msg_ctime;
u32 wwait;
u32 rwait;
unsigned short msg_cbytes;
@@ -2056,11 +2036,11 @@
struct msqid64_ds32 {
struct ipc64_perm32 msg_perm;
- __kernel_time_t32 msg_stime;
+ compat32_time_t msg_stime;
unsigned int __unused1;
- __kernel_time_t32 msg_rtime;
+ compat32_time_t msg_rtime;
unsigned int __unused2;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_ctime;
unsigned int __unused3;
unsigned int msg_cbytes;
unsigned int msg_qnum;
@@ -2074,9 +2054,9 @@
struct shmid_ds32 {
struct ipc_perm32 shm_perm;
int shm_segsz;
- __kernel_time_t32 shm_atime;
- __kernel_time_t32 shm_dtime;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_atime;
+ compat32_time_t shm_dtime;
+ compat32_time_t shm_ctime;
__kernel_ipc_pid_t32 shm_cpid;
__kernel_ipc_pid_t32 shm_lpid;
unsigned short shm_nattch;
@@ -2085,11 +2065,11 @@
struct shmid64_ds32 {
struct ipc64_perm shm_perm;
__kernel_size_t32 shm_segsz;
- __kernel_time_t32 shm_atime;
+ compat32_time_t shm_atime;
unsigned int __unused1;
- __kernel_time_t32 shm_dtime;
+ compat32_time_t shm_dtime;
unsigned int __unused2;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_ctime;
unsigned int __unused3;
__kernel_pid_t32 shm_cpid;
__kernel_pid_t32 shm_lpid;
diff -ruN 2.5.50/arch/mips64/Kconfig 2.5.50-32bit.1/arch/mips64/Kconfig
--- 2.5.50/arch/mips64/Kconfig 2002-11-28 10:35:37.000000000 +1100
+++ 2.5.50-32bit.1/arch/mips64/Kconfig 2002-11-28 13:22:35.000000000 +1100
@@ -371,6 +371,11 @@
compatibility. Since all software available for Linux/MIPS is
currently 32-bit you should say Y here.
+config COMPAT32
+ bool
+ depends on MIPS32_COMPAT
+ default y
+
config BINFMT_ELF32
bool
depends on MIPS32_COMPAT
diff -ruN 2.5.50/arch/mips64/kernel/linux32.c 2.5.50-32bit.1/arch/mips64/kernel/linux32.c
--- 2.5.50/arch/mips64/kernel/linux32.c 2002-10-21 01:02:44.000000000 +1000
+++ 2.5.50-32bit.1/arch/mips64/kernel/linux32.c 2002-11-28 14:36:49.000000000 +1100
@@ -27,6 +27,7 @@
#include <linux/personality.h>
#include <linux/timex.h>
#include <linux/dnotify.h>
+#include <linux/compat32.h>
#include <net/sock.h>
#include <asm/uaccess.h>
@@ -119,7 +120,7 @@
extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
struct utimbuf32 {
- __kernel_time_t32 actime, modtime;
+ compat32_time_t actime, modtime;
};
asmlinkage int sys32_utime(char * filename, struct utimbuf32 *times)
@@ -1205,11 +1206,6 @@
-struct timespec32 {
- int tv_sec;
- int tv_nsec;
-};
-
extern asmlinkage int sys_sched_rr_get_interval(pid_t pid,
struct timespec *interval);
@@ -1230,31 +1226,6 @@
}
-extern asmlinkage int sys_nanosleep(struct timespec *rqtp,
- struct timespec *rmtp);
-
-asmlinkage int
-sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
- struct timespec t;
- int ret;
- mm_segment_t old_fs = get_fs ();
-
- if (get_user (t.tv_sec, &rqtp->tv_sec) ||
- __get_user (t.tv_nsec, &rqtp->tv_nsec))
- return -EFAULT;
-
- set_fs (KERNEL_DS);
- ret = sys_nanosleep(&t, rmtp ? &t : NULL);
- set_fs (old_fs);
- if (rmtp && ret == -EINTR) {
- if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
- __put_user (t.tv_nsec, &rmtp->tv_nsec))
- return -EFAULT;
- }
- return ret;
-}
-
struct tms32 {
int tms_utime;
int tms_stime;
@@ -1418,8 +1389,8 @@
struct semid_ds32 {
struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
- __kernel_time_t32 sem_otime; /* last semop time */
- __kernel_time_t32 sem_ctime; /* last change time */
+ compat32_time_t sem_otime; /* last semop time */
+ compat32_time_t sem_ctime; /* last change time */
u32 sem_base; /* ptr to first semaphore in array */
u32 sem_pending; /* pending operations to be processed */
u32 sem_pending_last; /* last pending operation */
@@ -1432,9 +1403,9 @@
struct ipc_perm32 msg_perm;
u32 msg_first;
u32 msg_last;
- __kernel_time_t32 msg_stime;
- __kernel_time_t32 msg_rtime;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_stime;
+ compat32_time_t msg_rtime;
+ compat32_time_t msg_ctime;
u32 wwait;
u32 rwait;
unsigned short msg_cbytes;
@@ -1447,9 +1418,9 @@
struct shmid_ds32 {
struct ipc_perm32 shm_perm;
int shm_segsz;
- __kernel_time_t32 shm_atime;
- __kernel_time_t32 shm_dtime;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_atime;
+ compat32_time_t shm_dtime;
+ compat32_time_t shm_ctime;
__kernel_ipc_pid_t32 shm_cpid;
__kernel_ipc_pid_t32 shm_lpid;
unsigned short shm_nattch;
diff -ruN 2.5.50/arch/parisc/Kconfig 2.5.50-32bit.1/arch/parisc/Kconfig
--- 2.5.50/arch/parisc/Kconfig 2002-11-18 15:47:40.000000000 +1100
+++ 2.5.50-32bit.1/arch/parisc/Kconfig 2002-11-28 13:22:36.000000000 +1100
@@ -107,6 +107,11 @@
enable this option otherwise. The 64bit kernel is significantly bigger
and slower than the 32bit one.
+config COMPAT32
+ bool
+ depends PARISC64
+ default y
+
config PDC_NARROW
bool "32-bit firmware"
depends on PARISC64
diff -ruN 2.5.50/arch/parisc/kernel/ioctl32.c 2.5.50-32bit.1/arch/parisc/kernel/ioctl32.c
--- 2.5.50/arch/parisc/kernel/ioctl32.c 2002-10-31 14:05:12.000000000 +1100
+++ 2.5.50-32bit.1/arch/parisc/kernel/ioctl32.c 2002-11-28 14:38:55.000000000 +1100
@@ -10,6 +10,7 @@
#include <linux/config.h>
#include <linux/types.h>
+#include <linux/compat32.h>
#include "sys32.h"
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -1060,8 +1061,8 @@
#define PPPIOCSCOMPRESS32 _IOW('t', 77, struct ppp_option_data32)
struct ppp_idle32 {
- __kernel_time_t32 xmit_idle;
- __kernel_time_t32 recv_idle;
+ compat32_time_t xmit_idle;
+ compat32_time_t recv_idle;
};
#define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32)
diff -ruN 2.5.50/arch/parisc/kernel/sys_parisc32.c 2.5.50-32bit.1/arch/parisc/kernel/sys_parisc32.c
--- 2.5.50/arch/parisc/kernel/sys_parisc32.c 2002-11-18 15:47:40.000000000 +1100
+++ 2.5.50-32bit.1/arch/parisc/kernel/sys_parisc32.c 2002-11-28 14:37:59.000000000 +1100
@@ -52,6 +52,7 @@
#include <linux/mman.h>
#include <linux/binfmts.h>
#include <linux/namei.h>
+#include <linux/compat32.h>
#include <asm/types.h>
#include <asm/uaccess.h>
@@ -388,8 +389,8 @@
/* from utime.h */
struct utimbuf32 {
- __kernel_time_t32 actime;
- __kernel_time_t32 modtime;
+ compat32_time_t actime;
+ compat32_time_t modtime;
};
asmlinkage long sys32_utime(char *filename, struct utimbuf32 *times)
@@ -584,11 +585,6 @@
}
#endif /* CONFIG_SYSCTL */
-struct timespec32 {
- s32 tv_sec;
- s32 tv_nsec;
-};
-
static int
put_timespec32(struct timespec32 *u, struct timespec *t)
{
@@ -598,28 +594,6 @@
return copy_to_user(u, &t32, sizeof t32);
}
-asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
- struct timespec t;
- struct timespec32 t32;
- int ret;
- extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
-
- if (copy_from_user(&t32, rqtp, sizeof t32))
- return -EFAULT;
- t.tv_sec = t32.tv_sec;
- t.tv_nsec = t32.tv_nsec;
-
- DBG(("sys32_nanosleep({%d, %d})\n", t32.tv_sec, t32.tv_nsec));
-
- KERNEL_SYSCALL(ret, sys_nanosleep, &t, rmtp ? &t : NULL);
- if (rmtp && ret == -EINTR) {
- if (put_timespec32(rmtp, &t))
- return -EFAULT;
- }
- return ret;
-}
-
asmlinkage long sys32_sched_rr_get_interval(pid_t pid,
struct timespec32 *interval)
{
@@ -633,8 +607,6 @@
return ret;
}
-typedef __kernel_time_t32 time_t32;
-
static int
put_timeval32(struct timeval32 *u, struct timeval *t)
{
@@ -658,10 +630,10 @@
return err;
}
-asmlinkage long sys32_time(time_t32 *tloc)
+asmlinkage long sys32_time(compat32_time_t *tloc)
{
time_t now = get_seconds();
- time_t32 now32 = now;
+ compat32_time_t now32 = now;
if (tloc)
if (put_user(now32, tloc))
@@ -850,11 +822,11 @@
unsigned short st_reserved2; /* old st_gid */
__kernel_dev_t32 st_rdev;
__kernel_off_t32 st_size;
- __kernel_time_t32 st_atime;
+ compat32_time_t st_atime;
unsigned int st_spare1;
- __kernel_time_t32 st_mtime;
+ compat32_time_t st_mtime;
unsigned int st_spare2;
- __kernel_time_t32 st_ctime;
+ compat32_time_t st_ctime;
unsigned int st_spare3;
int st_blksize;
int st_blocks;
@@ -2903,8 +2875,8 @@
__u32 dqb_ihardlimit;
__u32 dqb_isoftlimit;
__u32 dqb_curinodes;
- __kernel_time_t32 dqb_btime;
- __kernel_time_t32 dqb_itime;
+ compat32_time_t dqb_btime;
+ compat32_time_t dqb_itime;
};
diff -ruN 2.5.50/arch/ppc64/Kconfig 2.5.50-32bit.1/arch/ppc64/Kconfig
--- 2.5.50/arch/ppc64/Kconfig 2002-11-18 15:47:40.000000000 +1100
+++ 2.5.50-32bit.1/arch/ppc64/Kconfig 2002-11-28 13:22:36.000000000 +1100
@@ -33,6 +33,10 @@
bool
default y
+config COMPAT32
+ bool
+ default y
+
source "init/Kconfig"
diff -ruN 2.5.50/arch/ppc64/kernel/ioctl32.c 2.5.50-32bit.1/arch/ppc64/kernel/ioctl32.c
--- 2.5.50/arch/ppc64/kernel/ioctl32.c 2002-11-11 14:55:28.000000000 +1100
+++ 2.5.50-32bit.1/arch/ppc64/kernel/ioctl32.c 2002-11-28 14:44:58.000000000 +1100
@@ -22,6 +22,7 @@
#include <linux/config.h>
#include <linux/types.h>
+#include <linux/compat32.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/smp.h>
@@ -1424,8 +1425,8 @@
#define PPPIOCSCOMPRESS32 _IOW('t', 77, struct ppp_option_data32)
struct ppp_idle32 {
- __kernel_time_t32 xmit_idle;
- __kernel_time_t32 recv_idle;
+ compat32_time_t xmit_idle;
+ compat32_time_t recv_idle;
};
#define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32)
diff -ruN 2.5.50/arch/ppc64/kernel/signal32.c 2.5.50-32bit.1/arch/ppc64/kernel/signal32.c
--- 2.5.50/arch/ppc64/kernel/signal32.c 2002-10-21 01:02:45.000000000 +1000
+++ 2.5.50-32bit.1/arch/ppc64/kernel/signal32.c 2002-11-28 13:22:36.000000000 +1100
@@ -22,6 +22,7 @@
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/elf.h>
+#include <linux/compat32.h>
#include <asm/ppc32.h>
#include <asm/uaccess.h>
#include <asm/ppcdebug.h>
@@ -53,11 +54,6 @@
#define MSR_USERCHANGE 0
#endif
-struct timespec32 {
- s32 tv_sec;
- s32 tv_nsec;
-};
-
struct sigregs32 {
/*
* the gp_regs array is 32 bit representation of the pt_regs
diff -ruN 2.5.50/arch/ppc64/kernel/sys_ppc32.c 2.5.50-32bit.1/arch/ppc64/kernel/sys_ppc32.c
--- 2.5.50/arch/ppc64/kernel/sys_ppc32.c 2002-11-28 10:35:37.000000000 +1100
+++ 2.5.50-32bit.1/arch/ppc64/kernel/sys_ppc32.c 2002-11-28 14:46:31.000000000 +1100
@@ -54,6 +54,7 @@
#include <linux/sysctl.h>
#include <linux/binfmts.h>
#include <linux/security.h>
+#include <linux/compat32.h>
#include <asm/types.h>
#include <asm/ipc.h>
@@ -72,7 +73,7 @@
extern asmlinkage long sys_utime(char * filename, struct utimbuf * times);
struct utimbuf32 {
- __kernel_time_t32 actime, modtime;
+ compat32_time_t actime, modtime;
};
asmlinkage long sys32_utime(char * filename, struct utimbuf32 *times)
@@ -1775,37 +1776,6 @@
-struct timespec32 {
- s32 tv_sec;
- s32 tv_nsec;
-};
-
-extern asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
-
-asmlinkage long sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
- struct timespec t;
- int ret;
- mm_segment_t old_fs = get_fs ();
-
- if (get_user (t.tv_sec, &rqtp->tv_sec) ||
- __get_user (t.tv_nsec, &rqtp->tv_nsec))
- return -EFAULT;
- set_fs (KERNEL_DS);
- ret = sys_nanosleep(&t, rmtp ? &t : NULL);
- set_fs (old_fs);
- if (rmtp && ret == -EINTR) {
- if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
- __put_user (t.tv_nsec, &rmtp->tv_nsec))
- return -EFAULT;
- }
-
- return ret;
-}
-
-
-
-
/* These are here just in case some old sparc32 binary calls it. */
asmlinkage long sys32_pause(void)
{
@@ -2163,8 +2133,8 @@
struct semid_ds32 {
struct ipc_perm sem_perm;
- __kernel_time_t32 sem_otime;
- __kernel_time_t32 sem_ctime;
+ compat32_time_t sem_otime;
+ compat32_time_t sem_ctime;
u32 sem_base;
u32 sem_pending;
u32 sem_pending_last;
@@ -2175,9 +2145,9 @@
struct semid64_ds32 {
struct ipc64_perm sem_perm;
unsigned int __unused1;
- __kernel_time_t32 sem_otime;
+ compat32_time_t sem_otime;
unsigned int __unused2;
- __kernel_time_t32 sem_ctime;
+ compat32_time_t sem_ctime;
u32 sem_nsems;
u32 __unused3;
u32 __unused4;
@@ -2188,9 +2158,9 @@
struct ipc_perm msg_perm;
u32 msg_first;
u32 msg_last;
- __kernel_time_t32 msg_stime;
- __kernel_time_t32 msg_rtime;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_stime;
+ compat32_time_t msg_rtime;
+ compat32_time_t msg_ctime;
u32 msg_lcbytes;
u32 msg_lqbytes;
unsigned short msg_cbytes;
@@ -2203,11 +2173,11 @@
struct msqid64_ds32 {
struct ipc64_perm msg_perm;
unsigned int __unused1;
- __kernel_time_t32 msg_stime;
+ compat32_time_t msg_stime;
unsigned int __unused2;
- __kernel_time_t32 msg_rtime;
+ compat32_time_t msg_rtime;
unsigned int __unused3;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_ctime;
unsigned int msg_cbytes;
unsigned int msg_qnum;
unsigned int msg_qbytes;
@@ -2220,9 +2190,9 @@
struct shmid_ds32 {
struct ipc_perm shm_perm;
int shm_segsz;
- __kernel_time_t32 shm_atime;
- __kernel_time_t32 shm_dtime;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_atime;
+ compat32_time_t shm_dtime;
+ compat32_time_t shm_ctime;
__kernel_ipc_pid_t32 shm_cpid;
__kernel_ipc_pid_t32 shm_lpid;
unsigned short shm_nattch;
@@ -2234,11 +2204,11 @@
struct shmid64_ds32 {
struct ipc64_perm shm_perm;
unsigned int __unused1;
- __kernel_time_t32 shm_atime;
+ compat32_time_t shm_atime;
unsigned int __unused2;
- __kernel_time_t32 shm_dtime;
+ compat32_time_t shm_dtime;
unsigned int __unused3;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_ctime;
unsigned int __unused4;
__kernel_size_t32 shm_segsz;
__kernel_pid_t32 shm_cpid;
@@ -3259,12 +3229,12 @@
* from 64-bit time values to 32-bit time values
*/
case SO_TIMESTAMP: {
- __kernel_time_t32* ptr_time32 = CMSG32_DATA(kcmsg32);
+ compat32_time_t* ptr_time32 = CMSG32_DATA(kcmsg32);
__kernel_time_t* ptr_time = CMSG_DATA(ucmsg);
*ptr_time32 = *ptr_time;
*(ptr_time32+1) = *(ptr_time+1);
kcmsg32->cmsg_len -= 2*(sizeof(__kernel_time_t) -
- sizeof(__kernel_time_t32));
+ sizeof(compat32_time_t));
}
default:;
}
@@ -4234,9 +4204,9 @@
return error;
}
-asmlinkage long sys32_time(__kernel_time_t32* tloc)
+asmlinkage long sys32_time(compat32_time_t* tloc)
{
- __kernel_time_t32 secs;
+ compat32_time_t secs;
struct timeval tv;
diff -ruN 2.5.50/arch/s390x/Kconfig 2.5.50-32bit.1/arch/s390x/Kconfig
--- 2.5.50/arch/s390x/Kconfig 2002-11-28 10:34:42.000000000 +1100
+++ 2.5.50-32bit.1/arch/s390x/Kconfig 2002-11-28 13:22:36.000000000 +1100
@@ -92,6 +92,11 @@
(and some other stuff like libraries and such) is needed for
executing 31 bit applications. It is safe to say "Y".
+config COMPAT32
+ bool
+ depends on S390_SUPPORT
+ default y
+
config BINFMT_ELF32
tristate "Kernel support for 31 bit ELF binaries"
depends on S390_SUPPORT
diff -ruN 2.5.50/arch/s390x/kernel/linux32.c 2.5.50-32bit.1/arch/s390x/kernel/linux32.c
--- 2.5.50/arch/s390x/kernel/linux32.c 2002-11-28 10:34:42.000000000 +1100
+++ 2.5.50-32bit.1/arch/s390x/kernel/linux32.c 2002-11-28 14:41:30.000000000 +1100
@@ -57,6 +57,7 @@
#include <linux/icmpv6.h>
#include <linux/sysctl.h>
#include <linux/binfmts.h>
+#include <linux/compat32.h>
#include <asm/types.h>
#include <asm/ipc.h>
@@ -318,8 +319,8 @@
struct semid_ds32 {
struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
- __kernel_time_t32 sem_otime; /* last semop time */
- __kernel_time_t32 sem_ctime; /* last change time */
+ compat32_time_t sem_otime; /* last semop time */
+ compat32_time_t sem_ctime; /* last change time */
u32 sem_base; /* ptr to first semaphore in array */
u32 sem_pending; /* pending operations to be processed */
u32 sem_pending_last; /* last pending operation */
@@ -330,9 +331,9 @@
struct semid64_ds32 {
struct ipc64_perm_ds32 sem_perm;
unsigned int __pad1;
- __kernel_time_t32 sem_otime;
+ compat32_time_t sem_otime;
unsigned int __pad2;
- __kernel_time_t32 sem_ctime;
+ compat32_time_t sem_ctime;
u32 sem_nsems;
u32 __unused1;
u32 __unused2;
@@ -343,9 +344,9 @@
struct ipc_perm32 msg_perm;
u32 msg_first;
u32 msg_last;
- __kernel_time_t32 msg_stime;
- __kernel_time_t32 msg_rtime;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_stime;
+ compat32_time_t msg_rtime;
+ compat32_time_t msg_ctime;
u32 wwait;
u32 rwait;
unsigned short msg_cbytes;
@@ -358,11 +359,11 @@
struct msqid64_ds32 {
struct ipc64_perm_ds32 msg_perm;
unsigned int __pad1;
- __kernel_time_t32 msg_stime;
+ compat32_time_t msg_stime;
unsigned int __pad2;
- __kernel_time_t32 msg_rtime;
+ compat32_time_t msg_rtime;
unsigned int __pad3;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_ctime;
unsigned int msg_cbytes;
unsigned int msg_qnum;
unsigned int msg_qbytes;
@@ -376,9 +377,9 @@
struct shmid_ds32 {
struct ipc_perm32 shm_perm;
int shm_segsz;
- __kernel_time_t32 shm_atime;
- __kernel_time_t32 shm_dtime;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_atime;
+ compat32_time_t shm_dtime;
+ compat32_time_t shm_ctime;
__kernel_ipc_pid_t32 shm_cpid;
__kernel_ipc_pid_t32 shm_lpid;
unsigned short shm_nattch;
@@ -387,11 +388,11 @@
struct shmid64_ds32 {
struct ipc64_perm_ds32 shm_perm;
__kernel_size_t32 shm_segsz;
- __kernel_time_t32 shm_atime;
+ compat32_time_t shm_atime;
unsigned int __unused1;
- __kernel_time_t32 shm_dtime;
+ compat32_time_t shm_dtime;
unsigned int __unused2;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_ctime;
unsigned int __unused3;
__kernel_pid_t32 shm_cpid;
__kernel_pid_t32 shm_lpid;
@@ -1013,7 +1014,7 @@
extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
struct utimbuf32 {
- __kernel_time_t32 actime, modtime;
+ compat32_time_t actime, modtime;
};
asmlinkage int sys32_utime(char * filename, struct utimbuf32 *times)
@@ -1774,11 +1775,6 @@
return ret;
}
-struct timespec32 {
- s32 tv_sec;
- s32 tv_nsec;
-};
-
extern asmlinkage int sys_sched_rr_get_interval(pid_t pid, struct timespec *interval);
asmlinkage int sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
@@ -1796,28 +1792,6 @@
return ret;
}
-extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
-
-asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
- struct timespec t;
- int ret;
- mm_segment_t old_fs = get_fs ();
-
- if (get_user (t.tv_sec, &rqtp->tv_sec) ||
- __get_user (t.tv_nsec, &rqtp->tv_nsec))
- return -EFAULT;
- set_fs (KERNEL_DS);
- ret = sys_nanosleep(&t, rmtp ? &t : NULL);
- set_fs (old_fs);
- if (rmtp && ret == -EINTR) {
- if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
- __put_user (t.tv_nsec, &rmtp->tv_nsec))
- return -EFAULT;
- }
- return ret;
-}
-
extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset);
asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset)
@@ -2498,12 +2472,12 @@
* from 64-bit time values to 32-bit time values
*/
case SO_TIMESTAMP: {
- __kernel_time_t32* ptr_time32 = CMSG32_DATA(kcmsg32);
+ compat32_time_t* ptr_time32 = CMSG32_DATA(kcmsg32);
__kernel_time_t* ptr_time = CMSG_DATA(ucmsg);
get_user(*ptr_time32, ptr_time);
get_user(*(ptr_time32+1), ptr_time+1);
kcmsg32->cmsg_len -= 2*(sizeof(__kernel_time_t) -
- sizeof(__kernel_time_t32));
+ sizeof(compat32_time_t));
}
default:;
}
diff -ruN 2.5.50/arch/s390x/kernel/linux32.h 2.5.50-32bit.1/arch/s390x/kernel/linux32.h
--- 2.5.50/arch/s390x/kernel/linux32.h 2002-10-08 12:02:40.000000000 +1000
+++ 2.5.50-32bit.1/arch/s390x/kernel/linux32.h 2002-11-28 14:39:23.000000000 +1100
@@ -18,7 +18,6 @@
typedef unsigned int __kernel_size_t32;
typedef int __kernel_ssize_t32;
typedef int __kernel_ptrdiff_t32;
-typedef int __kernel_time_t32;
typedef int __kernel_clock_t32;
typedef int __kernel_pid_t32;
typedef unsigned short __kernel_ipc_pid_t32;
diff -ruN 2.5.50/arch/s390x/kernel/wrapper32.S 2.5.50-32bit.1/arch/s390x/kernel/wrapper32.S
--- 2.5.50/arch/s390x/kernel/wrapper32.S 2002-11-28 10:34:42.000000000 +1100
+++ 2.5.50-32bit.1/arch/s390x/kernel/wrapper32.S 2002-11-28 13:22:36.000000000 +1100
@@ -748,8 +748,8 @@
.globl sys32_nanosleep_wrapper
sys32_nanosleep_wrapper:
- llgtr %r2,%r2 # struct timespec_emu31 *
- llgtr %r3,%r3 # struct timespec_emu31 *
+ llgtr %r2,%r2 # struct timespec32 *
+ llgtr %r3,%r3 # struct timespec32 *
jg sys32_nanosleep # branch to system call
.globl sys32_mremap_wrapper
diff -ruN 2.5.50/arch/sparc64/Kconfig 2.5.50-32bit.1/arch/sparc64/Kconfig
--- 2.5.50/arch/sparc64/Kconfig 2002-11-28 10:35:37.000000000 +1100
+++ 2.5.50-32bit.1/arch/sparc64/Kconfig 2002-11-28 13:22:36.000000000 +1100
@@ -352,6 +352,11 @@
This allows you to run 32-bit binaries on your Ultra.
Everybody wants this; say Y.
+config COMPAT32
+ bool
+ depends on SPARC32_COMPAT
+ default y
+
config BINFMT_ELF32
tristate "Kernel support for 32-bit ELF binaries"
depends on SPARC32_COMPAT
diff -ruN 2.5.50/arch/sparc64/kernel/ioctl32.c 2.5.50-32bit.1/arch/sparc64/kernel/ioctl32.c
--- 2.5.50/arch/sparc64/kernel/ioctl32.c 2002-11-18 15:47:41.000000000 +1100
+++ 2.5.50-32bit.1/arch/sparc64/kernel/ioctl32.c 2002-11-28 14:43:09.000000000 +1100
@@ -10,6 +10,7 @@
#include <linux/config.h>
#include <linux/types.h>
+#include <linux/compat32.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/smp.h>
@@ -1743,8 +1744,8 @@
#define PPPIOCSCOMPRESS32 _IOW('t', 77, struct ppp_option_data32)
struct ppp_idle32 {
- __kernel_time_t32 xmit_idle;
- __kernel_time_t32 recv_idle;
+ compat32_time_t xmit_idle;
+ compat32_time_t recv_idle;
};
#define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32)
diff -ruN 2.5.50/arch/sparc64/kernel/sys_sparc32.c 2.5.50-32bit.1/arch/sparc64/kernel/sys_sparc32.c
--- 2.5.50/arch/sparc64/kernel/sys_sparc32.c 2002-11-28 10:35:37.000000000 +1100
+++ 2.5.50-32bit.1/arch/sparc64/kernel/sys_sparc32.c 2002-11-28 14:44:11.000000000 +1100
@@ -51,6 +51,7 @@
#include <linux/sysctl.h>
#include <linux/binfmts.h>
#include <linux/dnotify.h>
+#include <linux/compat32.h>
#include <asm/types.h>
#include <asm/ipc.h>
@@ -327,8 +328,8 @@
struct semid_ds32 {
struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
- __kernel_time_t32 sem_otime; /* last semop time */
- __kernel_time_t32 sem_ctime; /* last change time */
+ compat32_time_t sem_otime; /* last semop time */
+ compat32_time_t sem_ctime; /* last change time */
u32 sem_base; /* ptr to first semaphore in array */
u32 sem_pending; /* pending operations to be processed */
u32 sem_pending_last; /* last pending operation */
@@ -339,9 +340,9 @@
struct semid64_ds32 {
struct ipc64_perm sem_perm; /* this structure is the same on sparc32 and sparc64 */
unsigned int __pad1;
- __kernel_time_t32 sem_otime;
+ compat32_time_t sem_otime;
unsigned int __pad2;
- __kernel_time_t32 sem_ctime;
+ compat32_time_t sem_ctime;
u32 sem_nsems;
u32 __unused1;
u32 __unused2;
@@ -352,9 +353,9 @@
struct ipc_perm32 msg_perm;
u32 msg_first;
u32 msg_last;
- __kernel_time_t32 msg_stime;
- __kernel_time_t32 msg_rtime;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_stime;
+ compat32_time_t msg_rtime;
+ compat32_time_t msg_ctime;
u32 wwait;
u32 rwait;
unsigned short msg_cbytes;
@@ -367,11 +368,11 @@
struct msqid64_ds32 {
struct ipc64_perm msg_perm;
unsigned int __pad1;
- __kernel_time_t32 msg_stime;
+ compat32_time_t msg_stime;
unsigned int __pad2;
- __kernel_time_t32 msg_rtime;
+ compat32_time_t msg_rtime;
unsigned int __pad3;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_ctime;
unsigned int msg_cbytes;
unsigned int msg_qnum;
unsigned int msg_qbytes;
@@ -385,9 +386,9 @@
struct shmid_ds32 {
struct ipc_perm32 shm_perm;
int shm_segsz;
- __kernel_time_t32 shm_atime;
- __kernel_time_t32 shm_dtime;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_atime;
+ compat32_time_t shm_dtime;
+ compat32_time_t shm_ctime;
__kernel_ipc_pid_t32 shm_cpid;
__kernel_ipc_pid_t32 shm_lpid;
unsigned short shm_nattch;
@@ -396,11 +397,11 @@
struct shmid64_ds32 {
struct ipc64_perm shm_perm;
unsigned int __pad1;
- __kernel_time_t32 shm_atime;
+ compat32_time_t shm_atime;
unsigned int __pad2;
- __kernel_time_t32 shm_dtime;
+ compat32_time_t shm_dtime;
unsigned int __pad3;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_ctime;
__kernel_size_t32 shm_segsz;
__kernel_pid_t32 shm_cpid;
__kernel_pid_t32 shm_lpid;
@@ -967,7 +968,7 @@
extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
struct utimbuf32 {
- __kernel_time_t32 actime, modtime;
+ compat32_time_t actime, modtime;
};
asmlinkage int sys32_utime(char * filename, struct utimbuf32 *times)
@@ -1794,11 +1795,6 @@
return ret;
}
-struct timespec32 {
- s32 tv_sec;
- s32 tv_nsec;
-};
-
extern asmlinkage int sys_sched_rr_get_interval(pid_t pid, struct timespec *interval);
asmlinkage int sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
@@ -1816,28 +1812,6 @@
return ret;
}
-extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
-
-asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
- struct timespec t;
- int ret;
- mm_segment_t old_fs = get_fs ();
-
- if (get_user (t.tv_sec, &rqtp->tv_sec) ||
- __get_user (t.tv_nsec, &rqtp->tv_nsec))
- return -EFAULT;
- set_fs (KERNEL_DS);
- ret = sys_nanosleep(&t, rmtp ? &t : NULL);
- set_fs (old_fs);
- if (rmtp && ret == -EINTR) {
- if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
- __put_user (t.tv_nsec, &rmtp->tv_nsec))
- return -EFAULT;
- }
- return ret;
-}
-
extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset);
asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset)
diff -ruN 2.5.50/arch/sparc64/kernel/sys_sunos32.c 2.5.50-32bit.1/arch/sparc64/kernel/sys_sunos32.c
--- 2.5.50/arch/sparc64/kernel/sys_sunos32.c 2002-11-28 10:34:43.000000000 +1100
+++ 2.5.50-32bit.1/arch/sparc64/kernel/sys_sunos32.c 2002-11-28 14:42:21.000000000 +1100
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
+#include <linux/compat32.h>
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/swap.h>
@@ -948,9 +949,9 @@
struct ipc_perm32 msg_perm;
u32 msg_first;
u32 msg_last;
- __kernel_time_t32 msg_stime;
- __kernel_time_t32 msg_rtime;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_stime;
+ compat32_time_t msg_rtime;
+ compat32_time_t msg_ctime;
u32 wwait;
u32 rwait;
unsigned short msg_cbytes;
@@ -1085,9 +1086,9 @@
struct shmid_ds32 {
struct ipc_perm32 shm_perm;
int shm_segsz;
- __kernel_time_t32 shm_atime;
- __kernel_time_t32 shm_dtime;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_atime;
+ compat32_time_t shm_dtime;
+ compat32_time_t shm_ctime;
__kernel_ipc_pid_t32 shm_cpid;
__kernel_ipc_pid_t32 shm_lpid;
unsigned short shm_nattch;
diff -ruN 2.5.50/arch/x86_64/Kconfig 2.5.50-32bit.1/arch/x86_64/Kconfig
--- 2.5.50/arch/x86_64/Kconfig 2002-11-28 10:34:43.000000000 +1100
+++ 2.5.50-32bit.1/arch/x86_64/Kconfig 2002-11-28 13:22:36.000000000 +1100
@@ -425,6 +425,11 @@
turn this on, unless you're 100% sure that you don't have any 32bit programs
left.
+config COMPAT32
+ bool
+ depends on IA32_EMULATION
+ default y
+
endmenu
source "drivers/mtd/Kconfig"
diff -ruN 2.5.50/arch/x86_64/ia32/ia32_ioctl.c 2.5.50-32bit.1/arch/x86_64/ia32/ia32_ioctl.c
--- 2.5.50/arch/x86_64/ia32/ia32_ioctl.c 2002-10-21 01:02:47.000000000 +1000
+++ 2.5.50-32bit.1/arch/x86_64/ia32/ia32_ioctl.c 2002-11-28 14:47:13.000000000 +1100
@@ -11,6 +11,7 @@
#include <linux/config.h>
#include <linux/types.h>
+#include <linux/compat32.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/smp.h>
@@ -1611,8 +1612,8 @@
#define PPPIOCSCOMPRESS32 _IOW('t', 77, struct ppp_option_data32)
struct ppp_idle32 {
- __kernel_time_t32 xmit_idle;
- __kernel_time_t32 recv_idle;
+ compat32_time_t xmit_idle;
+ compat32_time_t recv_idle;
};
#define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32)
diff -ruN 2.5.50/arch/x86_64/ia32/ipc32.c 2.5.50-32bit.1/arch/x86_64/ia32/ipc32.c
--- 2.5.50/arch/x86_64/ia32/ipc32.c 2002-10-21 01:02:47.000000000 +1000
+++ 2.5.50-32bit.1/arch/x86_64/ia32/ipc32.c 2002-11-28 14:48:46.000000000 +1100
@@ -8,6 +8,7 @@
#include <linux/shm.h>
#include <linux/slab.h>
#include <linux/ipc.h>
+#include <linux/compat32.h>
#include <asm/mman.h>
#include <asm/types.h>
#include <asm/uaccess.h>
@@ -53,8 +54,8 @@
struct semid_ds32 {
struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
- __kernel_time_t32 sem_otime; /* last semop time */
- __kernel_time_t32 sem_ctime; /* last change time */
+ compat32_time_t sem_otime; /* last semop time */
+ compat32_time_t sem_ctime; /* last change time */
u32 sem_base; /* ptr to first semaphore in array */
u32 sem_pending; /* pending operations to be processed */
u32 sem_pending_last; /* last pending operation */
@@ -64,9 +65,9 @@
struct semid64_ds32 {
struct ipc64_perm32 sem_perm;
- __kernel_time_t32 sem_otime;
+ compat32_time_t sem_otime;
unsigned int __unused1;
- __kernel_time_t32 sem_ctime;
+ compat32_time_t sem_ctime;
unsigned int __unused2;
unsigned int sem_nsems;
unsigned int __unused3;
@@ -77,9 +78,9 @@
struct ipc_perm32 msg_perm;
u32 msg_first;
u32 msg_last;
- __kernel_time_t32 msg_stime;
- __kernel_time_t32 msg_rtime;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_stime;
+ compat32_time_t msg_rtime;
+ compat32_time_t msg_ctime;
u32 wwait;
u32 rwait;
unsigned short msg_cbytes;
@@ -91,11 +92,11 @@
struct msqid64_ds32 {
struct ipc64_perm32 msg_perm;
- __kernel_time_t32 msg_stime;
+ compat32_time_t msg_stime;
unsigned int __unused1;
- __kernel_time_t32 msg_rtime;
+ compat32_time_t msg_rtime;
unsigned int __unused2;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_ctime;
unsigned int __unused3;
unsigned int msg_cbytes;
unsigned int msg_qnum;
@@ -109,9 +110,9 @@
struct shmid_ds32 {
struct ipc_perm32 shm_perm;
int shm_segsz;
- __kernel_time_t32 shm_atime;
- __kernel_time_t32 shm_dtime;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_atime;
+ compat32_time_t shm_dtime;
+ compat32_time_t shm_ctime;
__kernel_ipc_pid_t32 shm_cpid;
__kernel_ipc_pid_t32 shm_lpid;
unsigned short shm_nattch;
@@ -120,11 +121,11 @@
struct shmid64_ds32 {
struct ipc64_perm32 shm_perm;
__kernel_size_t32 shm_segsz;
- __kernel_time_t32 shm_atime;
+ compat32_time_t shm_atime;
unsigned int __unused1;
- __kernel_time_t32 shm_dtime;
+ compat32_time_t shm_dtime;
unsigned int __unused2;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_ctime;
unsigned int __unused3;
__kernel_pid_t32 shm_cpid;
__kernel_pid_t32 shm_lpid;
diff -ruN 2.5.50/arch/x86_64/ia32/sys_ia32.c 2.5.50-32bit.1/arch/x86_64/ia32/sys_ia32.c
--- 2.5.50/arch/x86_64/ia32/sys_ia32.c 2002-11-18 15:47:41.000000000 +1100
+++ 2.5.50-32bit.1/arch/x86_64/ia32/sys_ia32.c 2002-11-28 14:47:41.000000000 +1100
@@ -58,6 +58,7 @@
#include <linux/binfmts.h>
#include <linux/init.h>
#include <linux/aio_abi.h>
+#include <linux/compat32.h>
#include <asm/mman.h>
#include <asm/types.h>
#include <asm/uaccess.h>
@@ -934,36 +935,6 @@
(struct timeval32 *)A(a.tvp));
}
-struct timespec32 {
- int tv_sec;
- int tv_nsec;
-};
-
-extern asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
-
-asmlinkage long
-sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
- struct timespec t;
- int ret;
- mm_segment_t old_fs = get_fs ();
-
- if (verify_area(VERIFY_READ, rqtp, sizeof(struct timespec32)) ||
- __get_user (t.tv_sec, &rqtp->tv_sec) ||
- __get_user (t.tv_nsec, &rqtp->tv_nsec))
- return -EFAULT;
- set_fs (KERNEL_DS);
- ret = sys_nanosleep(&t, rmtp ? &t : NULL);
- set_fs (old_fs);
- if (rmtp && ret == -EINTR) {
- if (verify_area(VERIFY_WRITE, rmtp, sizeof(struct timespec32)) ||
- __put_user (t.tv_sec, &rmtp->tv_sec) ||
- __put_user (t.tv_nsec, &rmtp->tv_nsec))
- return -EFAULT;
- }
- return ret;
-}
-
asmlinkage ssize_t sys_readv(unsigned long,const struct iovec *,unsigned long);
asmlinkage ssize_t sys_writev(unsigned long,const struct iovec *,unsigned long);
@@ -1409,7 +1380,7 @@
extern asmlinkage long sys_utime(char * filename, struct utimbuf * times);
struct utimbuf32 {
- __kernel_time_t32 actime, modtime;
+ compat32_time_t actime, modtime;
};
asmlinkage long
diff -ruN 2.5.50/include/asm-ia64/compat32.h 2.5.50-32bit.1/include/asm-ia64/compat32.h
--- 2.5.50/include/asm-ia64/compat32.h 1970-01-01 10:00:00.000000000 +1000
+++ 2.5.50-32bit.1/include/asm-ia64/compat32.h 2002-11-28 14:20:49.000000000 +1100
@@ -0,0 +1,9 @@
+#ifndef _ASM_IA64_COMPAT32_H
+#define _ASM_IA64_COMPAT32_H
+/*
+ * Architecture specific 32 bit compatibility types
+ */
+
+typedef s32 compat32_time_t;
+
+#endif /* _ASM_IA64_COMPAT32_H */
diff -ruN 2.5.50/include/asm-ia64/ia32.h 2.5.50-32bit.1/include/asm-ia64/ia32.h
--- 2.5.50/include/asm-ia64/ia32.h 2002-10-31 14:06:05.000000000 +1100
+++ 2.5.50-32bit.1/include/asm-ia64/ia32.h 2002-11-28 14:30:23.000000000 +1100
@@ -15,7 +15,6 @@
typedef unsigned int __kernel_size_t32;
typedef int __kernel_ssize_t32;
typedef int __kernel_ptrdiff_t32;
-typedef int __kernel_time_t32;
typedef int __kernel_clock_t32;
typedef int __kernel_pid_t32;
typedef unsigned short __kernel_ipc_pid_t32;
@@ -41,11 +40,6 @@
#define IA32_CLOCKS_PER_SEC 100 /* Cast in stone for IA32 Linux */
#define IA32_TICK(tick) ((unsigned long long)(tick) * IA32_CLOCKS_PER_SEC / CLOCKS_PER_SEC)
-struct timespec32 {
- int tv_sec;
- int tv_nsec;
-};
-
/* fcntl.h */
struct flock32 {
short l_type;
diff -ruN 2.5.50/include/asm-mips64/compat32.h 2.5.50-32bit.1/include/asm-mips64/compat32.h
--- 2.5.50/include/asm-mips64/compat32.h 1970-01-01 10:00:00.000000000 +1000
+++ 2.5.50-32bit.1/include/asm-mips64/compat32.h 2002-11-28 14:22:15.000000000 +1100
@@ -0,0 +1,9 @@
+#ifndef _ASM_MIPS64_COMPAT32_H
+#define _ASM_MIPS64_COMPAT32_H
+/*
+ * Architecture specific 32 bit compatibility types
+ */
+
+typedef s32 compat32_time_t;
+
+#endif /* _ASM_MIPS64_COMPAT32_H */
diff -ruN 2.5.50/include/asm-mips64/posix_types.h 2.5.50-32bit.1/include/asm-mips64/posix_types.h
--- 2.5.50/include/asm-mips64/posix_types.h 2000-07-10 15:18:15.000000000 +1000
+++ 2.5.50-32bit.1/include/asm-mips64/posix_types.h 2002-11-28 14:30:39.000000000 +1100
@@ -61,7 +61,6 @@
typedef unsigned int __kernel_size_t32;
typedef int __kernel_ssize_t32;
typedef int __kernel_ptrdiff_t32;
-typedef int __kernel_time_t32;
typedef int __kernel_suseconds_t32;
typedef int __kernel_clock_t32;
typedef int __kernel_daddr_t32;
diff -ruN 2.5.50/include/asm-mips64/stat.h 2.5.50-32bit.1/include/asm-mips64/stat.h
--- 2.5.50/include/asm-mips64/stat.h 2002-11-18 15:47:55.000000000 +1100
+++ 2.5.50-32bit.1/include/asm-mips64/stat.h 2002-11-28 14:31:37.000000000 +1100
@@ -10,6 +10,7 @@
#define _ASM_STAT_H
#include <linux/types.h>
+#include <linux/compat32.h>
struct __old_kernel_stat {
unsigned int st_dev;
@@ -40,11 +41,11 @@
int st_pad2[2];
__kernel_off_t32 st_size;
int st_pad3;
- __kernel_time_t32 st_atime;
+ compat32_time_t st_atime;
int reserved0;
- __kernel_time_t32 st_mtime;
+ compat32_time_t st_mtime;
int reserved1;
- __kernel_time_t32 st_ctime;
+ compat32_time_t st_ctime;
int reserved2;
int st_blksize;
int st_blocks;
diff -ruN 2.5.50/include/asm-parisc/compat32.h 2.5.50-32bit.1/include/asm-parisc/compat32.h
--- 2.5.50/include/asm-parisc/compat32.h 1970-01-01 10:00:00.000000000 +1000
+++ 2.5.50-32bit.1/include/asm-parisc/compat32.h 2002-11-28 14:22:38.000000000 +1100
@@ -0,0 +1,9 @@
+#ifndef _ASM_PARISC_COMPAT32_H
+#define _ASM_PARISC_COMPAT32_H
+/*
+ * Architecture specific 32 bit compatibility types
+ */
+
+typedef s32 compat32_time_t;
+
+#endif /* _ASM_PARISC_COMPAT32_H */
diff -ruN 2.5.50/include/asm-parisc/posix_types.h 2.5.50-32bit.1/include/asm-parisc/posix_types.h
--- 2.5.50/include/asm-parisc/posix_types.h 2002-10-31 14:06:07.000000000 +1100
+++ 2.5.50-32bit.1/include/asm-parisc/posix_types.h 2002-11-28 14:31:56.000000000 +1100
@@ -69,7 +69,6 @@
typedef unsigned int __kernel_size_t32;
typedef int __kernel_ssize_t32;
typedef int __kernel_ptrdiff_t32;
-typedef int __kernel_time_t32;
typedef int __kernel_suseconds_t32;
typedef int __kernel_clock_t32;
typedef int __kernel_daddr_t32;
diff -ruN 2.5.50/include/asm-ppc64/compat32.h 2.5.50-32bit.1/include/asm-ppc64/compat32.h
--- 2.5.50/include/asm-ppc64/compat32.h 1970-01-01 10:00:00.000000000 +1000
+++ 2.5.50-32bit.1/include/asm-ppc64/compat32.h 2002-11-28 14:22:47.000000000 +1100
@@ -0,0 +1,9 @@
+#ifndef _ASM_PPC64_COMPAT32_H
+#define _ASM_PPC64_COMPAT32_H
+/*
+ * Architecture specific 32 bit compatibility types
+ */
+
+typedef s32 compat32_time_t;
+
+#endif /* _ASM_PPC64_COMPAT32_H */
diff -ruN 2.5.50/include/asm-ppc64/ppc32.h 2.5.50-32bit.1/include/asm-ppc64/ppc32.h
--- 2.5.50/include/asm-ppc64/ppc32.h 2002-10-21 01:02:53.000000000 +1000
+++ 2.5.50-32bit.1/include/asm-ppc64/ppc32.h 2002-11-28 14:34:33.000000000 +1100
@@ -1,6 +1,7 @@
#ifndef _PPC64_PPC32_H
#define _PPC64_PPC32_H
+#include <linux/compat32.h>
#include <asm/siginfo.h>
#include <asm/signal.h>
@@ -46,7 +47,6 @@
typedef unsigned int __kernel_size_t32;
typedef int __kernel_ssize_t32;
typedef int __kernel_ptrdiff_t32;
-typedef int __kernel_time_t32;
typedef int __kernel_clock_t32;
typedef int __kernel_pid_t32;
typedef unsigned short __kernel_ipc_pid_t32;
@@ -185,11 +185,11 @@
__kernel_off_t32 st_size; /* 4 */
__kernel_off_t32 st_blksize; /* 4 */
__kernel_off_t32 st_blocks; /* 4 */
- __kernel_time_t32 st_atime; /* 4 */
+ compat32_time_t st_atime; /* 4 */
unsigned int __unused1; /* 4 */
- __kernel_time_t32 st_mtime; /* 4 */
+ compat32_time_t st_mtime; /* 4 */
unsigned int __unused2; /* 4 */
- __kernel_time_t32 st_ctime; /* 4 */
+ compat32_time_t st_ctime; /* 4 */
unsigned int __unused3; /* 4 */
unsigned int __unused4[2]; /* 2*4 */
};
diff -ruN 2.5.50/include/asm-s390x/compat32.h 2.5.50-32bit.1/include/asm-s390x/compat32.h
--- 2.5.50/include/asm-s390x/compat32.h 1970-01-01 10:00:00.000000000 +1000
+++ 2.5.50-32bit.1/include/asm-s390x/compat32.h 2002-11-28 14:22:59.000000000 +1100
@@ -0,0 +1,9 @@
+#ifndef _ASM_S390X_COMPAT32_H
+#define _ASM_S390X_COMPAT32_H
+/*
+ * Architecture specific 32 bit compatibility types
+ */
+
+typedef s32 compat32_time_t;
+
+#endif /* _ASM_S390X_COMPAT32_H */
diff -ruN 2.5.50/include/asm-sparc64/compat32.h 2.5.50-32bit.1/include/asm-sparc64/compat32.h
--- 2.5.50/include/asm-sparc64/compat32.h 1970-01-01 10:00:00.000000000 +1000
+++ 2.5.50-32bit.1/include/asm-sparc64/compat32.h 2002-11-28 14:23:09.000000000 +1100
@@ -0,0 +1,9 @@
+#ifndef _ASM_SPARC64_COMPAT32_H
+#define _ASM_SPARC64_COMPAT32_H
+/*
+ * Architecture specific 32 bit compatibility types
+ */
+
+typedef s32 compat32_time_t;
+
+#endif /* _ASM_SPARC64_COMPAT32_H */
diff -ruN 2.5.50/include/asm-sparc64/posix_types.h 2.5.50-32bit.1/include/asm-sparc64/posix_types.h
--- 2.5.50/include/asm-sparc64/posix_types.h 2000-10-28 04:55:01.000000000 +1100
+++ 2.5.50-32bit.1/include/asm-sparc64/posix_types.h 2002-11-28 14:32:10.000000000 +1100
@@ -51,7 +51,6 @@
typedef unsigned int __kernel_size_t32;
typedef int __kernel_ssize_t32;
typedef int __kernel_ptrdiff_t32;
-typedef int __kernel_time_t32;
typedef int __kernel_clock_t32;
typedef int __kernel_pid_t32;
typedef unsigned short __kernel_ipc_pid_t32;
diff -ruN 2.5.50/include/asm-sparc64/stat.h 2.5.50-32bit.1/include/asm-sparc64/stat.h
--- 2.5.50/include/asm-sparc64/stat.h 2002-11-18 15:47:55.000000000 +1100
+++ 2.5.50-32bit.1/include/asm-sparc64/stat.h 2002-11-28 14:33:25.000000000 +1100
@@ -3,6 +3,7 @@
#define _SPARC64_STAT_H
#include <linux/types.h>
+#include <linux/compat32.h>
#include <linux/time.h>
struct stat32 {
@@ -14,11 +15,11 @@
__kernel_gid_t32 st_gid;
__kernel_dev_t32 st_rdev;
__kernel_off_t32 st_size;
- __kernel_time_t32 st_atime;
+ compat32_time_t st_atime;
unsigned int __unused1;
- __kernel_time_t32 st_mtime;
+ compat32_time_t st_mtime;
unsigned int __unused2;
- __kernel_time_t32 st_ctime;
+ compat32_time_t st_ctime;
unsigned int __unused3;
__kernel_off_t32 st_blksize;
__kernel_off_t32 st_blocks;
diff -ruN 2.5.50/include/asm-x86_64/compat32.h 2.5.50-32bit.1/include/asm-x86_64/compat32.h
--- 2.5.50/include/asm-x86_64/compat32.h 1970-01-01 10:00:00.000000000 +1000
+++ 2.5.50-32bit.1/include/asm-x86_64/compat32.h 2002-11-28 14:23:21.000000000 +1100
@@ -0,0 +1,9 @@
+#ifndef _ASM_X86_64_COMPAT32_H
+#define _ASM_X86_64_COMPAT32_H
+/*
+ * Architecture specific 32 bit compatibility types
+ */
+
+typedef s32 compat32_time_t;
+
+#endif /* _ASM_X86_64_COMPAT32_H */
diff -ruN 2.5.50/include/asm-x86_64/ia32.h 2.5.50-32bit.1/include/asm-x86_64/ia32.h
--- 2.5.50/include/asm-x86_64/ia32.h 2002-10-21 13:35:27.000000000 +1000
+++ 2.5.50-32bit.1/include/asm-x86_64/ia32.h 2002-11-28 14:34:57.000000000 +1100
@@ -13,7 +13,6 @@
typedef unsigned int __kernel_size_t32;
typedef int __kernel_ssize_t32;
typedef int __kernel_ptrdiff_t32;
-typedef int __kernel_time_t32;
typedef int __kernel_clock_t32;
typedef int __kernel_pid_t32;
typedef unsigned short __kernel_ipc_pid_t32;
diff -ruN 2.5.50/include/linux/compat32.h 2.5.50-32bit.1/include/linux/compat32.h
--- 2.5.50/include/linux/compat32.h 1970-01-01 10:00:00.000000000 +1000
+++ 2.5.50-32bit.1/include/linux/compat32.h 2002-11-28 14:24:26.000000000 +1100
@@ -0,0 +1,15 @@
+#ifndef _LINUX_COMPAT32_H
+#define _LINUX_COMPAT32_H
+/*
+ * These are the type definitions for the 32 compatibility
+ * layer on 64 bit architectures.
+ */
+#include <linux/types.h>
+#include <asm/compat32.h>
+
+struct timespec32 {
+ compat32_time_t tv_sec;
+ s32 tv_nsec;
+};
+
+#endif /* _LINUX_COMPAT32_H */
diff -ruN 2.5.50/include/linux/time.h 2.5.50-32bit.1/include/linux/time.h
--- 2.5.50/include/linux/time.h 2002-11-18 15:47:56.000000000 +1100
+++ 2.5.50-32bit.1/include/linux/time.h 2002-11-28 13:52:45.000000000 +1100
@@ -138,6 +138,7 @@
#ifdef __KERNEL__
extern void do_gettimeofday(struct timeval *tv);
extern void do_settimeofday(struct timeval *tv);
+extern long do_nanosleep(struct timespec *t);
#endif
#define FD_SETSIZE __FD_SETSIZE
diff -ruN 2.5.50/kernel/Makefile 2.5.50-32bit.1/kernel/Makefile
--- 2.5.50/kernel/Makefile 2002-11-28 10:34:59.000000000 +1100
+++ 2.5.50-32bit.1/kernel/Makefile 2002-11-28 14:11:10.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_COMPAT32) += compat32.o
ifneq ($(CONFIG_IA64),y)
# According to Alan Modra <[email protected]>, the -fno-omit-frame-pointer is
diff -ruN 2.5.50/kernel/compat32.c 2.5.50-32bit.1/kernel/compat32.c
--- 2.5.50/kernel/compat32.c 1970-01-01 10:00:00.000000000 +1000
+++ 2.5.50-32bit.1/kernel/compat32.c 2002-11-28 14:12:49.000000000 +1100
@@ -0,0 +1,40 @@
+/*
+ * linux/kernel/compat32.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/compat32.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+
+#include <asm/uaccess.h>
+
+asmlinkage long sys32_nanosleep(struct timespec32 *rqtp,
+ struct timespec32 *rmtp)
+{
+ struct timespec t;
+ struct timespec32 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;
+}
diff -ruN 2.5.50/kernel/timer.c 2.5.50-32bit.1/kernel/timer.c
--- 2.5.50/kernel/timer.c 2002-11-28 10:35:50.000000000 +1100
+++ 2.5.50-32bit.1/kernel/timer.c 2002-11-28 13:43:01.000000000 +1100
@@ -1022,33 +1022,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
*/
From: Stephen Rothwell <[email protected]>
Date: Thu, 28 Nov 2002 00:00:26 +1100
This will be allowed for when linux/compat32.h includes asm/compat32.h
at a later stage. asm/compat32.h will be expected to have typedefs for
compat32_<type> (or __kernel_<type>32 whatever) for all the types that
vary between the architectures.
This sounds fine.
From: David Mosberger <[email protected]>
Date: Wed, 27 Nov 2002 09:10:47 -0800
You conveniently cut of the important part of my message:
Remember that most compatibility syscalls go straight to the
64-bit syscall handlers. You're probably hosed anyhow if a
64-bit syscall returns, say, 0x1ffffffff, but on ia64 I'd
still rather play it safe and consistently have all
compatibility syscalls return a 64-bit sign-extended value
like all other syscall handlers ("least surprise" principle).
If the return path is different for the 32-bit syscalls,
which is the point I was talking about, then that code path
can sign extend, truncate, or whatever the upper 32-bits of
the return value.
You need to do things differently in the 32-bit return path anyways.
I didn't miss the content of your email at all David, quite the
opposite in fact.
From: Linus Torvalds <[email protected]>
Date: Wed, 27 Nov 2002 10:51:54 -0800 (PST)
You might as well also discuss just dropping the "32" from "compat32"
while you're at it. As far as I can tell the code and the fundamental
issue has nothing to do with 32-bitness per se.
I'm fine with this.
But having one "compat" could have some unintended side effects. For
example, what if we wanted to make the iBCS2 layer work for x86 apps
on ia64? With one "compat" thing, something like that gets hokey and
ibcs2 will probably end up in it's own tons_of_ibcs2_junk.c file.
With more care, it could be easy to integrate and simpler to maintain.
From: Linus Torvalds <[email protected]>
Date: Wed, 27 Nov 2002 09:18:06 -0800 (PST)
May I just suggest doing a
kernel/compat32.c
and doing most everything there? I think we're better off that way, even
if it means that "do_nanosleep()" etc cannot be static.
Please not this, this will continue the current problem we have
wherein overhauls of things like VFS infrastructure don't propagate to
the compat syscall implementations.
Putting the compat stuff right next to the "normal" version has
several advantages, one of which is that it is kept in sync with
things almost automatically. You have no choice but to notice
it, it's right there.
This isn't a "oh well we have to export some things" issue, it's a
long term maintainence issue. It is the main reason we want to move
this into a common area rather than deep within the arch code.
Hi Dave,
On Wed, 27 Nov 2002 21:26:38 -0800 (PST) "David S. Miller" <[email protected]> wrote:
>
> From: Stephen Rothwell <[email protected]>
> Date: Thu, 28 Nov 2002 16:22:31 +1100
>
> On Wed, 27 Nov 2002 09:18:06 -0800 (PST) Linus Torvalds <[email protected]> wrote:
> > May I just suggest doing a
> >
> > kernel/compat32.c
>
> OK, new version.
>
> Well, actually I disagree with this.
I agree with you. Apply the below patch over my previous one to get
what you like. How do we convince Linus?
Anyone else want to express an opinion ...
> A problem currently, is that when people change VFS stuff up one has
> to pay attention to update all the compat syscall layers as well.
>
> This often simply does not happen because the compat version is
> "somewhere else" is some other file.
>
> Now if we put the stuff next to the non-compat stuff, it likely won't
> get missed.
This, of course, is one of the main reasons to do these consolidations.
The other is so that we don't have the same bugs in all our architectures
and then it takes six months to get them fixed (See SIGURG fix ...)
--
Cheers,
Stephen Rothwell [email protected]
http://www.canb.auug.org.au/~sfr/
diff -ruN 2.5.50-32bit.1/include/linux/compat32.h 2.5.50-32bit.2/include/linux/compat32.h
--- 2.5.50-32bit.1/include/linux/compat32.h 2002-11-29 13:16:25.000000000 +1100
+++ 2.5.50-32bit.2/include/linux/compat32.h 2002-11-29 13:29:44.000000000 +1100
@@ -4,6 +4,10 @@
* These are the type definitions for the 32 compatibility
* layer on 64 bit architectures.
*/
+#include <linux/config.h>
+
+#ifdef CONFIG_COMPAT32
+
#include <linux/types.h>
#include <asm/compat32.h>
@@ -12,4 +16,5 @@
s32 tv_nsec;
};
+#endif /* CONFIG_COMPAT32 */
#endif /* _LINUX_COMPAT32_H */
diff -ruN 2.5.50-32bit.1/include/linux/time.h 2.5.50-32bit.2/include/linux/time.h
--- 2.5.50-32bit.1/include/linux/time.h 2002-11-29 13:16:25.000000000 +1100
+++ 2.5.50-32bit.2/include/linux/time.h 2002-11-29 13:31:11.000000000 +1100
@@ -138,7 +138,6 @@
#ifdef __KERNEL__
extern void do_gettimeofday(struct timeval *tv);
extern void do_settimeofday(struct timeval *tv);
-extern long do_nanosleep(struct timespec *t);
#endif
#define FD_SETSIZE __FD_SETSIZE
diff -ruN 2.5.50-32bit.1/kernel/Makefile 2.5.50-32bit.2/kernel/Makefile
--- 2.5.50-32bit.1/kernel/Makefile 2002-11-29 13:16:25.000000000 +1100
+++ 2.5.50-32bit.2/kernel/Makefile 2002-11-29 13:28:40.000000000 +1100
@@ -21,7 +21,6 @@
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o
-obj-$(CONFIG_COMPAT32) += compat32.o
ifneq ($(CONFIG_IA64),y)
# According to Alan Modra <[email protected]>, the -fno-omit-frame-pointer is
diff -ruN 2.5.50-32bit.1/kernel/compat32.c 2.5.50-32bit.2/kernel/compat32.c
--- 2.5.50-32bit.1/kernel/compat32.c 2002-11-29 13:16:25.000000000 +1100
+++ 2.5.50-32bit.2/kernel/compat32.c 1970-01-01 10:00:00.000000000 +1000
@@ -1,40 +0,0 @@
-/*
- * linux/kernel/compat32.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/compat32.h>
-#include <linux/errno.h>
-#include <linux/time.h>
-
-#include <asm/uaccess.h>
-
-asmlinkage long sys32_nanosleep(struct timespec32 *rqtp,
- struct timespec32 *rmtp)
-{
- struct timespec t;
- struct timespec32 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;
-}
diff -ruN 2.5.50-32bit.1/kernel/timer.c 2.5.50-32bit.2/kernel/timer.c
--- 2.5.50-32bit.1/kernel/timer.c 2002-11-29 13:16:25.000000000 +1100
+++ 2.5.50-32bit.2/kernel/timer.c 2002-11-29 13:28:02.000000000 +1100
@@ -25,6 +25,7 @@
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/notifier.h>
+#include <linux/compat32.h>
#include <asm/uaccess.h>
@@ -1022,7 +1023,7 @@
return current->pid;
}
-long do_nanosleep(struct timespec *t)
+static long do_nanosleep(struct timespec *t)
{
unsigned long expire;
@@ -1057,6 +1058,29 @@
return ret;
}
+#ifndef CONFIG_COMPAT32
+asmlinkage long sys32_nanosleep(struct timespec32 *rqtp,
+ struct timespec32 *rmtp)
+{
+ struct timespec t;
+ struct timespec32 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;
+}
+#endif /* CONFIG_COMPAT32 */
+
/*
* sys_sysinfo - fill in sysinfo struct
*/
Hi Linus,
On Wed, 27 Nov 2002 21:31:48 -0800 (PST) "David S. Miller" <[email protected]> wrote:
>
> From: Linus Torvalds <[email protected]>
> Date: Wed, 27 Nov 2002 09:18:06 -0800 (PST)
>
> May I just suggest doing a
>
> kernel/compat32.c
>
> and doing most everything there? I think we're better off that way, even
> if it means that "do_nanosleep()" etc cannot be static.
>
> Please not this, this will continue the current problem we have
> wherein overhauls of things like VFS infrastructure don't propagate to
> the compat syscall implementations.
Dave is right - I lost the vision for a second there :-)
New version of the patch - davem version.
For those who came in late this patch does:
introduces CONFIG_COMPAT32
introduces linux/compat32.h - which contains only struct timespec32
for now
creates an architecture independent version of sys32_nanosleep
in kernel/timer.c
creates asm-*/compat32.h
creates a typedef for compat32_time_t
uses compat32_time_t in timespec32
renames __kernel_time_t32 to compat32_time_t everywhere
This one has been built on PPC64. (Thanks, Anton)
--
Cheers,
Stephen Rothwell [email protected]
http://www.canb.auug.org.au/~sfr/
diff -ruN 2.5.50/arch/ia64/Kconfig 2.5.50-32bit.1/arch/ia64/Kconfig
--- 2.5.50/arch/ia64/Kconfig 2002-11-28 10:34:41.000000000 +1100
+++ 2.5.50-32bit.1/arch/ia64/Kconfig 2002-11-29 13:16:25.000000000 +1100
@@ -397,6 +397,11 @@
run IA-32 Linux binaries on an IA-64 Linux system.
If in doubt, say Y.
+config COMPAT32
+ bool
+ depends on IA32_SUPPORT
+ default y
+
config PERFMON
bool "Performance monitor support"
help
diff -ruN 2.5.50/arch/ia64/ia32/ia32_signal.c 2.5.50-32bit.1/arch/ia64/ia32/ia32_signal.c
--- 2.5.50/arch/ia64/ia32/ia32_signal.c 2002-10-31 14:05:10.000000000 +1100
+++ 2.5.50-32bit.1/arch/ia64/ia32/ia32_signal.c 2002-11-29 13:16:25.000000000 +1100
@@ -22,6 +22,7 @@
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/wait.h>
+#include <linux/compat32.h>
#include <asm/uaccess.h>
#include <asm/rse.h>
@@ -570,8 +571,8 @@
}
asmlinkage long
-sys32_rt_sigtimedwait (sigset32_t *uthese, siginfo_t32 *uinfo, struct timespec32 *uts,
- unsigned int sigsetsize)
+sys32_rt_sigtimedwait (sigset32_t *uthese, siginfo_t32 *uinfo,
+ struct timespec32 *uts, unsigned int sigsetsize)
{
extern asmlinkage long sys_rt_sigtimedwait (const sigset_t *, siginfo_t *,
const struct timespec *, size_t);
diff -ruN 2.5.50/arch/ia64/ia32/sys_ia32.c 2.5.50-32bit.1/arch/ia64/ia32/sys_ia32.c
--- 2.5.50/arch/ia64/ia32/sys_ia32.c 2002-11-18 15:47:40.000000000 +1100
+++ 2.5.50-32bit.1/arch/ia64/ia32/sys_ia32.c 2002-11-29 13:16:25.000000000 +1100
@@ -49,6 +49,7 @@
#include <linux/ptrace.h>
#include <linux/stat.h>
#include <linux/ipc.h>
+#include <linux/compat32.h>
#include <asm/types.h>
#include <asm/uaccess.h>
@@ -1113,27 +1114,6 @@
(struct timeval32 *) A(a.tvp));
}
-extern asmlinkage long sys_nanosleep (struct timespec *rqtp, struct timespec *rmtp);
-
-asmlinkage long
-sys32_nanosleep (struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
- struct timespec t;
- int ret;
- mm_segment_t old_fs = get_fs();
-
- if (get_user (t.tv_sec, &rqtp->tv_sec) || get_user (t.tv_nsec, &rqtp->tv_nsec))
- return -EFAULT;
- set_fs(KERNEL_DS);
- ret = sys_nanosleep(&t, rmtp ? &t : NULL);
- set_fs(old_fs);
- if (rmtp && ret == -EINTR) {
- if (put_user(t.tv_sec, &rmtp->tv_sec) || put_user(t.tv_nsec, &rmtp->tv_nsec))
- return -EFAULT;
- }
- return ret;
-}
-
struct iovec32 { unsigned int iov_base; int iov_len; };
asmlinkage ssize_t sys_readv (unsigned long,const struct iovec *,unsigned long);
asmlinkage ssize_t sys_writev (unsigned long,const struct iovec *,unsigned long);
@@ -2018,8 +1998,8 @@
struct semid_ds32 {
struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
- __kernel_time_t32 sem_otime; /* last semop time */
- __kernel_time_t32 sem_ctime; /* last change time */
+ compat32_time_t sem_otime; /* last semop time */
+ compat32_time_t sem_ctime; /* last change time */
u32 sem_base; /* ptr to first semaphore in array */
u32 sem_pending; /* pending operations to be processed */
u32 sem_pending_last; /* last pending operation */
@@ -2029,9 +2009,9 @@
struct semid64_ds32 {
struct ipc64_perm32 sem_perm;
- __kernel_time_t32 sem_otime;
+ compat32_time_t sem_otime;
unsigned int __unused1;
- __kernel_time_t32 sem_ctime;
+ compat32_time_t sem_ctime;
unsigned int __unused2;
unsigned int sem_nsems;
unsigned int __unused3;
@@ -2042,9 +2022,9 @@
struct ipc_perm32 msg_perm;
u32 msg_first;
u32 msg_last;
- __kernel_time_t32 msg_stime;
- __kernel_time_t32 msg_rtime;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_stime;
+ compat32_time_t msg_rtime;
+ compat32_time_t msg_ctime;
u32 wwait;
u32 rwait;
unsigned short msg_cbytes;
@@ -2056,11 +2036,11 @@
struct msqid64_ds32 {
struct ipc64_perm32 msg_perm;
- __kernel_time_t32 msg_stime;
+ compat32_time_t msg_stime;
unsigned int __unused1;
- __kernel_time_t32 msg_rtime;
+ compat32_time_t msg_rtime;
unsigned int __unused2;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_ctime;
unsigned int __unused3;
unsigned int msg_cbytes;
unsigned int msg_qnum;
@@ -2074,9 +2054,9 @@
struct shmid_ds32 {
struct ipc_perm32 shm_perm;
int shm_segsz;
- __kernel_time_t32 shm_atime;
- __kernel_time_t32 shm_dtime;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_atime;
+ compat32_time_t shm_dtime;
+ compat32_time_t shm_ctime;
__kernel_ipc_pid_t32 shm_cpid;
__kernel_ipc_pid_t32 shm_lpid;
unsigned short shm_nattch;
@@ -2085,11 +2065,11 @@
struct shmid64_ds32 {
struct ipc64_perm shm_perm;
__kernel_size_t32 shm_segsz;
- __kernel_time_t32 shm_atime;
+ compat32_time_t shm_atime;
unsigned int __unused1;
- __kernel_time_t32 shm_dtime;
+ compat32_time_t shm_dtime;
unsigned int __unused2;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_ctime;
unsigned int __unused3;
__kernel_pid_t32 shm_cpid;
__kernel_pid_t32 shm_lpid;
diff -ruN 2.5.50/arch/mips64/Kconfig 2.5.50-32bit.1/arch/mips64/Kconfig
--- 2.5.50/arch/mips64/Kconfig 2002-11-28 10:35:37.000000000 +1100
+++ 2.5.50-32bit.1/arch/mips64/Kconfig 2002-11-29 13:16:25.000000000 +1100
@@ -371,6 +371,11 @@
compatibility. Since all software available for Linux/MIPS is
currently 32-bit you should say Y here.
+config COMPAT32
+ bool
+ depends on MIPS32_COMPAT
+ default y
+
config BINFMT_ELF32
bool
depends on MIPS32_COMPAT
diff -ruN 2.5.50/arch/mips64/kernel/linux32.c 2.5.50-32bit.1/arch/mips64/kernel/linux32.c
--- 2.5.50/arch/mips64/kernel/linux32.c 2002-10-21 01:02:44.000000000 +1000
+++ 2.5.50-32bit.1/arch/mips64/kernel/linux32.c 2002-11-29 13:16:25.000000000 +1100
@@ -27,6 +27,7 @@
#include <linux/personality.h>
#include <linux/timex.h>
#include <linux/dnotify.h>
+#include <linux/compat32.h>
#include <net/sock.h>
#include <asm/uaccess.h>
@@ -119,7 +120,7 @@
extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
struct utimbuf32 {
- __kernel_time_t32 actime, modtime;
+ compat32_time_t actime, modtime;
};
asmlinkage int sys32_utime(char * filename, struct utimbuf32 *times)
@@ -1205,11 +1206,6 @@
-struct timespec32 {
- int tv_sec;
- int tv_nsec;
-};
-
extern asmlinkage int sys_sched_rr_get_interval(pid_t pid,
struct timespec *interval);
@@ -1230,31 +1226,6 @@
}
-extern asmlinkage int sys_nanosleep(struct timespec *rqtp,
- struct timespec *rmtp);
-
-asmlinkage int
-sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
- struct timespec t;
- int ret;
- mm_segment_t old_fs = get_fs ();
-
- if (get_user (t.tv_sec, &rqtp->tv_sec) ||
- __get_user (t.tv_nsec, &rqtp->tv_nsec))
- return -EFAULT;
-
- set_fs (KERNEL_DS);
- ret = sys_nanosleep(&t, rmtp ? &t : NULL);
- set_fs (old_fs);
- if (rmtp && ret == -EINTR) {
- if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
- __put_user (t.tv_nsec, &rmtp->tv_nsec))
- return -EFAULT;
- }
- return ret;
-}
-
struct tms32 {
int tms_utime;
int tms_stime;
@@ -1418,8 +1389,8 @@
struct semid_ds32 {
struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
- __kernel_time_t32 sem_otime; /* last semop time */
- __kernel_time_t32 sem_ctime; /* last change time */
+ compat32_time_t sem_otime; /* last semop time */
+ compat32_time_t sem_ctime; /* last change time */
u32 sem_base; /* ptr to first semaphore in array */
u32 sem_pending; /* pending operations to be processed */
u32 sem_pending_last; /* last pending operation */
@@ -1432,9 +1403,9 @@
struct ipc_perm32 msg_perm;
u32 msg_first;
u32 msg_last;
- __kernel_time_t32 msg_stime;
- __kernel_time_t32 msg_rtime;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_stime;
+ compat32_time_t msg_rtime;
+ compat32_time_t msg_ctime;
u32 wwait;
u32 rwait;
unsigned short msg_cbytes;
@@ -1447,9 +1418,9 @@
struct shmid_ds32 {
struct ipc_perm32 shm_perm;
int shm_segsz;
- __kernel_time_t32 shm_atime;
- __kernel_time_t32 shm_dtime;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_atime;
+ compat32_time_t shm_dtime;
+ compat32_time_t shm_ctime;
__kernel_ipc_pid_t32 shm_cpid;
__kernel_ipc_pid_t32 shm_lpid;
unsigned short shm_nattch;
diff -ruN 2.5.50/arch/parisc/Kconfig 2.5.50-32bit.1/arch/parisc/Kconfig
--- 2.5.50/arch/parisc/Kconfig 2002-11-18 15:47:40.000000000 +1100
+++ 2.5.50-32bit.1/arch/parisc/Kconfig 2002-11-29 13:16:25.000000000 +1100
@@ -107,6 +107,11 @@
enable this option otherwise. The 64bit kernel is significantly bigger
and slower than the 32bit one.
+config COMPAT32
+ bool
+ depends PARISC64
+ default y
+
config PDC_NARROW
bool "32-bit firmware"
depends on PARISC64
diff -ruN 2.5.50/arch/parisc/kernel/ioctl32.c 2.5.50-32bit.1/arch/parisc/kernel/ioctl32.c
--- 2.5.50/arch/parisc/kernel/ioctl32.c 2002-10-31 14:05:12.000000000 +1100
+++ 2.5.50-32bit.1/arch/parisc/kernel/ioctl32.c 2002-11-29 13:16:25.000000000 +1100
@@ -10,6 +10,7 @@
#include <linux/config.h>
#include <linux/types.h>
+#include <linux/compat32.h>
#include "sys32.h"
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -1060,8 +1061,8 @@
#define PPPIOCSCOMPRESS32 _IOW('t', 77, struct ppp_option_data32)
struct ppp_idle32 {
- __kernel_time_t32 xmit_idle;
- __kernel_time_t32 recv_idle;
+ compat32_time_t xmit_idle;
+ compat32_time_t recv_idle;
};
#define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32)
diff -ruN 2.5.50/arch/parisc/kernel/sys_parisc32.c 2.5.50-32bit.1/arch/parisc/kernel/sys_parisc32.c
--- 2.5.50/arch/parisc/kernel/sys_parisc32.c 2002-11-18 15:47:40.000000000 +1100
+++ 2.5.50-32bit.1/arch/parisc/kernel/sys_parisc32.c 2002-11-29 13:16:25.000000000 +1100
@@ -52,6 +52,7 @@
#include <linux/mman.h>
#include <linux/binfmts.h>
#include <linux/namei.h>
+#include <linux/compat32.h>
#include <asm/types.h>
#include <asm/uaccess.h>
@@ -388,8 +389,8 @@
/* from utime.h */
struct utimbuf32 {
- __kernel_time_t32 actime;
- __kernel_time_t32 modtime;
+ compat32_time_t actime;
+ compat32_time_t modtime;
};
asmlinkage long sys32_utime(char *filename, struct utimbuf32 *times)
@@ -584,11 +585,6 @@
}
#endif /* CONFIG_SYSCTL */
-struct timespec32 {
- s32 tv_sec;
- s32 tv_nsec;
-};
-
static int
put_timespec32(struct timespec32 *u, struct timespec *t)
{
@@ -598,28 +594,6 @@
return copy_to_user(u, &t32, sizeof t32);
}
-asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
- struct timespec t;
- struct timespec32 t32;
- int ret;
- extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
-
- if (copy_from_user(&t32, rqtp, sizeof t32))
- return -EFAULT;
- t.tv_sec = t32.tv_sec;
- t.tv_nsec = t32.tv_nsec;
-
- DBG(("sys32_nanosleep({%d, %d})\n", t32.tv_sec, t32.tv_nsec));
-
- KERNEL_SYSCALL(ret, sys_nanosleep, &t, rmtp ? &t : NULL);
- if (rmtp && ret == -EINTR) {
- if (put_timespec32(rmtp, &t))
- return -EFAULT;
- }
- return ret;
-}
-
asmlinkage long sys32_sched_rr_get_interval(pid_t pid,
struct timespec32 *interval)
{
@@ -633,8 +607,6 @@
return ret;
}
-typedef __kernel_time_t32 time_t32;
-
static int
put_timeval32(struct timeval32 *u, struct timeval *t)
{
@@ -658,10 +630,10 @@
return err;
}
-asmlinkage long sys32_time(time_t32 *tloc)
+asmlinkage long sys32_time(compat32_time_t *tloc)
{
time_t now = get_seconds();
- time_t32 now32 = now;
+ compat32_time_t now32 = now;
if (tloc)
if (put_user(now32, tloc))
@@ -850,11 +822,11 @@
unsigned short st_reserved2; /* old st_gid */
__kernel_dev_t32 st_rdev;
__kernel_off_t32 st_size;
- __kernel_time_t32 st_atime;
+ compat32_time_t st_atime;
unsigned int st_spare1;
- __kernel_time_t32 st_mtime;
+ compat32_time_t st_mtime;
unsigned int st_spare2;
- __kernel_time_t32 st_ctime;
+ compat32_time_t st_ctime;
unsigned int st_spare3;
int st_blksize;
int st_blocks;
@@ -2903,8 +2875,8 @@
__u32 dqb_ihardlimit;
__u32 dqb_isoftlimit;
__u32 dqb_curinodes;
- __kernel_time_t32 dqb_btime;
- __kernel_time_t32 dqb_itime;
+ compat32_time_t dqb_btime;
+ compat32_time_t dqb_itime;
};
diff -ruN 2.5.50/arch/ppc64/Kconfig 2.5.50-32bit.1/arch/ppc64/Kconfig
--- 2.5.50/arch/ppc64/Kconfig 2002-11-18 15:47:40.000000000 +1100
+++ 2.5.50-32bit.1/arch/ppc64/Kconfig 2002-11-29 13:16:25.000000000 +1100
@@ -33,6 +33,10 @@
bool
default y
+config COMPAT32
+ bool
+ default y
+
source "init/Kconfig"
diff -ruN 2.5.50/arch/ppc64/kernel/ioctl32.c 2.5.50-32bit.1/arch/ppc64/kernel/ioctl32.c
--- 2.5.50/arch/ppc64/kernel/ioctl32.c 2002-11-11 14:55:28.000000000 +1100
+++ 2.5.50-32bit.1/arch/ppc64/kernel/ioctl32.c 2002-11-29 13:16:25.000000000 +1100
@@ -22,6 +22,7 @@
#include <linux/config.h>
#include <linux/types.h>
+#include <linux/compat32.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/smp.h>
@@ -1424,8 +1425,8 @@
#define PPPIOCSCOMPRESS32 _IOW('t', 77, struct ppp_option_data32)
struct ppp_idle32 {
- __kernel_time_t32 xmit_idle;
- __kernel_time_t32 recv_idle;
+ compat32_time_t xmit_idle;
+ compat32_time_t recv_idle;
};
#define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32)
diff -ruN 2.5.50/arch/ppc64/kernel/signal32.c 2.5.50-32bit.1/arch/ppc64/kernel/signal32.c
--- 2.5.50/arch/ppc64/kernel/signal32.c 2002-10-21 01:02:45.000000000 +1000
+++ 2.5.50-32bit.1/arch/ppc64/kernel/signal32.c 2002-11-29 13:16:25.000000000 +1100
@@ -22,6 +22,7 @@
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/elf.h>
+#include <linux/compat32.h>
#include <asm/ppc32.h>
#include <asm/uaccess.h>
#include <asm/ppcdebug.h>
@@ -53,11 +54,6 @@
#define MSR_USERCHANGE 0
#endif
-struct timespec32 {
- s32 tv_sec;
- s32 tv_nsec;
-};
-
struct sigregs32 {
/*
* the gp_regs array is 32 bit representation of the pt_regs
diff -ruN 2.5.50/arch/ppc64/kernel/sys_ppc32.c 2.5.50-32bit.1/arch/ppc64/kernel/sys_ppc32.c
--- 2.5.50/arch/ppc64/kernel/sys_ppc32.c 2002-11-28 10:35:37.000000000 +1100
+++ 2.5.50-32bit.1/arch/ppc64/kernel/sys_ppc32.c 2002-11-29 13:16:25.000000000 +1100
@@ -54,6 +54,7 @@
#include <linux/sysctl.h>
#include <linux/binfmts.h>
#include <linux/security.h>
+#include <linux/compat32.h>
#include <asm/types.h>
#include <asm/ipc.h>
@@ -72,7 +73,7 @@
extern asmlinkage long sys_utime(char * filename, struct utimbuf * times);
struct utimbuf32 {
- __kernel_time_t32 actime, modtime;
+ compat32_time_t actime, modtime;
};
asmlinkage long sys32_utime(char * filename, struct utimbuf32 *times)
@@ -1775,37 +1776,6 @@
-struct timespec32 {
- s32 tv_sec;
- s32 tv_nsec;
-};
-
-extern asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
-
-asmlinkage long sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
- struct timespec t;
- int ret;
- mm_segment_t old_fs = get_fs ();
-
- if (get_user (t.tv_sec, &rqtp->tv_sec) ||
- __get_user (t.tv_nsec, &rqtp->tv_nsec))
- return -EFAULT;
- set_fs (KERNEL_DS);
- ret = sys_nanosleep(&t, rmtp ? &t : NULL);
- set_fs (old_fs);
- if (rmtp && ret == -EINTR) {
- if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
- __put_user (t.tv_nsec, &rmtp->tv_nsec))
- return -EFAULT;
- }
-
- return ret;
-}
-
-
-
-
/* These are here just in case some old sparc32 binary calls it. */
asmlinkage long sys32_pause(void)
{
@@ -2163,8 +2133,8 @@
struct semid_ds32 {
struct ipc_perm sem_perm;
- __kernel_time_t32 sem_otime;
- __kernel_time_t32 sem_ctime;
+ compat32_time_t sem_otime;
+ compat32_time_t sem_ctime;
u32 sem_base;
u32 sem_pending;
u32 sem_pending_last;
@@ -2175,9 +2145,9 @@
struct semid64_ds32 {
struct ipc64_perm sem_perm;
unsigned int __unused1;
- __kernel_time_t32 sem_otime;
+ compat32_time_t sem_otime;
unsigned int __unused2;
- __kernel_time_t32 sem_ctime;
+ compat32_time_t sem_ctime;
u32 sem_nsems;
u32 __unused3;
u32 __unused4;
@@ -2188,9 +2158,9 @@
struct ipc_perm msg_perm;
u32 msg_first;
u32 msg_last;
- __kernel_time_t32 msg_stime;
- __kernel_time_t32 msg_rtime;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_stime;
+ compat32_time_t msg_rtime;
+ compat32_time_t msg_ctime;
u32 msg_lcbytes;
u32 msg_lqbytes;
unsigned short msg_cbytes;
@@ -2203,11 +2173,11 @@
struct msqid64_ds32 {
struct ipc64_perm msg_perm;
unsigned int __unused1;
- __kernel_time_t32 msg_stime;
+ compat32_time_t msg_stime;
unsigned int __unused2;
- __kernel_time_t32 msg_rtime;
+ compat32_time_t msg_rtime;
unsigned int __unused3;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_ctime;
unsigned int msg_cbytes;
unsigned int msg_qnum;
unsigned int msg_qbytes;
@@ -2220,9 +2190,9 @@
struct shmid_ds32 {
struct ipc_perm shm_perm;
int shm_segsz;
- __kernel_time_t32 shm_atime;
- __kernel_time_t32 shm_dtime;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_atime;
+ compat32_time_t shm_dtime;
+ compat32_time_t shm_ctime;
__kernel_ipc_pid_t32 shm_cpid;
__kernel_ipc_pid_t32 shm_lpid;
unsigned short shm_nattch;
@@ -2234,11 +2204,11 @@
struct shmid64_ds32 {
struct ipc64_perm shm_perm;
unsigned int __unused1;
- __kernel_time_t32 shm_atime;
+ compat32_time_t shm_atime;
unsigned int __unused2;
- __kernel_time_t32 shm_dtime;
+ compat32_time_t shm_dtime;
unsigned int __unused3;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_ctime;
unsigned int __unused4;
__kernel_size_t32 shm_segsz;
__kernel_pid_t32 shm_cpid;
@@ -3259,12 +3229,12 @@
* from 64-bit time values to 32-bit time values
*/
case SO_TIMESTAMP: {
- __kernel_time_t32* ptr_time32 = CMSG32_DATA(kcmsg32);
+ compat32_time_t* ptr_time32 = CMSG32_DATA(kcmsg32);
__kernel_time_t* ptr_time = CMSG_DATA(ucmsg);
*ptr_time32 = *ptr_time;
*(ptr_time32+1) = *(ptr_time+1);
kcmsg32->cmsg_len -= 2*(sizeof(__kernel_time_t) -
- sizeof(__kernel_time_t32));
+ sizeof(compat32_time_t));
}
default:;
}
@@ -4234,9 +4204,9 @@
return error;
}
-asmlinkage long sys32_time(__kernel_time_t32* tloc)
+asmlinkage long sys32_time(compat32_time_t* tloc)
{
- __kernel_time_t32 secs;
+ compat32_time_t secs;
struct timeval tv;
diff -ruN 2.5.50/arch/s390x/Kconfig 2.5.50-32bit.1/arch/s390x/Kconfig
--- 2.5.50/arch/s390x/Kconfig 2002-11-28 10:34:42.000000000 +1100
+++ 2.5.50-32bit.1/arch/s390x/Kconfig 2002-11-29 13:16:25.000000000 +1100
@@ -92,6 +92,11 @@
(and some other stuff like libraries and such) is needed for
executing 31 bit applications. It is safe to say "Y".
+config COMPAT32
+ bool
+ depends on S390_SUPPORT
+ default y
+
config BINFMT_ELF32
tristate "Kernel support for 31 bit ELF binaries"
depends on S390_SUPPORT
diff -ruN 2.5.50/arch/s390x/kernel/linux32.c 2.5.50-32bit.1/arch/s390x/kernel/linux32.c
--- 2.5.50/arch/s390x/kernel/linux32.c 2002-11-28 10:34:42.000000000 +1100
+++ 2.5.50-32bit.1/arch/s390x/kernel/linux32.c 2002-11-29 13:16:25.000000000 +1100
@@ -57,6 +57,7 @@
#include <linux/icmpv6.h>
#include <linux/sysctl.h>
#include <linux/binfmts.h>
+#include <linux/compat32.h>
#include <asm/types.h>
#include <asm/ipc.h>
@@ -318,8 +319,8 @@
struct semid_ds32 {
struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
- __kernel_time_t32 sem_otime; /* last semop time */
- __kernel_time_t32 sem_ctime; /* last change time */
+ compat32_time_t sem_otime; /* last semop time */
+ compat32_time_t sem_ctime; /* last change time */
u32 sem_base; /* ptr to first semaphore in array */
u32 sem_pending; /* pending operations to be processed */
u32 sem_pending_last; /* last pending operation */
@@ -330,9 +331,9 @@
struct semid64_ds32 {
struct ipc64_perm_ds32 sem_perm;
unsigned int __pad1;
- __kernel_time_t32 sem_otime;
+ compat32_time_t sem_otime;
unsigned int __pad2;
- __kernel_time_t32 sem_ctime;
+ compat32_time_t sem_ctime;
u32 sem_nsems;
u32 __unused1;
u32 __unused2;
@@ -343,9 +344,9 @@
struct ipc_perm32 msg_perm;
u32 msg_first;
u32 msg_last;
- __kernel_time_t32 msg_stime;
- __kernel_time_t32 msg_rtime;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_stime;
+ compat32_time_t msg_rtime;
+ compat32_time_t msg_ctime;
u32 wwait;
u32 rwait;
unsigned short msg_cbytes;
@@ -358,11 +359,11 @@
struct msqid64_ds32 {
struct ipc64_perm_ds32 msg_perm;
unsigned int __pad1;
- __kernel_time_t32 msg_stime;
+ compat32_time_t msg_stime;
unsigned int __pad2;
- __kernel_time_t32 msg_rtime;
+ compat32_time_t msg_rtime;
unsigned int __pad3;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_ctime;
unsigned int msg_cbytes;
unsigned int msg_qnum;
unsigned int msg_qbytes;
@@ -376,9 +377,9 @@
struct shmid_ds32 {
struct ipc_perm32 shm_perm;
int shm_segsz;
- __kernel_time_t32 shm_atime;
- __kernel_time_t32 shm_dtime;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_atime;
+ compat32_time_t shm_dtime;
+ compat32_time_t shm_ctime;
__kernel_ipc_pid_t32 shm_cpid;
__kernel_ipc_pid_t32 shm_lpid;
unsigned short shm_nattch;
@@ -387,11 +388,11 @@
struct shmid64_ds32 {
struct ipc64_perm_ds32 shm_perm;
__kernel_size_t32 shm_segsz;
- __kernel_time_t32 shm_atime;
+ compat32_time_t shm_atime;
unsigned int __unused1;
- __kernel_time_t32 shm_dtime;
+ compat32_time_t shm_dtime;
unsigned int __unused2;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_ctime;
unsigned int __unused3;
__kernel_pid_t32 shm_cpid;
__kernel_pid_t32 shm_lpid;
@@ -1013,7 +1014,7 @@
extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
struct utimbuf32 {
- __kernel_time_t32 actime, modtime;
+ compat32_time_t actime, modtime;
};
asmlinkage int sys32_utime(char * filename, struct utimbuf32 *times)
@@ -1774,11 +1775,6 @@
return ret;
}
-struct timespec32 {
- s32 tv_sec;
- s32 tv_nsec;
-};
-
extern asmlinkage int sys_sched_rr_get_interval(pid_t pid, struct timespec *interval);
asmlinkage int sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
@@ -1796,28 +1792,6 @@
return ret;
}
-extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
-
-asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
- struct timespec t;
- int ret;
- mm_segment_t old_fs = get_fs ();
-
- if (get_user (t.tv_sec, &rqtp->tv_sec) ||
- __get_user (t.tv_nsec, &rqtp->tv_nsec))
- return -EFAULT;
- set_fs (KERNEL_DS);
- ret = sys_nanosleep(&t, rmtp ? &t : NULL);
- set_fs (old_fs);
- if (rmtp && ret == -EINTR) {
- if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
- __put_user (t.tv_nsec, &rmtp->tv_nsec))
- return -EFAULT;
- }
- return ret;
-}
-
extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset);
asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset)
@@ -2498,12 +2472,12 @@
* from 64-bit time values to 32-bit time values
*/
case SO_TIMESTAMP: {
- __kernel_time_t32* ptr_time32 = CMSG32_DATA(kcmsg32);
+ compat32_time_t* ptr_time32 = CMSG32_DATA(kcmsg32);
__kernel_time_t* ptr_time = CMSG_DATA(ucmsg);
get_user(*ptr_time32, ptr_time);
get_user(*(ptr_time32+1), ptr_time+1);
kcmsg32->cmsg_len -= 2*(sizeof(__kernel_time_t) -
- sizeof(__kernel_time_t32));
+ sizeof(compat32_time_t));
}
default:;
}
diff -ruN 2.5.50/arch/s390x/kernel/linux32.h 2.5.50-32bit.1/arch/s390x/kernel/linux32.h
--- 2.5.50/arch/s390x/kernel/linux32.h 2002-10-08 12:02:40.000000000 +1000
+++ 2.5.50-32bit.1/arch/s390x/kernel/linux32.h 2002-11-29 13:16:25.000000000 +1100
@@ -18,7 +18,6 @@
typedef unsigned int __kernel_size_t32;
typedef int __kernel_ssize_t32;
typedef int __kernel_ptrdiff_t32;
-typedef int __kernel_time_t32;
typedef int __kernel_clock_t32;
typedef int __kernel_pid_t32;
typedef unsigned short __kernel_ipc_pid_t32;
diff -ruN 2.5.50/arch/s390x/kernel/wrapper32.S 2.5.50-32bit.1/arch/s390x/kernel/wrapper32.S
--- 2.5.50/arch/s390x/kernel/wrapper32.S 2002-11-28 10:34:42.000000000 +1100
+++ 2.5.50-32bit.1/arch/s390x/kernel/wrapper32.S 2002-11-29 13:16:25.000000000 +1100
@@ -748,8 +748,8 @@
.globl sys32_nanosleep_wrapper
sys32_nanosleep_wrapper:
- llgtr %r2,%r2 # struct timespec_emu31 *
- llgtr %r3,%r3 # struct timespec_emu31 *
+ llgtr %r2,%r2 # struct timespec32 *
+ llgtr %r3,%r3 # struct timespec32 *
jg sys32_nanosleep # branch to system call
.globl sys32_mremap_wrapper
diff -ruN 2.5.50/arch/sparc64/Kconfig 2.5.50-32bit.1/arch/sparc64/Kconfig
--- 2.5.50/arch/sparc64/Kconfig 2002-11-28 10:35:37.000000000 +1100
+++ 2.5.50-32bit.1/arch/sparc64/Kconfig 2002-11-29 13:16:25.000000000 +1100
@@ -352,6 +352,11 @@
This allows you to run 32-bit binaries on your Ultra.
Everybody wants this; say Y.
+config COMPAT32
+ bool
+ depends on SPARC32_COMPAT
+ default y
+
config BINFMT_ELF32
tristate "Kernel support for 32-bit ELF binaries"
depends on SPARC32_COMPAT
diff -ruN 2.5.50/arch/sparc64/kernel/ioctl32.c 2.5.50-32bit.1/arch/sparc64/kernel/ioctl32.c
--- 2.5.50/arch/sparc64/kernel/ioctl32.c 2002-11-18 15:47:41.000000000 +1100
+++ 2.5.50-32bit.1/arch/sparc64/kernel/ioctl32.c 2002-11-29 13:16:25.000000000 +1100
@@ -10,6 +10,7 @@
#include <linux/config.h>
#include <linux/types.h>
+#include <linux/compat32.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/smp.h>
@@ -1743,8 +1744,8 @@
#define PPPIOCSCOMPRESS32 _IOW('t', 77, struct ppp_option_data32)
struct ppp_idle32 {
- __kernel_time_t32 xmit_idle;
- __kernel_time_t32 recv_idle;
+ compat32_time_t xmit_idle;
+ compat32_time_t recv_idle;
};
#define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32)
diff -ruN 2.5.50/arch/sparc64/kernel/sys_sparc32.c 2.5.50-32bit.1/arch/sparc64/kernel/sys_sparc32.c
--- 2.5.50/arch/sparc64/kernel/sys_sparc32.c 2002-11-28 10:35:37.000000000 +1100
+++ 2.5.50-32bit.1/arch/sparc64/kernel/sys_sparc32.c 2002-11-29 13:16:25.000000000 +1100
@@ -51,6 +51,7 @@
#include <linux/sysctl.h>
#include <linux/binfmts.h>
#include <linux/dnotify.h>
+#include <linux/compat32.h>
#include <asm/types.h>
#include <asm/ipc.h>
@@ -327,8 +328,8 @@
struct semid_ds32 {
struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
- __kernel_time_t32 sem_otime; /* last semop time */
- __kernel_time_t32 sem_ctime; /* last change time */
+ compat32_time_t sem_otime; /* last semop time */
+ compat32_time_t sem_ctime; /* last change time */
u32 sem_base; /* ptr to first semaphore in array */
u32 sem_pending; /* pending operations to be processed */
u32 sem_pending_last; /* last pending operation */
@@ -339,9 +340,9 @@
struct semid64_ds32 {
struct ipc64_perm sem_perm; /* this structure is the same on sparc32 and sparc64 */
unsigned int __pad1;
- __kernel_time_t32 sem_otime;
+ compat32_time_t sem_otime;
unsigned int __pad2;
- __kernel_time_t32 sem_ctime;
+ compat32_time_t sem_ctime;
u32 sem_nsems;
u32 __unused1;
u32 __unused2;
@@ -352,9 +353,9 @@
struct ipc_perm32 msg_perm;
u32 msg_first;
u32 msg_last;
- __kernel_time_t32 msg_stime;
- __kernel_time_t32 msg_rtime;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_stime;
+ compat32_time_t msg_rtime;
+ compat32_time_t msg_ctime;
u32 wwait;
u32 rwait;
unsigned short msg_cbytes;
@@ -367,11 +368,11 @@
struct msqid64_ds32 {
struct ipc64_perm msg_perm;
unsigned int __pad1;
- __kernel_time_t32 msg_stime;
+ compat32_time_t msg_stime;
unsigned int __pad2;
- __kernel_time_t32 msg_rtime;
+ compat32_time_t msg_rtime;
unsigned int __pad3;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_ctime;
unsigned int msg_cbytes;
unsigned int msg_qnum;
unsigned int msg_qbytes;
@@ -385,9 +386,9 @@
struct shmid_ds32 {
struct ipc_perm32 shm_perm;
int shm_segsz;
- __kernel_time_t32 shm_atime;
- __kernel_time_t32 shm_dtime;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_atime;
+ compat32_time_t shm_dtime;
+ compat32_time_t shm_ctime;
__kernel_ipc_pid_t32 shm_cpid;
__kernel_ipc_pid_t32 shm_lpid;
unsigned short shm_nattch;
@@ -396,11 +397,11 @@
struct shmid64_ds32 {
struct ipc64_perm shm_perm;
unsigned int __pad1;
- __kernel_time_t32 shm_atime;
+ compat32_time_t shm_atime;
unsigned int __pad2;
- __kernel_time_t32 shm_dtime;
+ compat32_time_t shm_dtime;
unsigned int __pad3;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_ctime;
__kernel_size_t32 shm_segsz;
__kernel_pid_t32 shm_cpid;
__kernel_pid_t32 shm_lpid;
@@ -967,7 +968,7 @@
extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
struct utimbuf32 {
- __kernel_time_t32 actime, modtime;
+ compat32_time_t actime, modtime;
};
asmlinkage int sys32_utime(char * filename, struct utimbuf32 *times)
@@ -1794,11 +1795,6 @@
return ret;
}
-struct timespec32 {
- s32 tv_sec;
- s32 tv_nsec;
-};
-
extern asmlinkage int sys_sched_rr_get_interval(pid_t pid, struct timespec *interval);
asmlinkage int sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
@@ -1816,28 +1812,6 @@
return ret;
}
-extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
-
-asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
- struct timespec t;
- int ret;
- mm_segment_t old_fs = get_fs ();
-
- if (get_user (t.tv_sec, &rqtp->tv_sec) ||
- __get_user (t.tv_nsec, &rqtp->tv_nsec))
- return -EFAULT;
- set_fs (KERNEL_DS);
- ret = sys_nanosleep(&t, rmtp ? &t : NULL);
- set_fs (old_fs);
- if (rmtp && ret == -EINTR) {
- if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
- __put_user (t.tv_nsec, &rmtp->tv_nsec))
- return -EFAULT;
- }
- return ret;
-}
-
extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset);
asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset)
diff -ruN 2.5.50/arch/sparc64/kernel/sys_sunos32.c 2.5.50-32bit.1/arch/sparc64/kernel/sys_sunos32.c
--- 2.5.50/arch/sparc64/kernel/sys_sunos32.c 2002-11-28 10:34:43.000000000 +1100
+++ 2.5.50-32bit.1/arch/sparc64/kernel/sys_sunos32.c 2002-11-29 13:16:25.000000000 +1100
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
+#include <linux/compat32.h>
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/swap.h>
@@ -948,9 +949,9 @@
struct ipc_perm32 msg_perm;
u32 msg_first;
u32 msg_last;
- __kernel_time_t32 msg_stime;
- __kernel_time_t32 msg_rtime;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_stime;
+ compat32_time_t msg_rtime;
+ compat32_time_t msg_ctime;
u32 wwait;
u32 rwait;
unsigned short msg_cbytes;
@@ -1085,9 +1086,9 @@
struct shmid_ds32 {
struct ipc_perm32 shm_perm;
int shm_segsz;
- __kernel_time_t32 shm_atime;
- __kernel_time_t32 shm_dtime;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_atime;
+ compat32_time_t shm_dtime;
+ compat32_time_t shm_ctime;
__kernel_ipc_pid_t32 shm_cpid;
__kernel_ipc_pid_t32 shm_lpid;
unsigned short shm_nattch;
diff -ruN 2.5.50/arch/x86_64/Kconfig 2.5.50-32bit.1/arch/x86_64/Kconfig
--- 2.5.50/arch/x86_64/Kconfig 2002-11-28 10:34:43.000000000 +1100
+++ 2.5.50-32bit.1/arch/x86_64/Kconfig 2002-11-29 13:16:25.000000000 +1100
@@ -425,6 +425,11 @@
turn this on, unless you're 100% sure that you don't have any 32bit programs
left.
+config COMPAT32
+ bool
+ depends on IA32_EMULATION
+ default y
+
endmenu
source "drivers/mtd/Kconfig"
diff -ruN 2.5.50/arch/x86_64/ia32/ia32_ioctl.c 2.5.50-32bit.1/arch/x86_64/ia32/ia32_ioctl.c
--- 2.5.50/arch/x86_64/ia32/ia32_ioctl.c 2002-10-21 01:02:47.000000000 +1000
+++ 2.5.50-32bit.1/arch/x86_64/ia32/ia32_ioctl.c 2002-11-29 13:16:25.000000000 +1100
@@ -11,6 +11,7 @@
#include <linux/config.h>
#include <linux/types.h>
+#include <linux/compat32.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/smp.h>
@@ -1611,8 +1612,8 @@
#define PPPIOCSCOMPRESS32 _IOW('t', 77, struct ppp_option_data32)
struct ppp_idle32 {
- __kernel_time_t32 xmit_idle;
- __kernel_time_t32 recv_idle;
+ compat32_time_t xmit_idle;
+ compat32_time_t recv_idle;
};
#define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32)
diff -ruN 2.5.50/arch/x86_64/ia32/ipc32.c 2.5.50-32bit.1/arch/x86_64/ia32/ipc32.c
--- 2.5.50/arch/x86_64/ia32/ipc32.c 2002-10-21 01:02:47.000000000 +1000
+++ 2.5.50-32bit.1/arch/x86_64/ia32/ipc32.c 2002-11-29 13:16:25.000000000 +1100
@@ -8,6 +8,7 @@
#include <linux/shm.h>
#include <linux/slab.h>
#include <linux/ipc.h>
+#include <linux/compat32.h>
#include <asm/mman.h>
#include <asm/types.h>
#include <asm/uaccess.h>
@@ -53,8 +54,8 @@
struct semid_ds32 {
struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
- __kernel_time_t32 sem_otime; /* last semop time */
- __kernel_time_t32 sem_ctime; /* last change time */
+ compat32_time_t sem_otime; /* last semop time */
+ compat32_time_t sem_ctime; /* last change time */
u32 sem_base; /* ptr to first semaphore in array */
u32 sem_pending; /* pending operations to be processed */
u32 sem_pending_last; /* last pending operation */
@@ -64,9 +65,9 @@
struct semid64_ds32 {
struct ipc64_perm32 sem_perm;
- __kernel_time_t32 sem_otime;
+ compat32_time_t sem_otime;
unsigned int __unused1;
- __kernel_time_t32 sem_ctime;
+ compat32_time_t sem_ctime;
unsigned int __unused2;
unsigned int sem_nsems;
unsigned int __unused3;
@@ -77,9 +78,9 @@
struct ipc_perm32 msg_perm;
u32 msg_first;
u32 msg_last;
- __kernel_time_t32 msg_stime;
- __kernel_time_t32 msg_rtime;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_stime;
+ compat32_time_t msg_rtime;
+ compat32_time_t msg_ctime;
u32 wwait;
u32 rwait;
unsigned short msg_cbytes;
@@ -91,11 +92,11 @@
struct msqid64_ds32 {
struct ipc64_perm32 msg_perm;
- __kernel_time_t32 msg_stime;
+ compat32_time_t msg_stime;
unsigned int __unused1;
- __kernel_time_t32 msg_rtime;
+ compat32_time_t msg_rtime;
unsigned int __unused2;
- __kernel_time_t32 msg_ctime;
+ compat32_time_t msg_ctime;
unsigned int __unused3;
unsigned int msg_cbytes;
unsigned int msg_qnum;
@@ -109,9 +110,9 @@
struct shmid_ds32 {
struct ipc_perm32 shm_perm;
int shm_segsz;
- __kernel_time_t32 shm_atime;
- __kernel_time_t32 shm_dtime;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_atime;
+ compat32_time_t shm_dtime;
+ compat32_time_t shm_ctime;
__kernel_ipc_pid_t32 shm_cpid;
__kernel_ipc_pid_t32 shm_lpid;
unsigned short shm_nattch;
@@ -120,11 +121,11 @@
struct shmid64_ds32 {
struct ipc64_perm32 shm_perm;
__kernel_size_t32 shm_segsz;
- __kernel_time_t32 shm_atime;
+ compat32_time_t shm_atime;
unsigned int __unused1;
- __kernel_time_t32 shm_dtime;
+ compat32_time_t shm_dtime;
unsigned int __unused2;
- __kernel_time_t32 shm_ctime;
+ compat32_time_t shm_ctime;
unsigned int __unused3;
__kernel_pid_t32 shm_cpid;
__kernel_pid_t32 shm_lpid;
diff -ruN 2.5.50/arch/x86_64/ia32/sys_ia32.c 2.5.50-32bit.1/arch/x86_64/ia32/sys_ia32.c
--- 2.5.50/arch/x86_64/ia32/sys_ia32.c 2002-11-18 15:47:41.000000000 +1100
+++ 2.5.50-32bit.1/arch/x86_64/ia32/sys_ia32.c 2002-11-29 13:16:25.000000000 +1100
@@ -58,6 +58,7 @@
#include <linux/binfmts.h>
#include <linux/init.h>
#include <linux/aio_abi.h>
+#include <linux/compat32.h>
#include <asm/mman.h>
#include <asm/types.h>
#include <asm/uaccess.h>
@@ -934,36 +935,6 @@
(struct timeval32 *)A(a.tvp));
}
-struct timespec32 {
- int tv_sec;
- int tv_nsec;
-};
-
-extern asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
-
-asmlinkage long
-sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
- struct timespec t;
- int ret;
- mm_segment_t old_fs = get_fs ();
-
- if (verify_area(VERIFY_READ, rqtp, sizeof(struct timespec32)) ||
- __get_user (t.tv_sec, &rqtp->tv_sec) ||
- __get_user (t.tv_nsec, &rqtp->tv_nsec))
- return -EFAULT;
- set_fs (KERNEL_DS);
- ret = sys_nanosleep(&t, rmtp ? &t : NULL);
- set_fs (old_fs);
- if (rmtp && ret == -EINTR) {
- if (verify_area(VERIFY_WRITE, rmtp, sizeof(struct timespec32)) ||
- __put_user (t.tv_sec, &rmtp->tv_sec) ||
- __put_user (t.tv_nsec, &rmtp->tv_nsec))
- return -EFAULT;
- }
- return ret;
-}
-
asmlinkage ssize_t sys_readv(unsigned long,const struct iovec *,unsigned long);
asmlinkage ssize_t sys_writev(unsigned long,const struct iovec *,unsigned long);
@@ -1409,7 +1380,7 @@
extern asmlinkage long sys_utime(char * filename, struct utimbuf * times);
struct utimbuf32 {
- __kernel_time_t32 actime, modtime;
+ compat32_time_t actime, modtime;
};
asmlinkage long
diff -ruN 2.5.50/include/asm-ia64/compat32.h 2.5.50-32bit.1/include/asm-ia64/compat32.h
--- 2.5.50/include/asm-ia64/compat32.h 1970-01-01 10:00:00.000000000 +1000
+++ 2.5.50-32bit.1/include/asm-ia64/compat32.h 2002-11-29 13:16:25.000000000 +1100
@@ -0,0 +1,9 @@
+#ifndef _ASM_IA64_COMPAT32_H
+#define _ASM_IA64_COMPAT32_H
+/*
+ * Architecture specific 32 bit compatibility types
+ */
+
+typedef s32 compat32_time_t;
+
+#endif /* _ASM_IA64_COMPAT32_H */
diff -ruN 2.5.50/include/asm-ia64/ia32.h 2.5.50-32bit.1/include/asm-ia64/ia32.h
--- 2.5.50/include/asm-ia64/ia32.h 2002-10-31 14:06:05.000000000 +1100
+++ 2.5.50-32bit.1/include/asm-ia64/ia32.h 2002-11-29 13:16:25.000000000 +1100
@@ -15,7 +15,6 @@
typedef unsigned int __kernel_size_t32;
typedef int __kernel_ssize_t32;
typedef int __kernel_ptrdiff_t32;
-typedef int __kernel_time_t32;
typedef int __kernel_clock_t32;
typedef int __kernel_pid_t32;
typedef unsigned short __kernel_ipc_pid_t32;
@@ -41,11 +40,6 @@
#define IA32_CLOCKS_PER_SEC 100 /* Cast in stone for IA32 Linux */
#define IA32_TICK(tick) ((unsigned long long)(tick) * IA32_CLOCKS_PER_SEC / CLOCKS_PER_SEC)
-struct timespec32 {
- int tv_sec;
- int tv_nsec;
-};
-
/* fcntl.h */
struct flock32 {
short l_type;
diff -ruN 2.5.50/include/asm-mips64/compat32.h 2.5.50-32bit.1/include/asm-mips64/compat32.h
--- 2.5.50/include/asm-mips64/compat32.h 1970-01-01 10:00:00.000000000 +1000
+++ 2.5.50-32bit.1/include/asm-mips64/compat32.h 2002-11-29 13:16:25.000000000 +1100
@@ -0,0 +1,9 @@
+#ifndef _ASM_MIPS64_COMPAT32_H
+#define _ASM_MIPS64_COMPAT32_H
+/*
+ * Architecture specific 32 bit compatibility types
+ */
+
+typedef s32 compat32_time_t;
+
+#endif /* _ASM_MIPS64_COMPAT32_H */
diff -ruN 2.5.50/include/asm-mips64/posix_types.h 2.5.50-32bit.1/include/asm-mips64/posix_types.h
--- 2.5.50/include/asm-mips64/posix_types.h 2000-07-10 15:18:15.000000000 +1000
+++ 2.5.50-32bit.1/include/asm-mips64/posix_types.h 2002-11-29 13:16:25.000000000 +1100
@@ -61,7 +61,6 @@
typedef unsigned int __kernel_size_t32;
typedef int __kernel_ssize_t32;
typedef int __kernel_ptrdiff_t32;
-typedef int __kernel_time_t32;
typedef int __kernel_suseconds_t32;
typedef int __kernel_clock_t32;
typedef int __kernel_daddr_t32;
diff -ruN 2.5.50/include/asm-mips64/stat.h 2.5.50-32bit.1/include/asm-mips64/stat.h
--- 2.5.50/include/asm-mips64/stat.h 2002-11-18 15:47:55.000000000 +1100
+++ 2.5.50-32bit.1/include/asm-mips64/stat.h 2002-11-29 13:16:25.000000000 +1100
@@ -10,6 +10,7 @@
#define _ASM_STAT_H
#include <linux/types.h>
+#include <linux/compat32.h>
struct __old_kernel_stat {
unsigned int st_dev;
@@ -40,11 +41,11 @@
int st_pad2[2];
__kernel_off_t32 st_size;
int st_pad3;
- __kernel_time_t32 st_atime;
+ compat32_time_t st_atime;
int reserved0;
- __kernel_time_t32 st_mtime;
+ compat32_time_t st_mtime;
int reserved1;
- __kernel_time_t32 st_ctime;
+ compat32_time_t st_ctime;
int reserved2;
int st_blksize;
int st_blocks;
diff -ruN 2.5.50/include/asm-parisc/compat32.h 2.5.50-32bit.1/include/asm-parisc/compat32.h
--- 2.5.50/include/asm-parisc/compat32.h 1970-01-01 10:00:00.000000000 +1000
+++ 2.5.50-32bit.1/include/asm-parisc/compat32.h 2002-11-29 13:16:25.000000000 +1100
@@ -0,0 +1,9 @@
+#ifndef _ASM_PARISC_COMPAT32_H
+#define _ASM_PARISC_COMPAT32_H
+/*
+ * Architecture specific 32 bit compatibility types
+ */
+
+typedef s32 compat32_time_t;
+
+#endif /* _ASM_PARISC_COMPAT32_H */
diff -ruN 2.5.50/include/asm-parisc/posix_types.h 2.5.50-32bit.1/include/asm-parisc/posix_types.h
--- 2.5.50/include/asm-parisc/posix_types.h 2002-10-31 14:06:07.000000000 +1100
+++ 2.5.50-32bit.1/include/asm-parisc/posix_types.h 2002-11-29 13:16:25.000000000 +1100
@@ -69,7 +69,6 @@
typedef unsigned int __kernel_size_t32;
typedef int __kernel_ssize_t32;
typedef int __kernel_ptrdiff_t32;
-typedef int __kernel_time_t32;
typedef int __kernel_suseconds_t32;
typedef int __kernel_clock_t32;
typedef int __kernel_daddr_t32;
diff -ruN 2.5.50/include/asm-ppc64/compat32.h 2.5.50-32bit.1/include/asm-ppc64/compat32.h
--- 2.5.50/include/asm-ppc64/compat32.h 1970-01-01 10:00:00.000000000 +1000
+++ 2.5.50-32bit.1/include/asm-ppc64/compat32.h 2002-11-29 13:16:25.000000000 +1100
@@ -0,0 +1,9 @@
+#ifndef _ASM_PPC64_COMPAT32_H
+#define _ASM_PPC64_COMPAT32_H
+/*
+ * Architecture specific 32 bit compatibility types
+ */
+
+typedef s32 compat32_time_t;
+
+#endif /* _ASM_PPC64_COMPAT32_H */
diff -ruN 2.5.50/include/asm-ppc64/ppc32.h 2.5.50-32bit.1/include/asm-ppc64/ppc32.h
--- 2.5.50/include/asm-ppc64/ppc32.h 2002-10-21 01:02:53.000000000 +1000
+++ 2.5.50-32bit.1/include/asm-ppc64/ppc32.h 2002-11-29 13:16:25.000000000 +1100
@@ -1,6 +1,7 @@
#ifndef _PPC64_PPC32_H
#define _PPC64_PPC32_H
+#include <linux/compat32.h>
#include <asm/siginfo.h>
#include <asm/signal.h>
@@ -46,7 +47,6 @@
typedef unsigned int __kernel_size_t32;
typedef int __kernel_ssize_t32;
typedef int __kernel_ptrdiff_t32;
-typedef int __kernel_time_t32;
typedef int __kernel_clock_t32;
typedef int __kernel_pid_t32;
typedef unsigned short __kernel_ipc_pid_t32;
@@ -185,11 +185,11 @@
__kernel_off_t32 st_size; /* 4 */
__kernel_off_t32 st_blksize; /* 4 */
__kernel_off_t32 st_blocks; /* 4 */
- __kernel_time_t32 st_atime; /* 4 */
+ compat32_time_t st_atime; /* 4 */
unsigned int __unused1; /* 4 */
- __kernel_time_t32 st_mtime; /* 4 */
+ compat32_time_t st_mtime; /* 4 */
unsigned int __unused2; /* 4 */
- __kernel_time_t32 st_ctime; /* 4 */
+ compat32_time_t st_ctime; /* 4 */
unsigned int __unused3; /* 4 */
unsigned int __unused4[2]; /* 2*4 */
};
diff -ruN 2.5.50/include/asm-s390x/compat32.h 2.5.50-32bit.1/include/asm-s390x/compat32.h
--- 2.5.50/include/asm-s390x/compat32.h 1970-01-01 10:00:00.000000000 +1000
+++ 2.5.50-32bit.1/include/asm-s390x/compat32.h 2002-11-29 13:16:25.000000000 +1100
@@ -0,0 +1,9 @@
+#ifndef _ASM_S390X_COMPAT32_H
+#define _ASM_S390X_COMPAT32_H
+/*
+ * Architecture specific 32 bit compatibility types
+ */
+
+typedef s32 compat32_time_t;
+
+#endif /* _ASM_S390X_COMPAT32_H */
diff -ruN 2.5.50/include/asm-sparc64/compat32.h 2.5.50-32bit.1/include/asm-sparc64/compat32.h
--- 2.5.50/include/asm-sparc64/compat32.h 1970-01-01 10:00:00.000000000 +1000
+++ 2.5.50-32bit.1/include/asm-sparc64/compat32.h 2002-11-29 13:16:25.000000000 +1100
@@ -0,0 +1,9 @@
+#ifndef _ASM_SPARC64_COMPAT32_H
+#define _ASM_SPARC64_COMPAT32_H
+/*
+ * Architecture specific 32 bit compatibility types
+ */
+
+typedef s32 compat32_time_t;
+
+#endif /* _ASM_SPARC64_COMPAT32_H */
diff -ruN 2.5.50/include/asm-sparc64/posix_types.h 2.5.50-32bit.1/include/asm-sparc64/posix_types.h
--- 2.5.50/include/asm-sparc64/posix_types.h 2000-10-28 04:55:01.000000000 +1100
+++ 2.5.50-32bit.1/include/asm-sparc64/posix_types.h 2002-11-29 13:16:25.000000000 +1100
@@ -51,7 +51,6 @@
typedef unsigned int __kernel_size_t32;
typedef int __kernel_ssize_t32;
typedef int __kernel_ptrdiff_t32;
-typedef int __kernel_time_t32;
typedef int __kernel_clock_t32;
typedef int __kernel_pid_t32;
typedef unsigned short __kernel_ipc_pid_t32;
diff -ruN 2.5.50/include/asm-sparc64/stat.h 2.5.50-32bit.1/include/asm-sparc64/stat.h
--- 2.5.50/include/asm-sparc64/stat.h 2002-11-18 15:47:55.000000000 +1100
+++ 2.5.50-32bit.1/include/asm-sparc64/stat.h 2002-11-29 13:16:25.000000000 +1100
@@ -3,6 +3,7 @@
#define _SPARC64_STAT_H
#include <linux/types.h>
+#include <linux/compat32.h>
#include <linux/time.h>
struct stat32 {
@@ -14,11 +15,11 @@
__kernel_gid_t32 st_gid;
__kernel_dev_t32 st_rdev;
__kernel_off_t32 st_size;
- __kernel_time_t32 st_atime;
+ compat32_time_t st_atime;
unsigned int __unused1;
- __kernel_time_t32 st_mtime;
+ compat32_time_t st_mtime;
unsigned int __unused2;
- __kernel_time_t32 st_ctime;
+ compat32_time_t st_ctime;
unsigned int __unused3;
__kernel_off_t32 st_blksize;
__kernel_off_t32 st_blocks;
diff -ruN 2.5.50/include/asm-x86_64/compat32.h 2.5.50-32bit.1/include/asm-x86_64/compat32.h
--- 2.5.50/include/asm-x86_64/compat32.h 1970-01-01 10:00:00.000000000 +1000
+++ 2.5.50-32bit.1/include/asm-x86_64/compat32.h 2002-11-29 13:16:25.000000000 +1100
@@ -0,0 +1,9 @@
+#ifndef _ASM_X86_64_COMPAT32_H
+#define _ASM_X86_64_COMPAT32_H
+/*
+ * Architecture specific 32 bit compatibility types
+ */
+
+typedef s32 compat32_time_t;
+
+#endif /* _ASM_X86_64_COMPAT32_H */
diff -ruN 2.5.50/include/asm-x86_64/ia32.h 2.5.50-32bit.1/include/asm-x86_64/ia32.h
--- 2.5.50/include/asm-x86_64/ia32.h 2002-10-21 13:35:27.000000000 +1000
+++ 2.5.50-32bit.1/include/asm-x86_64/ia32.h 2002-11-29 13:16:25.000000000 +1100
@@ -13,7 +13,6 @@
typedef unsigned int __kernel_size_t32;
typedef int __kernel_ssize_t32;
typedef int __kernel_ptrdiff_t32;
-typedef int __kernel_time_t32;
typedef int __kernel_clock_t32;
typedef int __kernel_pid_t32;
typedef unsigned short __kernel_ipc_pid_t32;
diff -ruN 2.5.50/include/linux/compat32.h 2.5.50-32bit.1/include/linux/compat32.h
--- 2.5.50/include/linux/compat32.h 1970-01-01 10:00:00.000000000 +1000
+++ 2.5.50-32bit.1/include/linux/compat32.h 2002-11-29 13:29:44.000000000 +1100
@@ -0,0 +1,20 @@
+#ifndef _LINUX_COMPAT32_H
+#define _LINUX_COMPAT32_H
+/*
+ * These are the type definitions for the 32 compatibility
+ * layer on 64 bit architectures.
+ */
+#include <linux/config.h>
+
+#ifdef CONFIG_COMPAT32
+
+#include <linux/types.h>
+#include <asm/compat32.h>
+
+struct timespec32 {
+ compat32_time_t tv_sec;
+ s32 tv_nsec;
+};
+
+#endif /* CONFIG_COMPAT32 */
+#endif /* _LINUX_COMPAT32_H */
diff -ruN 2.5.50/kernel/timer.c 2.5.50-32bit.1/kernel/timer.c
--- 2.5.50/kernel/timer.c 2002-11-28 10:35:50.000000000 +1100
+++ 2.5.50-32bit.1/kernel/timer.c 2002-11-29 15:34:48.000000000 +1100
@@ -19,12 +19,14 @@
* Designed by David S. Miller, Alexey Kuznetsov and Ingo Molnar
*/
+#include <linux/config.h>
#include <linux/kernel_stat.h>
#include <linux/interrupt.h>
#include <linux/percpu.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/notifier.h>
+#include <linux/compat32.h>
#include <asm/uaccess.h>
@@ -1022,33 +1024,64 @@
return current->pid;
}
-asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp)
+static 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;
+}
+
+#ifdef CONFIG_COMPAT32
+asmlinkage long sys32_nanosleep(struct timespec32 *rqtp,
+ struct timespec32 *rmtp)
+{
+ struct timespec t;
+ struct timespec32 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;
+}
+#endif /* CONFIG_COMPAT32 */
+
/*
* sys_sysinfo - fill in sysinfo struct
*/
Hi Linus,
This patch build on the previous patch and consolidates sys32_utime.
--
Cheers,
Stephen Rothwell [email protected]
http://www.canb.auug.org.au/~sfr/
diff -ruN 2.5.50-32bit.1/arch/ia64/ia32/sys_ia32.c 2.5.50-32bit.2/arch/ia64/ia32/sys_ia32.c
--- 2.5.50-32bit.1/arch/ia64/ia32/sys_ia32.c 2002-11-29 13:16:25.000000000 +1100
+++ 2.5.50-32bit.2/arch/ia64/ia32/sys_ia32.c 2002-11-29 15:13:13.000000000 +1100
@@ -20,7 +20,6 @@
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/signal.h>
-#include <linux/utime.h>
#include <linux/resource.h>
#include <linux/times.h>
#include <linux/utsname.h>
@@ -803,37 +802,6 @@
/* Translations due to time_t size differences. Which affects all
sorts of things, like timeval and itimerval. */
-struct utimbuf_32 {
- int atime;
- int mtime;
-};
-
-extern asmlinkage long sys_utimes(char * filename, struct timeval * utimes);
-extern asmlinkage long sys_gettimeofday (struct timeval *tv, struct timezone *tz);
-
-asmlinkage long
-sys32_utime (char *filename, struct utimbuf_32 *times32)
-{
- mm_segment_t old_fs = get_fs();
- struct timeval tv[2], *tvp;
- long ret;
-
- if (times32) {
- if (get_user(tv[0].tv_sec, ×32->atime))
- return -EFAULT;
- tv[0].tv_usec = 0;
- if (get_user(tv[1].tv_sec, ×32->mtime))
- return -EFAULT;
- tv[1].tv_usec = 0;
- set_fs(KERNEL_DS);
- tvp = tv;
- } else
- tvp = NULL;
- ret = sys_utimes(filename, tvp);
- set_fs(old_fs);
- return ret;
-}
-
extern struct timezone sys_tz;
extern int do_sys_settimeofday (struct timeval *tv, struct timezone *tz);
diff -ruN 2.5.50-32bit.1/arch/mips64/kernel/linux32.c 2.5.50-32bit.2/arch/mips64/kernel/linux32.c
--- 2.5.50-32bit.1/arch/mips64/kernel/linux32.c 2002-11-29 13:16:25.000000000 +1100
+++ 2.5.50-32bit.2/arch/mips64/kernel/linux32.c 2002-11-29 15:13:13.000000000 +1100
@@ -22,7 +22,6 @@
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/sysctl.h>
-#include <linux/utime.h>
#include <linux/utsname.h>
#include <linux/personality.h>
#include <linux/timex.h>
@@ -117,36 +116,6 @@
return sys_ftruncate(fd, ((long) high << 32) | low);
}
-extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
-
-struct utimbuf32 {
- compat32_time_t actime, modtime;
-};
-
-asmlinkage int sys32_utime(char * filename, struct utimbuf32 *times)
-{
- struct utimbuf t;
- mm_segment_t old_fs;
- int ret;
- char *filenam;
-
- if (!times)
- return sys_utime(filename, NULL);
- if (get_user (t.actime, ×->actime) ||
- __get_user (t.modtime, ×->modtime))
- return -EFAULT;
- filenam = getname (filename);
- ret = PTR_ERR(filenam);
- if (!IS_ERR(filenam)) {
- old_fs = get_fs();
- set_fs (KERNEL_DS);
- ret = sys_utime(filenam, &t);
- set_fs (old_fs);
- putname (filenam);
- }
- return ret;
-}
-
#if 0
/*
* count32() counts the number of arguments/envelopes
diff -ruN 2.5.50-32bit.1/arch/parisc/kernel/sys_parisc32.c 2.5.50-32bit.2/arch/parisc/kernel/sys_parisc32.c
--- 2.5.50-32bit.1/arch/parisc/kernel/sys_parisc32.c 2002-11-29 13:16:25.000000000 +1100
+++ 2.5.50-32bit.2/arch/parisc/kernel/sys_parisc32.c 2002-11-29 15:13:13.000000000 +1100
@@ -16,7 +16,6 @@
#include <linux/mm.h>
#include <linux/file.h>
#include <linux/signal.h>
-#include <linux/utime.h>
#include <linux/resource.h>
#include <linux/times.h>
#include <linux/utsname.h>
@@ -387,42 +386,6 @@
* code available in case it's useful to others. -PB
*/
-/* from utime.h */
-struct utimbuf32 {
- compat32_time_t actime;
- compat32_time_t modtime;
-};
-
-asmlinkage long sys32_utime(char *filename, struct utimbuf32 *times)
-{
- struct utimbuf32 times32;
- struct utimbuf times64;
- extern long sys_utime(char *filename, struct utimbuf *times);
- char *fname;
- long ret;
-
- if (!times)
- return sys_utime(filename, NULL);
-
- /* get the 32-bit struct from user space */
- if (copy_from_user(×32, times, sizeof times32))
- return -EFAULT;
-
- /* convert it into the 64-bit one */
- times64.actime = times32.actime;
- times64.modtime = times32.modtime;
-
- /* grab the file name */
- fname = getname(filename);
-
- KERNEL_SYSCALL(ret, sys_utime, fname, ×64);
-
- /* free the file name */
- putname(fname);
-
- return ret;
-}
-
struct tms32 {
__kernel_clock_t32 tms_utime;
__kernel_clock_t32 tms_stime;
diff -ruN 2.5.50-32bit.1/arch/ppc64/kernel/sys_ppc32.c 2.5.50-32bit.2/arch/ppc64/kernel/sys_ppc32.c
--- 2.5.50-32bit.1/arch/ppc64/kernel/sys_ppc32.c 2002-11-29 13:16:25.000000000 +1100
+++ 2.5.50-32bit.2/arch/ppc64/kernel/sys_ppc32.c 2002-11-29 15:13:13.000000000 +1100
@@ -22,7 +22,6 @@
#include <linux/mm.h>
#include <linux/file.h>
#include <linux/signal.h>
-#include <linux/utime.h>
#include <linux/resource.h>
#include <linux/times.h>
#include <linux/utsname.h>
@@ -70,39 +69,6 @@
#include <asm/ppc32.h>
#include <asm/mmu_context.h>
-extern asmlinkage long sys_utime(char * filename, struct utimbuf * times);
-
-struct utimbuf32 {
- compat32_time_t actime, modtime;
-};
-
-asmlinkage long sys32_utime(char * filename, struct utimbuf32 *times)
-{
- struct utimbuf t;
- mm_segment_t old_fs;
- int ret;
- char *filenam;
-
- if (!times)
- return sys_utime(filename, NULL);
- if (get_user(t.actime, ×->actime) || __get_user(t.modtime, ×->modtime))
- return -EFAULT;
- filenam = getname(filename);
-
- ret = PTR_ERR(filenam);
- if (!IS_ERR(filenam)) {
- old_fs = get_fs();
- set_fs (KERNEL_DS);
- ret = sys_utime(filenam, &t);
- set_fs (old_fs);
- putname (filenam);
- }
-
- return ret;
-}
-
-
-
struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; };
typedef ssize_t (*IO_fn_t)(struct file *, char *, size_t, loff_t *);
diff -ruN 2.5.50-32bit.1/arch/s390x/kernel/linux32.c 2.5.50-32bit.2/arch/s390x/kernel/linux32.c
--- 2.5.50-32bit.1/arch/s390x/kernel/linux32.c 2002-11-29 13:16:25.000000000 +1100
+++ 2.5.50-32bit.2/arch/s390x/kernel/linux32.c 2002-11-29 15:13:13.000000000 +1100
@@ -22,7 +22,6 @@
#include <linux/mm.h>
#include <linux/file.h>
#include <linux/signal.h>
-#include <linux/utime.h>
#include <linux/resource.h>
#include <linux/times.h>
#include <linux/utsname.h>
@@ -1011,36 +1010,6 @@
return sys_ftruncate(fd, (high << 32) | low);
}
-extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
-
-struct utimbuf32 {
- compat32_time_t actime, modtime;
-};
-
-asmlinkage int sys32_utime(char * filename, struct utimbuf32 *times)
-{
- struct utimbuf t;
- mm_segment_t old_fs;
- int ret;
- char *filenam;
-
- if (!times)
- return sys_utime(filename, NULL);
- if (get_user (t.actime, ×->actime) ||
- __get_user (t.modtime, ×->modtime))
- return -EFAULT;
- filenam = getname (filename);
- ret = PTR_ERR(filenam);
- if (!IS_ERR(filenam)) {
- old_fs = get_fs();
- set_fs (KERNEL_DS);
- ret = sys_utime(filenam, &t);
- set_fs (old_fs);
- putname (filenam);
- }
- return ret;
-}
-
struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; };
typedef ssize_t (*io_fn_t)(struct file *, char *, size_t, loff_t *);
diff -ruN 2.5.50-32bit.1/arch/s390x/kernel/wrapper32.S 2.5.50-32bit.2/arch/s390x/kernel/wrapper32.S
--- 2.5.50-32bit.1/arch/s390x/kernel/wrapper32.S 2002-11-29 13:16:25.000000000 +1100
+++ 2.5.50-32bit.2/arch/s390x/kernel/wrapper32.S 2002-11-29 15:13:13.000000000 +1100
@@ -133,7 +133,7 @@
.globl sys32_utime_wrapper
sys32_utime_wrapper:
llgtr %r2,%r2 # char *
- llgtr %r3,%r3 # struct utimbuf_emu31 *
+ llgtr %r3,%r3 # struct utimbuf32 *
jg sys32_utime # branch to system call
.globl sys32_access_wrapper
diff -ruN 2.5.50-32bit.1/arch/sparc64/kernel/sys_sparc32.c 2.5.50-32bit.2/arch/sparc64/kernel/sys_sparc32.c
--- 2.5.50-32bit.1/arch/sparc64/kernel/sys_sparc32.c 2002-11-29 13:16:25.000000000 +1100
+++ 2.5.50-32bit.2/arch/sparc64/kernel/sys_sparc32.c 2002-11-29 15:13:13.000000000 +1100
@@ -15,7 +15,6 @@
#include <linux/mm.h>
#include <linux/file.h>
#include <linux/signal.h>
-#include <linux/utime.h>
#include <linux/resource.h>
#include <linux/times.h>
#include <linux/utsname.h>
@@ -965,36 +964,6 @@
return sys_ftruncate(fd, (high << 32) | low);
}
-extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
-
-struct utimbuf32 {
- compat32_time_t actime, modtime;
-};
-
-asmlinkage int sys32_utime(char * filename, struct utimbuf32 *times)
-{
- struct utimbuf t;
- mm_segment_t old_fs;
- int ret;
- char *filenam;
-
- if (!times)
- return sys_utime(filename, NULL);
- if (get_user (t.actime, ×->actime) ||
- __get_user (t.modtime, ×->modtime))
- return -EFAULT;
- filenam = getname (filename);
- ret = PTR_ERR(filenam);
- if (!IS_ERR(filenam)) {
- old_fs = get_fs();
- set_fs (KERNEL_DS);
- ret = sys_utime(filenam, &t);
- set_fs (old_fs);
- putname (filenam);
- }
- return ret;
-}
-
struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; };
typedef ssize_t (*io_fn_t)(struct file *, char *, size_t, loff_t *);
diff -ruN 2.5.50-32bit.1/arch/x86_64/ia32/sys_ia32.c 2.5.50-32bit.2/arch/x86_64/ia32/sys_ia32.c
--- 2.5.50-32bit.1/arch/x86_64/ia32/sys_ia32.c 2002-11-29 13:16:25.000000000 +1100
+++ 2.5.50-32bit.2/arch/x86_64/ia32/sys_ia32.c 2002-11-29 15:13:13.000000000 +1100
@@ -26,7 +26,6 @@
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/signal.h>
-#include <linux/utime.h>
#include <linux/resource.h>
#include <linux/times.h>
#include <linux/utsname.h>
@@ -617,40 +616,6 @@
/* Translations due to time_t size differences. Which affects all
sorts of things, like timeval and itimerval. */
-struct utimbuf_32 {
- int atime;
- int mtime;
-};
-
-extern asmlinkage long sys_utimes(char * filename, struct timeval * utimes);
-extern asmlinkage long sys_gettimeofday (struct timeval *tv, struct timezone *tz);
-
-asmlinkage long
-ia32_utime(char * filename, struct utimbuf_32 *times32)
-{
- mm_segment_t old_fs = get_fs();
- struct timeval tv[2];
- long ret;
-
- if (times32) {
- get_user(tv[0].tv_sec, ×32->atime);
- tv[0].tv_usec = 0;
- get_user(tv[1].tv_sec, ×32->mtime);
- tv[1].tv_usec = 0;
- set_fs (KERNEL_DS);
- } else {
- set_fs (KERNEL_DS);
- ret = sys_gettimeofday(&tv[0], 0);
- if (ret < 0)
- goto out;
- tv[1] = tv[0];
- }
- ret = sys_utimes(filename, tv);
- out:
- set_fs (old_fs);
- return ret;
-}
-
extern struct timezone sys_tz;
extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
@@ -1377,38 +1342,6 @@
/* 32-bit timeval and related flotsam. */
-extern asmlinkage long sys_utime(char * filename, struct utimbuf * times);
-
-struct utimbuf32 {
- compat32_time_t actime, modtime;
-};
-
-asmlinkage long
-sys32_utime(char * filename, struct utimbuf32 *times)
-{
- struct utimbuf t;
- mm_segment_t old_fs;
- int ret;
- char *filenam;
-
- if (!times)
- return sys_utime(filename, NULL);
- if (verify_area(VERIFY_READ, times, sizeof(struct utimbuf32)) ||
- __get_user (t.actime, ×->actime) ||
- __get_user (t.modtime, ×->modtime))
- return -EFAULT;
- filenam = getname (filename);
- ret = PTR_ERR(filenam);
- if (!IS_ERR(filenam)) {
- old_fs = get_fs();
- set_fs (KERNEL_DS);
- ret = sys_utime(filenam, &t);
- set_fs (old_fs);
- putname(filenam);
- }
- return ret;
-}
-
extern asmlinkage long sys_sysfs(int option, unsigned long arg1,
unsigned long arg2);
diff -ruN 2.5.50-32bit.1/fs/open.c 2.5.50-32bit.2/fs/open.c
--- 2.5.50-32bit.1/fs/open.c 2002-11-28 10:35:47.000000000 +1100
+++ 2.5.50-32bit.2/fs/open.c 2002-11-29 15:16:27.000000000 +1100
@@ -4,6 +4,7 @@
* Copyright (C) 1991, 1992 Linus Torvalds
*/
+#include <linux/config.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/utime.h>
@@ -18,6 +19,7 @@
#include <linux/backing-dev.h>
#include <linux/security.h>
#include <linux/mount.h>
+#include <linux/compat32.h>
#include <asm/uaccess.h>
@@ -279,7 +281,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)
+static long do_utimes(char * filename, struct timeval * times)
{
int error;
struct nameidata nd;
@@ -298,11 +300,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;
@@ -322,6 +320,37 @@
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);
+}
+
+#ifdef CONFIG_COMPAT32
+/*
+ * Not all architectures have sys_utime, so implement this in terms
+ * of sys_utimes.
+ */
+extern long do_utimes(char * filename, struct timeval *utimes);
+
+asmlinkage long sys32_utime(char *filename, struct utimbuf32 *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);
+}
+#endif
+
/*
* 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-32bit.1/include/linux/compat32.h 2.5.50-32bit.2/include/linux/compat32.h
--- 2.5.50-32bit.1/include/linux/compat32.h 2002-11-29 13:29:44.000000000 +1100
+++ 2.5.50-32bit.2/include/linux/compat32.h 2002-11-29 15:14:38.000000000 +1100
@@ -16,5 +16,10 @@
s32 tv_nsec;
};
+struct utimbuf32 {
+ compat32_time_t actime;
+ compat32_time_t modtime;
+};
+
#endif /* CONFIG_COMPAT32 */
#endif /* _LINUX_COMPAT32_H */
On Wed, Nov 27, 2002 at 09:29:18AM +0100, Andi Kleen wrote:
> > That is not a safe assumption. The ia64 ABI requires that a 32-bit
> > result is returned in the least-significant 32 bits only---the upper
> > 32 bits may contain garbage. It should be safe to declare the syscall
> > return type always as "long", no?
>
> But the 32bit user space surely doesn't care about any garbage in
> the upper 32bits, no ?
It does. With very few exceptions all 32-bit instructions on MIPS require
that all the register values are properly sign extended to 64-bit or the
operation of those instructions is undefined.
Ralf
On Wed, 27 Nov 2002, David S. Miller wrote:
>
> I envisioned moving the compat stuff right next to the "normal"
> implementation.
Why?
> A problem currently, is that when people change VFS stuff up one has
> to pay attention to update all the compat syscall layers as well.
Doesn't matter. The thing is, you have two kinds of fixups for things like
VFS changes:
- compiler warning/error based fixups (in which case it doesn't _matter_
where it is, since in neither case will it get compiled for x86
- a simple "grep xxxx *.c" kind of approach.
Yes, the latter often misses out on architecture files, because people
just won't even look at hits in sparc/ppc64/xxx, either being too timid to
want to check, or just not caring. But if the file is in kernel/xxxx, it
will be noticed - at least as well as it would be if it was uglifying
regular files with #ifdef's.
> Now if we put the stuff next to the non-compat stuff, it likely won't
> get missed.
.. but it will have ugly #ifdef's inside the source file, something that I
absolutely detest.
Face it, the "compat" stuff is _secondary_. If it breaks, it breaks. It's
better to have the main code paths clean and unsullied, and take the risk
of occasionally breaking the compatibility stuff (that will break
occasionally anyway, see above).
Quite frankly, I want people to literally have the option to just ignore
the compat stuff, simply because it's not as important as the core kernel
code.
I see the compat32 patches as a convenience, and as a way to avoid
duplicating bus over the system. I do NOT consider it to be core
functionality, and I do _not_ think it should be a first-class citizen.
Sorry, guys. Code cleanliness is _way_ more important to me.
Linus
On Sun, 2002-12-01 at 10:54, Linus Torvalds wrote:
> But if the file is in kernel/xxxx, it
> will be noticed - at least as well as it would be if it was uglifying
> regular files with #ifdef's.
Ok, this I accept.
> Face it, the "compat" stuff is _secondary_. If it breaks, it breaks.
Secondary for x86, sure.
But for Sparc64 and PPC64, the 32-bit userland is currently still
the primary one, so when compat32 breaks the whole system hits the
toilet.
That isn't going to change. The 32-bit apps are a) smaller and b)
run much faster. So for simple things like the basic userland apps
like 'ls', the shell, etc. it simply makes no sense to compile them
64-bit. It just results in big huge 64-bit binaries when 32-bit
ones would suffice just fine.
Sparc64 and PPC64 are different from ia64 in that the apps truly
run on the processor at full speed, no in some compat logic soldered
onto the cpu like the ia64 x86 support seems to be :-)
X86_64 on the other hand seems to run x86 binaries in a similar
fashion. I don't know how people currently doing this port intend
to do the useland, but I bet it would benefit from a mostly 32-bit
userland just like sparc64/ppc64 does, both in space and performance.
Hi Dave,
On 01 Dec 2002 20:46:40 -0800 "David S. Miller" <[email protected]> wrote:
>
> On Sun, 2002-12-01 at 10:54, Linus Torvalds wrote:
> > But if the file is in kernel/xxxx, it
> > will be noticed - at least as well as it would be if it was uglifying
> > regular files with #ifdef's.
>
> Ok, this I accept.
So, does this mean you are happy if I produce patches with kernel/compat.c
in them rather than code #ifdef'ed into the mainline? This, of course,
begs the question of whether it should all go into kernel/compat.c or
should there be an fs/compat.c, mm/compat.c ...
At the moment, I just want to get something that we all agree on past
Linus and into his tree.
--
Cheers,
Stephen Rothwell [email protected]
http://www.canb.auug.org.au/~sfr/
From: Stephen Rothwell <[email protected]>
Date: Mon, 2 Dec 2002 15:57:29 +1100
On 01 Dec 2002 20:46:40 -0800 "David S. Miller" <[email protected]> wrote:
>
> On Sun, 2002-12-01 at 10:54, Linus Torvalds wrote:
> > But if the file is in kernel/xxxx, it
> > will be noticed - at least as well as it would be if it was uglifying
> > regular files with #ifdef's.
>
> Ok, this I accept.
So, does this mean you are happy if I produce patches with kernel/compat.c
in them rather than code #ifdef'ed into the mainline? This, of course,
begs the question of whether it should all go into kernel/compat.c or
should there be an fs/compat.c, mm/compat.c ...
Yes, I'm fine with it.
My personal take on the next issue is that I do believe we should
have fs/compat.c et al.
But for you initial patch, just put it into kernel/compat.c
On Sun, Dec 01, 2002 at 08:46:40PM -0800, David S. Miller wrote:
> X86_64 on the other hand seems to run x86 binaries in a similar
> fashion. I don't know how people currently doing this port intend
> to do the useland, but I bet it would benefit from a mostly 32-bit
> userland just like sparc64/ppc64 does, both in space and performance.
Except that x86-64 binaries get to use 16 more registers, can use
pc-relative addressing modes, and have a sane function calling
convention. So things tend to run a bit faster in 64-bit mode.
r~
From: Richard Henderson <[email protected]>
Date: Sun, 1 Dec 2002 23:39:01 -0800
Except that x86-64 binaries get to use 16 more registers, can use
pc-relative addressing modes, and have a sane function calling
convention. So things tend to run a bit faster in 64-bit mode.
Sure, I'll give you that, but nothing in the architecture is going to
half the size of every pointer for you.
I bet overall the TLB and cache usage is higher. The things the lack
of registers do is spill and thus beat on the stack, big deal, that
all tends to be in a contiguous areas of memory (ie. same cache blocks
and same TLB pages) and at least Intel has optimized stack memory
accesses out the wazoo.
On Sun, Dec 01, 2002 at 11:39:01PM -0800, Richard Henderson wrote:
> On Sun, Dec 01, 2002 at 08:46:40PM -0800, David S. Miller wrote:
> > X86_64 on the other hand seems to run x86 binaries in a similar
> > fashion. I don't know how people currently doing this port intend
> > to do the useland, but I bet it would benefit from a mostly 32-bit
> > userland just like sparc64/ppc64 does, both in space and performance.
>
> Except that x86-64 binaries get to use 16 more registers, can use
> pc-relative addressing modes, and have a sane function calling
> convention. So things tend to run a bit faster in 64-bit mode.
Cache locality tends to make a much bigger difference. I've been reported
a performance difference of over 100% for certain applications running 32-bit
on MIPS. 64-bit stuff just tends to push apps out of caches so I don't
see us on MIPS switch to a pure 64-bit any time soon either. Assuming the
availability of 64-bit compiler etc that is - at the moment we're entirely
dependant on the 32-bit environment.
What's the plan to attack 32-bit ioctls? Compared to "normal" syscalls
that's the much bigger dragon. The various ioctl32.c files in the tree
are ugly enough to cause a solar eclipse ;) The only sane solution that
also can work for multiply used ioctl numbers is pushing that down into
the the actual ioctl handlers (as opposed to an implementation sitting on
top of sys_ioctl() which basically is what we're having now) - but I guess
that's going to cause objections?
Ralf
From: Ralf Baechle <[email protected]>
Date: Mon, 2 Dec 2002 08:59:23 +0100
What's the plan to attack 32-bit ioctls?
...
but I guess that's going to cause objections?
Yes, a huge dragon to slay for sure.
To be honest, I'm happy with what's possible right now.
SIOCDEVPRIVATE was the biggest problem and that can be
gradually phased out.
Let's attack the easy stuff first, then we can retry finding
a nicer solution to the ioctl bits.
There are places where real work is needed, for example emulation
of drivers/usb/core/devio.c is nearly impossible without adding
some code to devio.c It keeps around user pointers, and doesn't
write to the area during that syscall but at some later time
as the result of another system call.
"David S. Miller" <[email protected]> writes:
> X86_64 on the other hand seems to run x86 binaries in a similar
> fashion. I don't know how people currently doing this port intend
Yes it does.
> to do the useland, but I bet it would benefit from a mostly 32-bit
> userland just like sparc64/ppc64 does, both in space and performance.
Apart from a few unfortunate exceptions[1] the code size growth from
ia32 to x86-64 is very moderate. The binaries appear a bit bigger
because they have an .ehframe linked in by default, but .text growth
is not that bad (normally 5-10%, in some cases it even gets smaller)
Random sample (with .ehframe stripped):
64bit ls:
-rwxr-xr-x 1 root root 76672 Oct 25 05:59 /bin/ls
text data bss dec hex filename
64847 7752 1136 73735 12007 /bin/ls
32bit ls:
-rwxr-xr-x 1 root root 68524 2002-09-09 22:56 /bin/ls
text data bss dec hex filename
65353 1112 872 67337 10709 /bin/ls
[< 1K .text growth, some .data growth due to 64bit pointers]
Performance is good too and gcc is a lot happier with 16 general purpose
integer registers than with 8.
The current x86-64 distributions I'm aware of have a full 64bit userland.
That said you can run a 32bit distribution with a 64bit kernel just fine,
with the exception of modutils, but that should be fixed now with the 2.5
in kernel module loader. Good 32bit emulation is a goal for the port.
So you can run what you want - 32bit or 64bit - but the default is 64bit.
-Andi
[1] emacs is twice as big because its fundamental lisp word grows
from 32bit to 64bit.
From: Andi Kleen <[email protected]>
Date: 02 Dec 2002 09:13:58 +0100
Random sample (with .ehframe stripped):
64bit ls:
-rwxr-xr-x 1 root root 76672 Oct 25 05:59 /bin/ls
text data bss dec hex filename
64847 7752 1136 73735 12007 /bin/ls
32bit ls:
-rwxr-xr-x 1 root root 68524 2002-09-09 22:56 /bin/ls
text data bss dec hex filename
65353 1112 872 67337 10709 /bin/ls
[< 1K .text growth, some .data growth due to 64bit pointers]
The data is where I'd say the bloat would be, and lo and behold is a
nearly 7-fold increase for the sample you give us _only_ in the .data
section.
This doesn't even include dynamically allocated data structures,
things that sit on the stack, etc.
I can definitely see the text staying roughly the same, that's not the
big cost, it's the larger data structures.
BTW, I bet your dynamic relocation tables are a bit larger too.
> The data is where I'd say the bloat would be, and lo and behold is a
> nearly 7-fold increase for the sample you give us _only_ in the .data
> section.
.data is normally not a significant part of programs, because few programs
use global variables that heavily (yes, there are exceptions, like that emacs
thing, but it's not common)
It appear big in ls because it's a very small program, but even there
are absolute numbers don't make much difference (1K vs 7K, even 1K
data needs one 4K page so the actual bloat is only another 4K)
Regarding the stack use: we're using 6.3K kernel stack + separate interrupt
stack in the kernel. While there were a few problems with stack overflow
it was usually very stupid bugs (like someone declaring a big long/pointer
array that just fit on 32bit, but exceeded it on 64bit). The normal
stack frame tend to be not that much bigger.
There is some heap bloat from pointers, but the effects are fairly
limited and I doubt ls will suffer from it significantly. Of course
when you're performance limited on a given problem it may be a good
idea to benchmark both -m32 and -m64, just to see if it's cache bound
by pointers. But I think -m64 is a good default nevertheless, simply
because the generated code is much better.
> BTW, I bet your dynamic relocation tables are a bit larger too.
Somewhat, but does it matter? They are not kept in memory anyways.
-Andi
On Mon, Dec 02, 2002 at 10:07:56AM +0100, Andi Kleen wrote:
> > The data is where I'd say the bloat would be, and lo and behold is a
> > nearly 7-fold increase for the sample you give us _only_ in the .data
> > section.
>
> .data is normally not a significant part of programs, because few programs
> use global variables that heavily (yes, there are exceptions, like that emacs
> thing, but it's not common)
.data is significant, that is e.g. something that cannot be shared
between processes.
The fastest model on x86-64 would IMHO be a 32-bit model using all
registers, rip relative addressing and register passing conventions
(ie. a 3rd ABI).
> > BTW, I bet your dynamic relocation tables are a bit larger too.
>
> Somewhat, but does it matter? They are not kept in memory anyways.
Surely it does, for startup time (unless prelinking) the 3 times bigger .rel*
sections mean significantly more data needs to be loaded into RAM and
caches, for short-lived processes it matters a lot.
Jakub
From: Andi Kleen <[email protected]>
Date: Mon, 2 Dec 2002 10:07:56 +0100
> BTW, I bet your dynamic relocation tables are a bit larger too.
Somewhat, but does it matter? They are not kept in memory anyways.
It's all about how much data a ld.so relocation has to touch. But
preloading will help out here, even though that isn't in wide spread
use just yet.
And I was talking about user stack usage, not the kernel kind
:-)
Andi, do something very simple like run -m32 vs -m64 microbenchmarks,
I bet -m32 beats -m64 in all the lmbench lat_proc tests. On sparc64
it's (on a 2-way SMP system):
-m32 fork+exit: 360.8328 microseconds
-m32 fork+execve: 1342.2213 microseconds
-m32 fork+/bin/sh: 5497.0149 microseconds
-m64 fork+exit: 553.9076 microseconds
-m64 fork+execve: 1904.6315 microseconds
-m64 fork+/bin/sh: 6268.6932 microseconds
NOTE: make sure you change /bin/sh to be 32-bit/64-bit as
appropriate in the tests above.
So what is this on x86_64? :-) I think lat_proc is great becuase it
shows pure libc overhead in continually relocating the exit()
etc. symbols in the child for fork+exit, for example.
The reason I'm making such a stink about this is that I don't want
people believing that "the code generation improvements due to the
extra x86_64 registers available nullifies the bloat cost from
going to 64-bit"
To me, believe that is an utterly bogus claim and completely
misleading.
Jakub Jelinek writes:
> The fastest model on x86-64 would IMHO be a 32-bit model using all
> registers, rip relative addressing and register passing conventions
> (ie. a 3rd ABI).
When not doing Linux hacks I work on compilers and runtime systems,
and I agree that a model with x86_64 native mode enabled (and thus
the extra registers and addressing modes) but still in a 32-bit
address space looks like a very interesting option for those
applications that don't need tons of address space.
/Mikael
From: Pavel Machek <[email protected]>
Date: Wed, 4 Dec 2002 12:19:47 +0100
Actually, it tends to nullify the bloat cost and then make it few
percent faster... For most of spec2000 modulo two or three cache-bound
tests that are 50% slower :-(.
How about some test where relocations come into play?
spec2000 is a bad example, it's just crunch code.
Most systems spend their time running quick small executables over and
over, and in such cases relocation overhead shows up very strongly.
This is why I asked for fork, exec et al. latency figures for 32-bit
vs 64-bit on x86_64 but I've been informed in private email that
nobody can send me numbers due to NDAs.
I still think making the simple programs like ls, cat, bash et
al. 64-bit in a dist is a bad idea.
Hi!
> > BTW, I bet your dynamic relocation tables are a bit larger too.
>
> Somewhat, but does it matter? They are not kept in memory anyways.
>
> It's all about how much data a ld.so relocation has to touch. But
> preloading will help out here, even though that isn't in wide spread
> use just yet.
>
> And I was talking about user stack usage, not the kernel kind
> :-)
>
> Andi, do something very simple like run -m32 vs -m64 microbenchmarks,
> I bet -m32 beats -m64 in all the lmbench lat_proc tests. On sparc64
> it's (on a 2-way SMP system):
>
> -m32 fork+exit: 360.8328 microseconds
> -m32 fork+execve: 1342.2213 microseconds
> -m32 fork+/bin/sh: 5497.0149 microseconds
>
> -m64 fork+exit: 553.9076 microseconds
> -m64 fork+execve: 1904.6315 microseconds
> -m64 fork+/bin/sh: 6268.6932 microseconds
>
> NOTE: make sure you change /bin/sh to be 32-bit/64-bit as
> appropriate in the tests above.
>
> So what is this on x86_64? :-) I think lat_proc is great becuase it
> shows pure libc overhead in continually relocating the exit()
> etc. symbols in the child for fork+exit, for example.
>
> The reason I'm making such a stink about this is that I don't want
> people believing that "the code generation improvements due to the
> extra x86_64 registers available nullifies the bloat cost from
> going to 64-bit"
Actually, it tends to nullify the bloat cost and then make it few
percent faster... For most of spec2000 modulo two or three cache-bound
tests that are 50% slower :-(.
Pavel
--
Worst form of spam? Adding advertisment signatures ala sourceforge.net.
What goes next? Inserting advertisment *into* email?
From: Pavel Machek <[email protected]>
Date: Wed, 4 Dec 2002 12:22:36 +0100
Right option might be to kill devio.c :-). It has other problems, too,
IIRC.
Well, something has to replace it so that I can download pictures
from my Canon EOS D30 in userspace :-)
Hi!
> Actually, it tends to nullify the bloat cost and then make it few
> percent faster... For most of spec2000 modulo two or three cache-bound
> tests that are 50% slower :-(.
>
> How about some test where relocations come into play?
> spec2000 is a bad example, it's just crunch code.
time ./configure might be a good test...
> Most systems spend their time running quick small executables over and
> over, and in such cases relocation overhead shows up very strongly.
Really? What workload besides configure does many small programs?
> This is why I asked for fork, exec et al. latency figures for 32-bit
> vs 64-bit on x86_64 but I've been informed in private email that
> nobody can send me numbers due to NDAs.
>
> I still think making the simple programs like ls, cat, bash et
> al. 64-bit in a dist is a bad idea.
Agreed for ls and cat, but I do not think it hurts for bash...
Pavel
--
Worst form of spam? Adding advertisment signatures ala sourceforge.net.
What goes next? Inserting advertisment *into* email?
Hi!
> > How about some test where relocations come into play?
> > spec2000 is a bad example, it's just crunch code.
>
> time ./configure might be a good test...
>
> Agreed.
>
> > Most systems spend their time running quick small executables over and
> > over, and in such cases relocation overhead shows up very strongly.
>
> Really? What workload besides configure does many small programs?
>
> What do you do when you're developing code? make, edit, ldd, ls,
> grep, etc.
Yes, but as developing code is human-bound (waits for my input most of
the time), it is not *that* important. [It is probably still nice to
have it fast.]
OTOH: gcc is faster 64-bit, and if you mix 32-bit and 64-bit, you
loose caches and have twice as many libraries. I guess 5% faster gcc
is more important than 30% slower ls...
Pavel
--
Casualities in World Trade Center: ~3k dead inside the building,
cryptography in U.S.A. and free speech in Czech Republic.
Hi!
> What's the plan to attack 32-bit ioctls?
> ...
> but I guess that's going to cause objections?
>
> Yes, a huge dragon to slay for sure.
>
> To be honest, I'm happy with what's possible right now.
> SIOCDEVPRIVATE was the biggest problem and that can be
> gradually phased out.
>
> Let's attack the easy stuff first, then we can retry finding
> a nicer solution to the ioctl bits.
>
> There are places where real work is needed, for example emulation
> of drivers/usb/core/devio.c is nearly impossible without adding
> some code to devio.c It keeps around user pointers, and doesn't
> write to the area during that syscall but at some later time
> as the result of another system call.
Right option might be to kill devio.c :-). It has other problems, too,
IIRC.
Pavel
--
Worst form of spam? Adding advertisment signatures ala sourceforge.net.
What goes next? Inserting advertisment *into* email?
From: Pavel Machek <[email protected]>
Date: Thu, 5 Dec 2002 22:21:20 +0100
> How about some test where relocations come into play?
> spec2000 is a bad example, it's just crunch code.
time ./configure might be a good test...
Agreed.
> Most systems spend their time running quick small executables over and
> over, and in such cases relocation overhead shows up very strongly.
Really? What workload besides configure does many small programs?
What do you do when you're developing code? make, edit, ldd, ls,
grep, etc.
Agreed for ls and cat, but I do not think it hurts for bash...
It does a lot of relocations in child processes, so I bet it will
matter. 'make' might be better off since it uses vfork but on the
other hand it does have quite sizable data structures.