s390/ptrace: remove opencoded offsetof
authorHeiko Carstens <hca@linux.ibm.com>
Thu, 17 Feb 2022 14:46:01 +0000 (15:46 +0100)
committerVasily Gorbik <gor@linux.ibm.com>
Tue, 1 Mar 2022 20:05:10 +0000 (21:05 +0100)
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>
arch/s390/kernel/ptrace.c

index 0ea3d02..ed34395 100644 (file)
@@ -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) &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
                 */
-               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) &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
                 */
-               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) &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
                 */
-               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);
        }