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

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
Loading
Loading
Loading
Loading
+76 −88
Original line number Diff line number Diff line
@@ -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);
	}