Commit 96f6641a authored by Heiko Carstens's avatar Heiko Carstens Committed by Vasily Gorbik

s390/ptrace: remove opencoded offsetof

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