s390/ptrace: remove opencoded offsetof
Remove opencoded offsetof and use offsetof instead. The generated code is identical before/after this change. Reviewed-by: Sven Schnelle <svens@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
This commit is contained in:
parent
4851d22622
commit
96f6641a6a
|
@ -147,38 +147,36 @@ void ptrace_disable(struct task_struct *task)
|
|||
static inline unsigned long __peek_user_per(struct task_struct *child,
|
||||
addr_t addr)
|
||||
{
|
||||
struct per_struct_kernel *dummy = NULL;
|
||||
|
||||
if (addr == (addr_t) &dummy->cr9)
|
||||
if (addr == offsetof(struct per_struct_kernel, cr9))
|
||||
/* Control bits of the active per set. */
|
||||
return test_thread_flag(TIF_SINGLE_STEP) ?
|
||||
PER_EVENT_IFETCH : child->thread.per_user.control;
|
||||
else if (addr == (addr_t) &dummy->cr10)
|
||||
else if (addr == offsetof(struct per_struct_kernel, cr10))
|
||||
/* Start address of the active per set. */
|
||||
return test_thread_flag(TIF_SINGLE_STEP) ?
|
||||
0 : child->thread.per_user.start;
|
||||
else if (addr == (addr_t) &dummy->cr11)
|
||||
else if (addr == offsetof(struct per_struct_kernel, cr11))
|
||||
/* End address of the active per set. */
|
||||
return test_thread_flag(TIF_SINGLE_STEP) ?
|
||||
-1UL : child->thread.per_user.end;
|
||||
else if (addr == (addr_t) &dummy->bits)
|
||||
else if (addr == offsetof(struct per_struct_kernel, bits))
|
||||
/* Single-step bit. */
|
||||
return test_thread_flag(TIF_SINGLE_STEP) ?
|
||||
(1UL << (BITS_PER_LONG - 1)) : 0;
|
||||
else if (addr == (addr_t) &dummy->starting_addr)
|
||||
else if (addr == offsetof(struct per_struct_kernel, starting_addr))
|
||||
/* Start address of the user specified per set. */
|
||||
return child->thread.per_user.start;
|
||||
else if (addr == (addr_t) &dummy->ending_addr)
|
||||
else if (addr == offsetof(struct per_struct_kernel, ending_addr))
|
||||
/* End address of the user specified per set. */
|
||||
return child->thread.per_user.end;
|
||||
else if (addr == (addr_t) &dummy->perc_atmid)
|
||||
else if (addr == offsetof(struct per_struct_kernel, perc_atmid))
|
||||
/* PER code, ATMID and AI of the last PER trap */
|
||||
return (unsigned long)
|
||||
child->thread.per_event.cause << (BITS_PER_LONG - 16);
|
||||
else if (addr == (addr_t) &dummy->address)
|
||||
else if (addr == offsetof(struct per_struct_kernel, address))
|
||||
/* Address of the last PER trap */
|
||||
return child->thread.per_event.address;
|
||||
else if (addr == (addr_t) &dummy->access_id)
|
||||
else if (addr == offsetof(struct per_struct_kernel, access_id))
|
||||
/* Access id of the last PER trap */
|
||||
return (unsigned long)
|
||||
child->thread.per_event.paid << (BITS_PER_LONG - 8);
|
||||
|
@ -196,61 +194,60 @@ static inline unsigned long __peek_user_per(struct task_struct *child,
|
|||
*/
|
||||
static unsigned long __peek_user(struct task_struct *child, addr_t addr)
|
||||
{
|
||||
struct user *dummy = NULL;
|
||||
addr_t offset, tmp;
|
||||
|
||||
if (addr < (addr_t) &dummy->regs.acrs) {
|
||||
if (addr < offsetof(struct user, regs.acrs)) {
|
||||
/*
|
||||
* psw and gprs are stored on the stack
|
||||
*/
|
||||
tmp = *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr);
|
||||
if (addr == (addr_t) &dummy->regs.psw.mask) {
|
||||
if (addr == offsetof(struct user, regs.psw.mask)) {
|
||||
/* Return a clean psw mask. */
|
||||
tmp &= PSW_MASK_USER | PSW_MASK_RI;
|
||||
tmp |= PSW_USER_BITS;
|
||||
}
|
||||
|
||||
} else if (addr < (addr_t) &dummy->regs.orig_gpr2) {
|
||||
} else if (addr < offsetof(struct user, regs.orig_gpr2)) {
|
||||
/*
|
||||
* access registers are stored in the thread structure
|
||||
*/
|
||||
offset = addr - (addr_t) &dummy->regs.acrs;
|
||||
offset = addr - offsetof(struct user, regs.acrs);
|
||||
/*
|
||||
* Very special case: old & broken 64 bit gdb reading
|
||||
* from acrs[15]. Result is a 64 bit value. Read the
|
||||
* 32 bit acrs[15] value and shift it by 32. Sick...
|
||||
*/
|
||||
if (addr == (addr_t) &dummy->regs.acrs[15])
|
||||
if (addr == offsetof(struct user, regs.acrs[15]))
|
||||
tmp = ((unsigned long) child->thread.acrs[15]) << 32;
|
||||
else
|
||||
tmp = *(addr_t *)((addr_t) &child->thread.acrs + offset);
|
||||
|
||||
} else if (addr == (addr_t) &dummy->regs.orig_gpr2) {
|
||||
} else if (addr == offsetof(struct user, regs.orig_gpr2)) {
|
||||
/*
|
||||
* orig_gpr2 is stored on the kernel stack
|
||||
*/
|
||||
tmp = (addr_t) task_pt_regs(child)->orig_gpr2;
|
||||
|
||||
} else if (addr < (addr_t) &dummy->regs.fp_regs) {
|
||||
} else if (addr < offsetof(struct user, regs.fp_regs)) {
|
||||
/*
|
||||
* prevent reads of padding hole between
|
||||
* orig_gpr2 and fp_regs on s390.
|
||||
*/
|
||||
tmp = 0;
|
||||
|
||||
} else if (addr == (addr_t) &dummy->regs.fp_regs.fpc) {
|
||||
} else if (addr == offsetof(struct user, regs.fp_regs.fpc)) {
|
||||
/*
|
||||
* floating point control reg. is in the thread structure
|
||||
*/
|
||||
tmp = child->thread.fpu.fpc;
|
||||
tmp <<= BITS_PER_LONG - 32;
|
||||
|
||||
} else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
|
||||
} else if (addr < offsetof(struct user, regs.fp_regs) + sizeof(s390_fp_regs)) {
|
||||
/*
|
||||
* floating point regs. are either in child->thread.fpu
|
||||
* or the child->thread.fpu.vxrs array
|
||||
*/
|
||||
offset = addr - (addr_t) &dummy->regs.fp_regs.fprs;
|
||||
offset = addr - offsetof(struct user, regs.fp_regs.fprs);
|
||||
if (MACHINE_HAS_VX)
|
||||
tmp = *(addr_t *)
|
||||
((addr_t) child->thread.fpu.vxrs + 2*offset);
|
||||
|
@ -258,11 +255,11 @@ static unsigned long __peek_user(struct task_struct *child, addr_t addr)
|
|||
tmp = *(addr_t *)
|
||||
((addr_t) child->thread.fpu.fprs + offset);
|
||||
|
||||
} else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
|
||||
} else if (addr < offsetof(struct user, regs.per_info) + sizeof(per_struct)) {
|
||||
/*
|
||||
* Handle access to the per_info structure.
|
||||
*/
|
||||
addr -= (addr_t) &dummy->regs.per_info;
|
||||
addr -= offsetof(struct user, regs.per_info);
|
||||
tmp = __peek_user_per(child, addr);
|
||||
|
||||
} else
|
||||
|
@ -281,8 +278,8 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data)
|
|||
* an alignment of 4. Programmers from hell...
|
||||
*/
|
||||
mask = __ADDR_MASK;
|
||||
if (addr >= (addr_t) &((struct user *) NULL)->regs.acrs &&
|
||||
addr < (addr_t) &((struct user *) NULL)->regs.orig_gpr2)
|
||||
if (addr >= offsetof(struct user, regs.acrs) &&
|
||||
addr < offsetof(struct user, regs.orig_gpr2))
|
||||
mask = 3;
|
||||
if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK)
|
||||
return -EIO;
|
||||
|
@ -294,8 +291,6 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data)
|
|||
static inline void __poke_user_per(struct task_struct *child,
|
||||
addr_t addr, addr_t data)
|
||||
{
|
||||
struct per_struct_kernel *dummy = NULL;
|
||||
|
||||
/*
|
||||
* There are only three fields in the per_info struct that the
|
||||
* debugger user can write to.
|
||||
|
@ -308,14 +303,14 @@ static inline void __poke_user_per(struct task_struct *child,
|
|||
* addresses are used only if single stepping is not in effect.
|
||||
* Writes to any other field in per_info are ignored.
|
||||
*/
|
||||
if (addr == (addr_t) &dummy->cr9)
|
||||
if (addr == offsetof(struct per_struct_kernel, cr9))
|
||||
/* PER event mask of the user specified per set. */
|
||||
child->thread.per_user.control =
|
||||
data & (PER_EVENT_MASK | PER_CONTROL_MASK);
|
||||
else if (addr == (addr_t) &dummy->starting_addr)
|
||||
else if (addr == offsetof(struct per_struct_kernel, starting_addr))
|
||||
/* Starting address of the user specified per set. */
|
||||
child->thread.per_user.start = data;
|
||||
else if (addr == (addr_t) &dummy->ending_addr)
|
||||
else if (addr == offsetof(struct per_struct_kernel, ending_addr))
|
||||
/* Ending address of the user specified per set. */
|
||||
child->thread.per_user.end = data;
|
||||
}
|
||||
|
@ -328,16 +323,15 @@ static inline void __poke_user_per(struct task_struct *child,
|
|||
*/
|
||||
static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
|
||||
{
|
||||
struct user *dummy = NULL;
|
||||
addr_t offset;
|
||||
|
||||
|
||||
if (addr < (addr_t) &dummy->regs.acrs) {
|
||||
if (addr < offsetof(struct user, regs.acrs)) {
|
||||
struct pt_regs *regs = task_pt_regs(child);
|
||||
/*
|
||||
* psw and gprs are stored on the stack
|
||||
*/
|
||||
if (addr == (addr_t) &dummy->regs.psw.mask) {
|
||||
if (addr == offsetof(struct user, regs.psw.mask)) {
|
||||
unsigned long mask = PSW_MASK_USER;
|
||||
|
||||
mask |= is_ri_task(child) ? PSW_MASK_RI : 0;
|
||||
|
@ -359,36 +353,36 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
|
|||
regs->int_code = 0x20000 | (data & 0xffff);
|
||||
}
|
||||
*(addr_t *)((addr_t) ®s->psw + addr) = data;
|
||||
} else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) {
|
||||
} else if (addr < offsetof(struct user, regs.orig_gpr2)) {
|
||||
/*
|
||||
* access registers are stored in the thread structure
|
||||
*/
|
||||
offset = addr - (addr_t) &dummy->regs.acrs;
|
||||
offset = addr - offsetof(struct user, regs.acrs);
|
||||
/*
|
||||
* Very special case: old & broken 64 bit gdb writing
|
||||
* to acrs[15] with a 64 bit value. Ignore the lower
|
||||
* half of the value and write the upper 32 bit to
|
||||
* acrs[15]. Sick...
|
||||
*/
|
||||
if (addr == (addr_t) &dummy->regs.acrs[15])
|
||||
if (addr == offsetof(struct user, regs.acrs[15]))
|
||||
child->thread.acrs[15] = (unsigned int) (data >> 32);
|
||||
else
|
||||
*(addr_t *)((addr_t) &child->thread.acrs + offset) = data;
|
||||
|
||||
} else if (addr == (addr_t) &dummy->regs.orig_gpr2) {
|
||||
} else if (addr == offsetof(struct user, regs.orig_gpr2)) {
|
||||
/*
|
||||
* orig_gpr2 is stored on the kernel stack
|
||||
*/
|
||||
task_pt_regs(child)->orig_gpr2 = data;
|
||||
|
||||
} else if (addr < (addr_t) &dummy->regs.fp_regs) {
|
||||
} else if (addr < offsetof(struct user, regs.fp_regs)) {
|
||||
/*
|
||||
* prevent writes of padding hole between
|
||||
* orig_gpr2 and fp_regs on s390.
|
||||
*/
|
||||
return 0;
|
||||
|
||||
} else if (addr == (addr_t) &dummy->regs.fp_regs.fpc) {
|
||||
} else if (addr == offsetof(struct user, regs.fp_regs.fpc)) {
|
||||
/*
|
||||
* floating point control reg. is in the thread structure
|
||||
*/
|
||||
|
@ -397,12 +391,12 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
|
|||
return -EINVAL;
|
||||
child->thread.fpu.fpc = data >> (BITS_PER_LONG - 32);
|
||||
|
||||
} else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
|
||||
} else if (addr < offsetof(struct user, regs.fp_regs) + sizeof(s390_fp_regs)) {
|
||||
/*
|
||||
* floating point regs. are either in child->thread.fpu
|
||||
* or the child->thread.fpu.vxrs array
|
||||
*/
|
||||
offset = addr - (addr_t) &dummy->regs.fp_regs.fprs;
|
||||
offset = addr - offsetof(struct user, regs.fp_regs.fprs);
|
||||
if (MACHINE_HAS_VX)
|
||||
*(addr_t *)((addr_t)
|
||||
child->thread.fpu.vxrs + 2*offset) = data;
|
||||
|
@ -410,11 +404,11 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
|
|||
*(addr_t *)((addr_t)
|
||||
child->thread.fpu.fprs + offset) = data;
|
||||
|
||||
} else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
|
||||
} else if (addr < offsetof(struct user, regs.per_info) + sizeof(per_struct)) {
|
||||
/*
|
||||
* Handle access to the per_info structure.
|
||||
*/
|
||||
addr -= (addr_t) &dummy->regs.per_info;
|
||||
addr -= offsetof(struct user, regs.per_info);
|
||||
__poke_user_per(child, addr, data);
|
||||
|
||||
}
|
||||
|
@ -431,8 +425,8 @@ static int poke_user(struct task_struct *child, addr_t addr, addr_t data)
|
|||
* an alignment of 4. Programmers from hell indeed...
|
||||
*/
|
||||
mask = __ADDR_MASK;
|
||||
if (addr >= (addr_t) &((struct user *) NULL)->regs.acrs &&
|
||||
addr < (addr_t) &((struct user *) NULL)->regs.orig_gpr2)
|
||||
if (addr >= offsetof(struct user, regs.acrs) &&
|
||||
addr < offsetof(struct user, regs.orig_gpr2))
|
||||
mask = 3;
|
||||
if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK)
|
||||
return -EIO;
|
||||
|
@ -540,37 +534,35 @@ long arch_ptrace(struct task_struct *child, long request,
|
|||
static inline __u32 __peek_user_per_compat(struct task_struct *child,
|
||||
addr_t addr)
|
||||
{
|
||||
struct compat_per_struct_kernel *dummy32 = NULL;
|
||||
|
||||
if (addr == (addr_t) &dummy32->cr9)
|
||||
if (addr == offsetof(struct compat_per_struct_kernel, cr9))
|
||||
/* Control bits of the active per set. */
|
||||
return (__u32) test_thread_flag(TIF_SINGLE_STEP) ?
|
||||
PER_EVENT_IFETCH : child->thread.per_user.control;
|
||||
else if (addr == (addr_t) &dummy32->cr10)
|
||||
else if (addr == offsetof(struct compat_per_struct_kernel, cr10))
|
||||
/* Start address of the active per set. */
|
||||
return (__u32) test_thread_flag(TIF_SINGLE_STEP) ?
|
||||
0 : child->thread.per_user.start;
|
||||
else if (addr == (addr_t) &dummy32->cr11)
|
||||
else if (addr == offsetof(struct compat_per_struct_kernel, cr11))
|
||||
/* End address of the active per set. */
|
||||
return test_thread_flag(TIF_SINGLE_STEP) ?
|
||||
PSW32_ADDR_INSN : child->thread.per_user.end;
|
||||
else if (addr == (addr_t) &dummy32->bits)
|
||||
else if (addr == offsetof(struct compat_per_struct_kernel, bits))
|
||||
/* Single-step bit. */
|
||||
return (__u32) test_thread_flag(TIF_SINGLE_STEP) ?
|
||||
0x80000000 : 0;
|
||||
else if (addr == (addr_t) &dummy32->starting_addr)
|
||||
else if (addr == offsetof(struct compat_per_struct_kernel, starting_addr))
|
||||
/* Start address of the user specified per set. */
|
||||
return (__u32) child->thread.per_user.start;
|
||||
else if (addr == (addr_t) &dummy32->ending_addr)
|
||||
else if (addr == offsetof(struct compat_per_struct_kernel, ending_addr))
|
||||
/* End address of the user specified per set. */
|
||||
return (__u32) child->thread.per_user.end;
|
||||
else if (addr == (addr_t) &dummy32->perc_atmid)
|
||||
else if (addr == offsetof(struct compat_per_struct_kernel, perc_atmid))
|
||||
/* PER code, ATMID and AI of the last PER trap */
|
||||
return (__u32) child->thread.per_event.cause << 16;
|
||||
else if (addr == (addr_t) &dummy32->address)
|
||||
else if (addr == offsetof(struct compat_per_struct_kernel, address))
|
||||
/* Address of the last PER trap */
|
||||
return (__u32) child->thread.per_event.address;
|
||||
else if (addr == (addr_t) &dummy32->access_id)
|
||||
else if (addr == offsetof(struct compat_per_struct_kernel, access_id))
|
||||
/* Access id of the last PER trap */
|
||||
return (__u32) child->thread.per_event.paid << 24;
|
||||
return 0;
|
||||
|
@ -581,21 +573,20 @@ static inline __u32 __peek_user_per_compat(struct task_struct *child,
|
|||
*/
|
||||
static u32 __peek_user_compat(struct task_struct *child, addr_t addr)
|
||||
{
|
||||
struct compat_user *dummy32 = NULL;
|
||||
addr_t offset;
|
||||
__u32 tmp;
|
||||
|
||||
if (addr < (addr_t) &dummy32->regs.acrs) {
|
||||
if (addr < offsetof(struct compat_user, regs.acrs)) {
|
||||
struct pt_regs *regs = task_pt_regs(child);
|
||||
/*
|
||||
* psw and gprs are stored on the stack
|
||||
*/
|
||||
if (addr == (addr_t) &dummy32->regs.psw.mask) {
|
||||
if (addr == offsetof(struct compat_user, regs.psw.mask)) {
|
||||
/* Fake a 31 bit psw mask. */
|
||||
tmp = (__u32)(regs->psw.mask >> 32);
|
||||
tmp &= PSW32_MASK_USER | PSW32_MASK_RI;
|
||||
tmp |= PSW32_USER_BITS;
|
||||
} else if (addr == (addr_t) &dummy32->regs.psw.addr) {
|
||||
} else if (addr == offsetof(struct compat_user, regs.psw.addr)) {
|
||||
/* Fake a 31 bit psw address. */
|
||||
tmp = (__u32) regs->psw.addr |
|
||||
(__u32)(regs->psw.mask & PSW_MASK_BA);
|
||||
|
@ -603,38 +594,38 @@ static u32 __peek_user_compat(struct task_struct *child, addr_t addr)
|
|||
/* gpr 0-15 */
|
||||
tmp = *(__u32 *)((addr_t) ®s->psw + addr*2 + 4);
|
||||
}
|
||||
} else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {
|
||||
} else if (addr < offsetof(struct compat_user, regs.orig_gpr2)) {
|
||||
/*
|
||||
* access registers are stored in the thread structure
|
||||
*/
|
||||
offset = addr - (addr_t) &dummy32->regs.acrs;
|
||||
offset = addr - offsetof(struct compat_user, regs.acrs);
|
||||
tmp = *(__u32*)((addr_t) &child->thread.acrs + offset);
|
||||
|
||||
} else if (addr == (addr_t) (&dummy32->regs.orig_gpr2)) {
|
||||
} else if (addr == offsetof(struct compat_user, regs.orig_gpr2)) {
|
||||
/*
|
||||
* orig_gpr2 is stored on the kernel stack
|
||||
*/
|
||||
tmp = *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4);
|
||||
|
||||
} else if (addr < (addr_t) &dummy32->regs.fp_regs) {
|
||||
} else if (addr < offsetof(struct compat_user, regs.fp_regs)) {
|
||||
/*
|
||||
* prevent reads of padding hole between
|
||||
* orig_gpr2 and fp_regs on s390.
|
||||
*/
|
||||
tmp = 0;
|
||||
|
||||
} else if (addr == (addr_t) &dummy32->regs.fp_regs.fpc) {
|
||||
} else if (addr == offsetof(struct compat_user, regs.fp_regs.fpc)) {
|
||||
/*
|
||||
* floating point control reg. is in the thread structure
|
||||
*/
|
||||
tmp = child->thread.fpu.fpc;
|
||||
|
||||
} else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
|
||||
} else if (addr < offsetof(struct compat_user, regs.fp_regs) + sizeof(s390_fp_regs)) {
|
||||
/*
|
||||
* floating point regs. are either in child->thread.fpu
|
||||
* or the child->thread.fpu.vxrs array
|
||||
*/
|
||||
offset = addr - (addr_t) &dummy32->regs.fp_regs.fprs;
|
||||
offset = addr - offsetof(struct compat_user, regs.fp_regs.fprs);
|
||||
if (MACHINE_HAS_VX)
|
||||
tmp = *(__u32 *)
|
||||
((addr_t) child->thread.fpu.vxrs + 2*offset);
|
||||
|
@ -642,11 +633,11 @@ static u32 __peek_user_compat(struct task_struct *child, addr_t addr)
|
|||
tmp = *(__u32 *)
|
||||
((addr_t) child->thread.fpu.fprs + offset);
|
||||
|
||||
} else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) {
|
||||
} else if (addr < offsetof(struct compat_user, regs.per_info) + sizeof(struct compat_per_struct_kernel)) {
|
||||
/*
|
||||
* Handle access to the per_info structure.
|
||||
*/
|
||||
addr -= (addr_t) &dummy32->regs.per_info;
|
||||
addr -= offsetof(struct compat_user, regs.per_info);
|
||||
tmp = __peek_user_per_compat(child, addr);
|
||||
|
||||
} else
|
||||
|
@ -673,16 +664,14 @@ static int peek_user_compat(struct task_struct *child,
|
|||
static inline void __poke_user_per_compat(struct task_struct *child,
|
||||
addr_t addr, __u32 data)
|
||||
{
|
||||
struct compat_per_struct_kernel *dummy32 = NULL;
|
||||
|
||||
if (addr == (addr_t) &dummy32->cr9)
|
||||
if (addr == offsetof(struct compat_per_struct_kernel, cr9))
|
||||
/* PER event mask of the user specified per set. */
|
||||
child->thread.per_user.control =
|
||||
data & (PER_EVENT_MASK | PER_CONTROL_MASK);
|
||||
else if (addr == (addr_t) &dummy32->starting_addr)
|
||||
else if (addr == offsetof(struct compat_per_struct_kernel, starting_addr))
|
||||
/* Starting address of the user specified per set. */
|
||||
child->thread.per_user.start = data;
|
||||
else if (addr == (addr_t) &dummy32->ending_addr)
|
||||
else if (addr == offsetof(struct compat_per_struct_kernel, ending_addr))
|
||||
/* Ending address of the user specified per set. */
|
||||
child->thread.per_user.end = data;
|
||||
}
|
||||
|
@ -693,16 +682,15 @@ static inline void __poke_user_per_compat(struct task_struct *child,
|
|||
static int __poke_user_compat(struct task_struct *child,
|
||||
addr_t addr, addr_t data)
|
||||
{
|
||||
struct compat_user *dummy32 = NULL;
|
||||
__u32 tmp = (__u32) data;
|
||||
addr_t offset;
|
||||
|
||||
if (addr < (addr_t) &dummy32->regs.acrs) {
|
||||
if (addr < offsetof(struct compat_user, regs.acrs)) {
|
||||
struct pt_regs *regs = task_pt_regs(child);
|
||||
/*
|
||||
* psw, gprs, acrs and orig_gpr2 are stored on the stack
|
||||
*/
|
||||
if (addr == (addr_t) &dummy32->regs.psw.mask) {
|
||||
if (addr == offsetof(struct compat_user, regs.psw.mask)) {
|
||||
__u32 mask = PSW32_MASK_USER;
|
||||
|
||||
mask |= is_ri_task(child) ? PSW32_MASK_RI : 0;
|
||||
|
@ -716,7 +704,7 @@ static int __poke_user_compat(struct task_struct *child,
|
|||
regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
|
||||
(regs->psw.mask & PSW_MASK_BA) |
|
||||
(__u64)(tmp & mask) << 32;
|
||||
} else if (addr == (addr_t) &dummy32->regs.psw.addr) {
|
||||
} else if (addr == offsetof(struct compat_user, regs.psw.addr)) {
|
||||
/* Build a 64 bit psw address from 31 bit address. */
|
||||
regs->psw.addr = (__u64) tmp & PSW32_ADDR_INSN;
|
||||
/* Transfer 31 bit amode bit to psw mask. */
|
||||
|
@ -732,27 +720,27 @@ static int __poke_user_compat(struct task_struct *child,
|
|||
/* gpr 0-15 */
|
||||
*(__u32*)((addr_t) ®s->psw + addr*2 + 4) = tmp;
|
||||
}
|
||||
} else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {
|
||||
} else if (addr < offsetof(struct compat_user, regs.orig_gpr2)) {
|
||||
/*
|
||||
* access registers are stored in the thread structure
|
||||
*/
|
||||
offset = addr - (addr_t) &dummy32->regs.acrs;
|
||||
offset = addr - offsetof(struct compat_user, regs.acrs);
|
||||
*(__u32*)((addr_t) &child->thread.acrs + offset) = tmp;
|
||||
|
||||
} else if (addr == (addr_t) (&dummy32->regs.orig_gpr2)) {
|
||||
} else if (addr == offsetof(struct compat_user, regs.orig_gpr2)) {
|
||||
/*
|
||||
* orig_gpr2 is stored on the kernel stack
|
||||
*/
|
||||
*(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4) = tmp;
|
||||
|
||||
} else if (addr < (addr_t) &dummy32->regs.fp_regs) {
|
||||
} else if (addr < offsetof(struct compat_user, regs.fp_regs)) {
|
||||
/*
|
||||
* prevent writess of padding hole between
|
||||
* orig_gpr2 and fp_regs on s390.
|
||||
*/
|
||||
return 0;
|
||||
|
||||
} else if (addr == (addr_t) &dummy32->regs.fp_regs.fpc) {
|
||||
} else if (addr == offsetof(struct compat_user, regs.fp_regs.fpc)) {
|
||||
/*
|
||||
* floating point control reg. is in the thread structure
|
||||
*/
|
||||
|
@ -760,12 +748,12 @@ static int __poke_user_compat(struct task_struct *child,
|
|||
return -EINVAL;
|
||||
child->thread.fpu.fpc = data;
|
||||
|
||||
} else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
|
||||
} else if (addr < offsetof(struct compat_user, regs.fp_regs) + sizeof(s390_fp_regs)) {
|
||||
/*
|
||||
* floating point regs. are either in child->thread.fpu
|
||||
* or the child->thread.fpu.vxrs array
|
||||
*/
|
||||
offset = addr - (addr_t) &dummy32->regs.fp_regs.fprs;
|
||||
offset = addr - offsetof(struct compat_user, regs.fp_regs.fprs);
|
||||
if (MACHINE_HAS_VX)
|
||||
*(__u32 *)((addr_t)
|
||||
child->thread.fpu.vxrs + 2*offset) = tmp;
|
||||
|
@ -773,11 +761,11 @@ static int __poke_user_compat(struct task_struct *child,
|
|||
*(__u32 *)((addr_t)
|
||||
child->thread.fpu.fprs + offset) = tmp;
|
||||
|
||||
} else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) {
|
||||
} else if (addr < offsetof(struct compat_user, regs.per_info) + sizeof(struct compat_per_struct_kernel)) {
|
||||
/*
|
||||
* Handle access to the per_info structure.
|
||||
*/
|
||||
addr -= (addr_t) &dummy32->regs.per_info;
|
||||
addr -= offsetof(struct compat_user, regs.per_info);
|
||||
__poke_user_per_compat(child, addr, data);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue