Commit fa58239a authored by Paul Mackerras's avatar Paul Mackerras

Merge samba.org:/home/paulus/kernel/linux-2.5

into samba.org:/home/paulus/kernel/for-linus-ppc
parents 7dbb30bf 2bbc35cb
...@@ -272,7 +272,7 @@ restore_user_regs(struct pt_regs *regs, struct mcontext __user *sr) ...@@ -272,7 +272,7 @@ restore_user_regs(struct pt_regs *regs, struct mcontext __user *sr)
sizeof(sr->mc_vregs))) sizeof(sr->mc_vregs)))
return 1; return 1;
} else if (current->thread.used_vr) } else if (current->thread.used_vr)
memset(&current->thread.vr, 0, sizeof(current->thread.vr)); memset(&current->thread.vr, 0, ELF_NVRREG * sizeof(vector128));
/* Always get VRSAVE back */ /* Always get VRSAVE back */
if (__get_user(current->thread.vrsave, (u32 *)&sr->mc_vregs[32])) if (__get_user(current->thread.vrsave, (u32 *)&sr->mc_vregs[32]))
...@@ -328,7 +328,6 @@ handle_rt_signal(unsigned long sig, struct k_sigaction *ka, ...@@ -328,7 +328,6 @@ handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
&rt_sf->uc.uc_stack.ss_flags) &rt_sf->uc.uc_stack.ss_flags)
|| __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size) || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
|| __put_user(&rt_sf->uc.uc_mcontext, &rt_sf->uc.uc_regs) || __put_user(&rt_sf->uc.uc_mcontext, &rt_sf->uc.uc_regs)
|| __copy_to_user(&rt_sf->uc.uc_oldsigmask, oldset, sizeof(*oldset))
|| __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset))) || __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset)))
goto badframe; goto badframe;
...@@ -363,12 +362,13 @@ handle_rt_signal(unsigned long sig, struct k_sigaction *ka, ...@@ -363,12 +362,13 @@ handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs) static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs)
{ {
sigset_t set; sigset_t set;
struct mcontext *mcp;
if (__copy_from_user(&set, &ucp->uc_sigmask, sizeof(set))) if (__copy_from_user(&set, &ucp->uc_sigmask, sizeof(set))
|| __get_user(mcp, &ucp->uc_regs))
return -EFAULT; return -EFAULT;
restore_sigmask(&set); restore_sigmask(&set);
if (restore_user_regs(regs, mcp))
if (restore_user_regs(regs, &ucp->uc_mcontext))
return -EFAULT; return -EFAULT;
return 0; return 0;
...@@ -385,9 +385,6 @@ int sys_swapcontext(struct ucontext __user *old_ctx, ...@@ -385,9 +385,6 @@ int sys_swapcontext(struct ucontext __user *old_ctx,
|| save_user_regs(regs, &old_ctx->uc_mcontext, 0) || save_user_regs(regs, &old_ctx->uc_mcontext, 0)
|| __copy_to_user(&old_ctx->uc_sigmask, || __copy_to_user(&old_ctx->uc_sigmask,
&current->blocked, sizeof(sigset_t)) &current->blocked, sizeof(sigset_t))
/* the next 2 things aren't strictly necessary */
|| __copy_to_user(&old_ctx->uc_oldsigmask,
&current->blocked, sizeof(sigset_t))
|| __put_user(&old_ctx->uc_mcontext, &old_ctx->uc_regs)) || __put_user(&old_ctx->uc_mcontext, &old_ctx->uc_regs))
return -EFAULT; return -EFAULT;
} }
......
...@@ -79,16 +79,28 @@ extern void sort_exception_table(void); ...@@ -79,16 +79,28 @@ extern void sort_exception_table(void);
* As we use the same address space for kernel and user data on the * As we use the same address space for kernel and user data on the
* PowerPC, we can just do these as direct assignments. (Of course, the * PowerPC, we can just do these as direct assignments. (Of course, the
* exception handling means that it's no longer "just"...) * exception handling means that it's no longer "just"...)
*
* The "user64" versions of the user access functions are versions that
* allow access of 64-bit data. The "get_user" functions do not
* properly handle 64-bit data because the value gets down cast to a long.
* The "put_user" functions already handle 64-bit data properly but we add
* "user64" versions for completeness
*/ */
#define get_user(x,ptr) \ #define get_user(x,ptr) \
__get_user_check((x),(ptr),sizeof(*(ptr))) __get_user_check((x),(ptr),sizeof(*(ptr)))
#define get_user64(x,ptr) \
__get_user64_check((x),(ptr),sizeof(*(ptr)))
#define put_user(x,ptr) \ #define put_user(x,ptr) \
__put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
#define put_user64(x,ptr) put_user(x,ptr)
#define __get_user(x,ptr) \ #define __get_user(x,ptr) \
__get_user_nocheck((x),(ptr),sizeof(*(ptr))) __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
#define __get_user64(x,ptr) \
__get_user64_nocheck((x),(ptr),sizeof(*(ptr)))
#define __put_user(x,ptr) \ #define __put_user(x,ptr) \
__put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
#define __put_user64(x,ptr) __put_user(x,ptr)
extern long __put_user_bad(void); extern long __put_user_bad(void);
...@@ -168,6 +180,15 @@ struct __large_struct { unsigned long buf[100]; }; ...@@ -168,6 +180,15 @@ struct __large_struct { unsigned long buf[100]; };
__gu_err; \ __gu_err; \
}) })
#define __get_user64_nocheck(x,ptr,size) \
({ \
long __gu_err; \
long long __gu_val; \
__get_user_size64(__gu_val,(ptr),(size),__gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
#define __get_user_check(x,ptr,size) \ #define __get_user_check(x,ptr,size) \
({ \ ({ \
long __gu_err = -EFAULT, __gu_val = 0; \ long __gu_err = -EFAULT, __gu_val = 0; \
...@@ -178,6 +199,17 @@ struct __large_struct { unsigned long buf[100]; }; ...@@ -178,6 +199,17 @@ struct __large_struct { unsigned long buf[100]; };
__gu_err; \ __gu_err; \
}) })
#define __get_user64_check(x,ptr,size) \
({ \
long __gu_err = -EFAULT; \
long long __gu_val = 0; \
const __typeof__(*(ptr)) *__gu_addr = (ptr); \
if (access_ok(VERIFY_READ,__gu_addr,size)) \
__get_user_size64(__gu_val,__gu_addr,(size),__gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
extern long __get_user_bad(void); extern long __get_user_bad(void);
#define __get_user_size(x,ptr,size,retval) \ #define __get_user_size(x,ptr,size,retval) \
...@@ -187,7 +219,18 @@ do { \ ...@@ -187,7 +219,18 @@ do { \
case 1: __get_user_asm(x,ptr,retval,"lbz"); break; \ case 1: __get_user_asm(x,ptr,retval,"lbz"); break; \
case 2: __get_user_asm(x,ptr,retval,"lhz"); break; \ case 2: __get_user_asm(x,ptr,retval,"lhz"); break; \
case 4: __get_user_asm(x,ptr,retval,"lwz"); break; \ case 4: __get_user_asm(x,ptr,retval,"lwz"); break; \
case 8: __get_user_asm2(x, ptr, retval); \ default: (x) = __get_user_bad(); \
} \
} while (0)
#define __get_user_size64(x,ptr,size,retval) \
do { \
retval = 0; \
switch (size) { \
case 1: __get_user_asm(x,ptr,retval,"lbz"); break; \
case 2: __get_user_asm(x,ptr,retval,"lhz"); break; \
case 4: __get_user_asm(x,ptr,retval,"lwz"); break; \
case 8: __get_user_asm2(x, ptr, retval); break; \
default: (x) = __get_user_bad(); \ default: (x) = __get_user_bad(); \
} \ } \
} while (0) } while (0)
......
...@@ -16,12 +16,11 @@ struct ucontext { ...@@ -16,12 +16,11 @@ struct ucontext {
struct ucontext *uc_link; struct ucontext *uc_link;
stack_t uc_stack; stack_t uc_stack;
int uc_pad[7]; int uc_pad[7];
struct mcontext *uc_regs; /* backward compat */ struct mcontext *uc_regs; /* points to uc_mcontext field */
sigset_t uc_oldsigmask; /* backward compat */
int uc_pad2;
sigset_t uc_sigmask; sigset_t uc_sigmask;
/* glibc has 1024-bit signal masks, ours are 64-bit */ /* glibc has 1024-bit signal masks, ours are 64-bit */
int uc_maskext[30]; int uc_maskext[30];
int uc_pad2[3];
struct mcontext uc_mcontext; struct mcontext uc_mcontext;
}; };
......
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