Commit 92f777ca authored by Stephen Rothwell's avatar Stephen Rothwell Committed by Vojtech Pavlik

[PATCH] x86_64 compatibility layer update

Andi has asked that I send these straight forward compatibility patches
to you and he will fix up any merge problems later.  These are the
outstanding patches for x86_64 against 2.5.60.
parent daebc586
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/unistd.h> #include <linux/unistd.h>
#include <linux/stddef.h> #include <linux/stddef.h>
#include <linux/personality.h> #include <linux/personality.h>
#include <linux/compat.h>
#include <asm/ucontext.h> #include <asm/ucontext.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/i387.h> #include <asm/i387.h>
...@@ -134,7 +135,7 @@ struct sigframe ...@@ -134,7 +135,7 @@ struct sigframe
int sig; int sig;
struct sigcontext_ia32 sc; struct sigcontext_ia32 sc;
struct _fpstate_ia32 fpstate; struct _fpstate_ia32 fpstate;
unsigned int extramask[_IA32_NSIG_WORDS-1]; unsigned int extramask[_COMPAT_NSIG_WORDS-1];
char retcode[8]; char retcode[8];
}; };
...@@ -237,7 +238,7 @@ asmlinkage long sys32_sigreturn(struct pt_regs regs) ...@@ -237,7 +238,7 @@ asmlinkage long sys32_sigreturn(struct pt_regs regs)
if (verify_area(VERIFY_READ, frame, sizeof(*frame))) if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
goto badframe; goto badframe;
if (__get_user(set.sig[0], &frame->sc.oldmask) if (__get_user(set.sig[0], &frame->sc.oldmask)
|| (_IA32_NSIG_WORDS > 1 || (_COMPAT_NSIG_WORDS > 1
&& __copy_from_user((((char *) &set.sig) + 4), &frame->extramask, && __copy_from_user((((char *) &set.sig) + 4), &frame->extramask,
sizeof(frame->extramask)))) sizeof(frame->extramask))))
goto badframe; goto badframe;
...@@ -373,7 +374,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) ...@@ -373,7 +374,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
} }
void ia32_setup_frame(int sig, struct k_sigaction *ka, void ia32_setup_frame(int sig, struct k_sigaction *ka,
sigset32_t *set, struct pt_regs * regs) compat_sigset_t *set, struct pt_regs * regs)
{ {
struct sigframe *frame; struct sigframe *frame;
int err = 0; int err = 0;
...@@ -399,7 +400,7 @@ void ia32_setup_frame(int sig, struct k_sigaction *ka, ...@@ -399,7 +400,7 @@ void ia32_setup_frame(int sig, struct k_sigaction *ka,
if (err) if (err)
goto give_sigsegv; goto give_sigsegv;
if (_IA32_NSIG_WORDS > 1) { if (_COMPAT_NSIG_WORDS > 1) {
err |= __copy_to_user(frame->extramask, &set->sig[1], err |= __copy_to_user(frame->extramask, &set->sig[1],
sizeof(frame->extramask)); sizeof(frame->extramask));
} }
...@@ -460,7 +461,7 @@ void ia32_setup_frame(int sig, struct k_sigaction *ka, ...@@ -460,7 +461,7 @@ void ia32_setup_frame(int sig, struct k_sigaction *ka,
} }
void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
sigset32_t *set, struct pt_regs * regs) compat_sigset_t *set, struct pt_regs * regs)
{ {
struct rt_sigframe *frame; struct rt_sigframe *frame;
int err = 0; int err = 0;
......
...@@ -273,7 +273,7 @@ ia32_sys_call_table: ...@@ -273,7 +273,7 @@ ia32_sys_call_table:
.quad sys_setreuid16 /* 70 */ .quad sys_setreuid16 /* 70 */
.quad sys_setregid16 .quad sys_setregid16
.quad stub32_sigsuspend .quad stub32_sigsuspend
.quad sys32_sigpending .quad compat_sys_sigpending
.quad sys_sethostname .quad sys_sethostname
.quad sys32_setrlimit /* 75 */ .quad sys32_setrlimit /* 75 */
.quad sys32_old_getrlimit /* old_getrlimit */ .quad sys32_old_getrlimit /* old_getrlimit */
...@@ -326,7 +326,7 @@ ia32_sys_call_table: ...@@ -326,7 +326,7 @@ ia32_sys_call_table:
.quad sys32_modify_ldt .quad sys32_modify_ldt
.quad sys32_adjtimex .quad sys32_adjtimex
.quad sys32_mprotect /* 125 */ .quad sys32_mprotect /* 125 */
.quad sys32_sigprocmask .quad compat_sys_sigprocmask
.quad sys32_module_warning /* create_module */ .quad sys32_module_warning /* create_module */
.quad sys_init_module .quad sys_init_module
.quad sys_delete_module .quad sys_delete_module
......
...@@ -626,9 +626,7 @@ static long semtimedop32(int semid, struct sembuf *sb, ...@@ -626,9 +626,7 @@ static long semtimedop32(int semid, struct sembuf *sb,
return -E2BIG; return -E2BIG;
if (!access_ok(VERIFY_READ, sb, nsops * sizeof(struct sembuf))) if (!access_ok(VERIFY_READ, sb, nsops * sizeof(struct sembuf)))
return -EFAULT; return -EFAULT;
if (ts32 && if (ts32 && get_compat_timespec(&ts, ts32))
(get_user(ts.tv_sec, &ts32->tv_sec) ||
__get_user(ts.tv_nsec, &ts32->tv_nsec)))
return -EFAULT; return -EFAULT;
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
......
...@@ -276,10 +276,10 @@ sys32_rt_sigaction(int sig, struct sigaction32 *act, ...@@ -276,10 +276,10 @@ sys32_rt_sigaction(int sig, struct sigaction32 *act,
{ {
struct k_sigaction new_ka, old_ka; struct k_sigaction new_ka, old_ka;
int ret; int ret;
sigset32_t set32; compat_sigset_t set32;
/* XXX: Don't preclude handling different sized sigset_t's. */ /* XXX: Don't preclude handling different sized sigset_t's. */
if (sigsetsize != sizeof(sigset32_t)) if (sigsetsize != sizeof(compat_sigset_t))
return -EINVAL; return -EINVAL;
if (act) { if (act) {
...@@ -287,10 +287,10 @@ sys32_rt_sigaction(int sig, struct sigaction32 *act, ...@@ -287,10 +287,10 @@ sys32_rt_sigaction(int sig, struct sigaction32 *act,
__get_user((long)new_ka.sa.sa_handler, &act->sa_handler) || __get_user((long)new_ka.sa.sa_handler, &act->sa_handler) ||
__get_user(new_ka.sa.sa_flags, &act->sa_flags) || __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
__get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer)|| __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer)||
__copy_from_user(&set32, &act->sa_mask, sizeof(sigset32_t))) __copy_from_user(&set32, &act->sa_mask, sizeof(compat_sigset_t)))
return -EFAULT; return -EFAULT;
/* FIXME: here we rely on _IA32_NSIG_WORS to be >= than _NSIG_WORDS << 1 */ /* FIXME: here we rely on _COMPAT_NSIG_WORS to be >= than _NSIG_WORDS << 1 */
switch (_NSIG_WORDS) { switch (_NSIG_WORDS) {
case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6] case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6]
| (((long)set32.sig[7]) << 32); | (((long)set32.sig[7]) << 32);
...@@ -306,7 +306,7 @@ sys32_rt_sigaction(int sig, struct sigaction32 *act, ...@@ -306,7 +306,7 @@ sys32_rt_sigaction(int sig, struct sigaction32 *act,
ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
if (!ret && oact) { if (!ret && oact) {
/* FIXME: here we rely on _IA32_NSIG_WORS to be >= than _NSIG_WORDS << 1 */ /* FIXME: here we rely on _COMPAT_NSIG_WORS to be >= than _NSIG_WORDS << 1 */
switch (_NSIG_WORDS) { switch (_NSIG_WORDS) {
case 4: case 4:
set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32); set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32);
...@@ -325,7 +325,7 @@ sys32_rt_sigaction(int sig, struct sigaction32 *act, ...@@ -325,7 +325,7 @@ sys32_rt_sigaction(int sig, struct sigaction32 *act,
__put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) || __put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) ||
__put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) || __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) ||
__put_user(old_ka.sa.sa_flags, &oact->sa_flags) || __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
__copy_to_user(&oact->sa_mask, &set32, sizeof(sigset32_t))) __copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t)))
return -EFAULT; return -EFAULT;
} }
...@@ -339,7 +339,7 @@ sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *o ...@@ -339,7 +339,7 @@ sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *o
int ret; int ret;
if (act) { if (act) {
old_sigset32_t mask; compat_old_sigset_t mask;
if (verify_area(VERIFY_READ, act, sizeof(*act)) || if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
__get_user((long)new_ka.sa.sa_handler, &act->sa_handler) || __get_user((long)new_ka.sa.sa_handler, &act->sa_handler) ||
...@@ -368,16 +368,16 @@ extern asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset ...@@ -368,16 +368,16 @@ extern asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset
size_t sigsetsize); size_t sigsetsize);
asmlinkage long asmlinkage long
sys32_rt_sigprocmask(int how, sigset32_t *set, sigset32_t *oset, sys32_rt_sigprocmask(int how, compat_sigset_t *set, compat_sigset_t *oset,
unsigned int sigsetsize) unsigned int sigsetsize)
{ {
sigset_t s; sigset_t s;
sigset32_t s32; compat_sigset_t s32;
int ret; int ret;
mm_segment_t old_fs = get_fs(); mm_segment_t old_fs = get_fs();
if (set) { if (set) {
if (copy_from_user (&s32, set, sizeof(sigset32_t))) if (copy_from_user (&s32, set, sizeof(compat_sigset_t)))
return -EFAULT; return -EFAULT;
switch (_NSIG_WORDS) { switch (_NSIG_WORDS) {
case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32); case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
...@@ -398,7 +398,7 @@ sys32_rt_sigprocmask(int how, sigset32_t *set, sigset32_t *oset, ...@@ -398,7 +398,7 @@ sys32_rt_sigprocmask(int how, sigset32_t *set, sigset32_t *oset,
case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1]; case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0]; case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
} }
if (copy_to_user (oset, &s32, sizeof(sigset32_t))) if (copy_to_user (oset, &s32, sizeof(compat_sigset_t)))
return -EFAULT; return -EFAULT;
} }
return 0; return 0;
...@@ -1219,55 +1219,18 @@ sys32_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec *interval) ...@@ -1219,55 +1219,18 @@ sys32_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec *interval)
set_fs (KERNEL_DS); set_fs (KERNEL_DS);
ret = sys_sched_rr_get_interval(pid, &t); ret = sys_sched_rr_get_interval(pid, &t);
set_fs (old_fs); set_fs (old_fs);
if (verify_area(VERIFY_WRITE, interval, sizeof(struct compat_timespec)) || if (put_compat_timespec(&t, interval))
__put_user (t.tv_sec, &interval->tv_sec) ||
__put_user (t.tv_nsec, &interval->tv_nsec))
return -EFAULT; return -EFAULT;
return ret; return ret;
} }
extern asmlinkage long sys_sigprocmask(int how, old_sigset_t *set,
old_sigset_t *oset);
asmlinkage long
sys32_sigprocmask(int how, old_sigset32_t *set, old_sigset32_t *oset)
{
old_sigset_t s;
int ret;
mm_segment_t old_fs = get_fs();
if (set && get_user (s, set)) return -EFAULT;
set_fs (KERNEL_DS);
ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL);
set_fs (old_fs);
if (ret) return ret;
if (oset && put_user (s, oset)) return -EFAULT;
return 0;
}
extern asmlinkage long sys_sigpending(old_sigset_t *set);
asmlinkage long
sys32_sigpending(old_sigset32_t *set)
{
old_sigset_t s;
int ret;
mm_segment_t old_fs = get_fs();
set_fs (KERNEL_DS);
ret = sys_sigpending(&s);
set_fs (old_fs);
if (put_user (s, set)) return -EFAULT;
return ret;
}
extern asmlinkage long sys_rt_sigpending(sigset_t *set, size_t sigsetsize); extern asmlinkage long sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
asmlinkage long asmlinkage long
sys32_rt_sigpending(sigset32_t *set, compat_size_t sigsetsize) sys32_rt_sigpending(compat_sigset_t *set, compat_size_t sigsetsize)
{ {
sigset_t s; sigset_t s;
sigset32_t s32; compat_sigset_t s32;
int ret; int ret;
mm_segment_t old_fs = get_fs(); mm_segment_t old_fs = get_fs();
...@@ -1281,7 +1244,7 @@ sys32_rt_sigpending(sigset32_t *set, compat_size_t sigsetsize) ...@@ -1281,7 +1244,7 @@ sys32_rt_sigpending(sigset32_t *set, compat_size_t sigsetsize)
case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1]; case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0]; case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
} }
if (copy_to_user (set, &s32, sizeof(sigset32_t))) if (copy_to_user (set, &s32, sizeof(compat_sigset_t)))
return -EFAULT; return -EFAULT;
} }
return ret; return ret;
...@@ -1369,18 +1332,18 @@ sys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo, ...@@ -1369,18 +1332,18 @@ sys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo,
const struct timespec *uts, size_t sigsetsize); const struct timespec *uts, size_t sigsetsize);
asmlinkage long asmlinkage long
sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo, sys32_rt_sigtimedwait(compat_sigset_t *uthese, siginfo_t32 *uinfo,
struct compat_timespec *uts, compat_size_t sigsetsize) struct compat_timespec *uts, compat_size_t sigsetsize)
{ {
sigset_t s; sigset_t s;
sigset32_t s32; compat_sigset_t s32;
struct timespec t; struct timespec t;
int ret; int ret;
mm_segment_t old_fs = get_fs(); mm_segment_t old_fs = get_fs();
siginfo_t info; siginfo_t info;
siginfo_t32 info32; siginfo_t32 info32;
if (copy_from_user (&s32, uthese, sizeof(sigset32_t))) if (copy_from_user (&s32, uthese, sizeof(compat_sigset_t)))
return -EFAULT; return -EFAULT;
switch (_NSIG_WORDS) { switch (_NSIG_WORDS) {
case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32); case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
...@@ -1388,14 +1351,11 @@ sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo, ...@@ -1388,14 +1351,11 @@ sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo,
case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32); case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32); case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
} }
if (uts) { if (uts && get_compat_timespec(&t, uts))
if (verify_area(VERIFY_READ, uts, sizeof(struct compat_timespec)) || return -EFAULT;
__get_user (t.tv_sec, &uts->tv_sec) ||
__get_user (t.tv_nsec, &uts->tv_nsec))
return -EFAULT;
}
set_fs (KERNEL_DS); set_fs (KERNEL_DS);
ret = sys_rt_sigtimedwait(&s, &info, &t, sigsetsize); ret = sys_rt_sigtimedwait(&s, uinfo ? &info : NULL, uts ? &t : NULL,
sigsetsize);
set_fs (old_fs); set_fs (old_fs);
if (ret >= 0 && uinfo) { if (ret >= 0 && uinfo) {
if (copy_to_user (uinfo, siginfo64to32(&info32, &info), if (copy_to_user (uinfo, siginfo64to32(&info32, &info),
...@@ -2248,20 +2208,13 @@ sys32_futex(unsigned long uaddr, int op, int val, struct compat_timespec *utime3 ...@@ -2248,20 +2208,13 @@ sys32_futex(unsigned long uaddr, int op, int val, struct compat_timespec *utime3
mm_segment_t oldfs = get_fs(); mm_segment_t oldfs = get_fs();
int err; int err;
if (utime32) { if (utime32 && get_compat_timespec(&t, utime32))
if (verify_area(VERIFY_READ, utime32, sizeof(*utime32))) return -EFAULT;
return -EFAULT;
if (__get_user(t.tv_sec, &utime32->tv_sec) ||
__get_user(t.tv_nsec, &utime32->tv_nsec))
return -EFAULT;
}
/* the set_fs is safe because futex doesn't use the seg limit /* the set_fs is safe because futex doesn't use the seg limit
for valid page checking of uaddr. */ for valid page checking of uaddr. */
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
err = sys_futex(uaddr, op, val, &t); err = sys_futex(uaddr, op, val, utime32 ? &t : NULL);
set_fs(oldfs); set_fs(oldfs);
return err; return err;
} }
...@@ -2340,22 +2293,18 @@ asmlinkage long sys32_io_getevents(aio_context_t ctx_id, ...@@ -2340,22 +2293,18 @@ asmlinkage long sys32_io_getevents(aio_context_t ctx_id,
{ {
long ret; long ret;
mm_segment_t oldfs; mm_segment_t oldfs;
struct timespec t32; struct timespec t;
/* Harden against bogus ptrace */ /* Harden against bogus ptrace */
if (nr >= 0xffffffff || if (nr >= 0xffffffff ||
!access_ok(VERIFY_WRITE, events, nr * sizeof(struct io_event))) !access_ok(VERIFY_WRITE, events, nr * sizeof(struct io_event)))
return -EFAULT; return -EFAULT;
if (timeout && if (timeout && get_compat_timespec(&t, timeout))
(get_user(t32.tv_sec, &timeout->tv_sec) ||
__get_user(t32.tv_nsec, &timeout->tv_nsec)))
return -EFAULT; return -EFAULT;
oldfs = get_fs(); oldfs = get_fs();
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
ret = sys_io_getevents(ctx_id,min_nr,nr,events,timeout ? &t32 : NULL); ret = sys_io_getevents(ctx_id,min_nr,nr,events,timeout ? &t : NULL);
set_fs(oldfs); set_fs(oldfs);
if (timeout && if (timeout && put_compat_timespec(&t, timeout))
(__put_user(t32.tv_sec, &timeout->tv_sec) ||
__put_user(t32.tv_nsec, &timeout->tv_nsec)))
return -EFAULT; return -EFAULT;
return ret; return ret;
} }
......
...@@ -26,28 +26,18 @@ struct ia32_flock64 { ...@@ -26,28 +26,18 @@ struct ia32_flock64 {
#include <asm/sigcontext32.h> #include <asm/sigcontext32.h>
/* signal.h */ /* signal.h */
#define _IA32_NSIG 64
#define _IA32_NSIG_BPW 32
#define _IA32_NSIG_WORDS (_IA32_NSIG / _IA32_NSIG_BPW)
typedef struct {
unsigned int sig[_IA32_NSIG_WORDS];
} sigset32_t;
struct sigaction32 { struct sigaction32 {
unsigned int sa_handler; /* Really a pointer, but need to deal unsigned int sa_handler; /* Really a pointer, but need to deal
with 32 bits */ with 32 bits */
unsigned int sa_flags; unsigned int sa_flags;
unsigned int sa_restorer; /* Another 32 bit pointer */ unsigned int sa_restorer; /* Another 32 bit pointer */
sigset32_t sa_mask; /* A 32 bit mask */ compat_sigset_t sa_mask; /* A 32 bit mask */
}; };
typedef unsigned int old_sigset32_t; /* at least 32 bits */
struct old_sigaction32 { struct old_sigaction32 {
unsigned int sa_handler; /* Really a pointer, but need to deal unsigned int sa_handler; /* Really a pointer, but need to deal
with 32 bits */ with 32 bits */
old_sigset32_t sa_mask; /* A 32 bit mask */ compat_old_sigset_t sa_mask; /* A 32 bit mask */
unsigned int sa_flags; unsigned int sa_flags;
unsigned int sa_restorer; /* Another 32 bit pointer */ unsigned int sa_restorer; /* Another 32 bit pointer */
}; };
...@@ -63,7 +53,7 @@ struct ucontext_ia32 { ...@@ -63,7 +53,7 @@ struct ucontext_ia32 {
unsigned int uc_link; unsigned int uc_link;
stack_ia32_t uc_stack; stack_ia32_t uc_stack;
struct sigcontext_ia32 uc_mcontext; struct sigcontext_ia32 uc_mcontext;
sigset32_t uc_sigmask; /* mask last for extensibility */ compat_sigset_t uc_sigmask; /* mask last for extensibility */
}; };
/* This matches struct stat64 in glibc2.2, hence the absolutely /* This matches struct stat64 in glibc2.2, hence the absolutely
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment