diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 0abbce8c70bc7911d949ee026ab4996df343ef0e..b324dcac1c561c8564d1473a0a8113b4733f2cdc 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -57,7 +57,9 @@ int main(void)
   DEFINE(TI_TP_VALUE,		offsetof(struct thread_info, tp_value));
   DEFINE(TI_FPSTATE,		offsetof(struct thread_info, fpstate));
   DEFINE(TI_VFPSTATE,		offsetof(struct thread_info, vfpstate));
-  DEFINE(TI_IWMMXT_STATE,	(offsetof(struct thread_info, fpstate)+4)&~7);
+#ifdef CONFIG_IWMMXT
+  DEFINE(TI_IWMMXT_STATE,	offsetof(struct thread_info, fpstate.iwmmxt));
+#endif
   BLANK();
   DEFINE(S_R0,			offsetof(struct pt_regs, ARM_r0));
   DEFINE(S_R1,			offsetof(struct pt_regs, ARM_r1));
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 7b6256bb590ed4ddc90a2300ddf3d7299452c016..bc9e2f8ae3265de120f28a7939e5c24ca8d2d1d1 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -610,15 +610,12 @@ static int ptrace_setfpregs(struct task_struct *tsk, void __user *ufp)
 static int ptrace_getwmmxregs(struct task_struct *tsk, void __user *ufp)
 {
 	struct thread_info *thread = task_thread_info(tsk);
-	void *ptr = &thread->fpstate;
 
 	if (!test_ti_thread_flag(thread, TIF_USING_IWMMXT))
 		return -ENODATA;
 	iwmmxt_task_disable(thread);  /* force it to ram */
-	/* The iWMMXt state is stored doubleword-aligned.  */
-	if (((long) ptr) & 4)
-		ptr += 4;
-	return copy_to_user(ufp, ptr, 0x98) ? -EFAULT : 0;
+	return copy_to_user(ufp, &thread->fpstate.iwmmxt, IWMMXT_SIZE)
+		? -EFAULT : 0;
 }
 
 /*
@@ -627,15 +624,12 @@ static int ptrace_getwmmxregs(struct task_struct *tsk, void __user *ufp)
 static int ptrace_setwmmxregs(struct task_struct *tsk, void __user *ufp)
 {
 	struct thread_info *thread = task_thread_info(tsk);
-	void *ptr = &thread->fpstate;
 
 	if (!test_ti_thread_flag(thread, TIF_USING_IWMMXT))
 		return -EACCES;
 	iwmmxt_task_release(thread);  /* force a reload */
-	/* The iWMMXt state is stored doubleword-aligned.  */
-	if (((long) ptr) & 4)
-		ptr += 4;
-	return copy_from_user(ptr, ufp, 0x98) ? -EFAULT : 0;
+	return copy_from_user(&thead->fpstate.iwmmxt, ufp, IWMMXT_SIZE)
+		? -EFAULT : 0;
 }
 
 #endif
diff --git a/include/asm-arm/fpstate.h b/include/asm-arm/fpstate.h
index f7430e3aa55d2eb2f5601839b5d92f5da4e0da7b..6246bf83627d3c7c5304cdc47d974daec61f8702 100644
--- a/include/asm-arm/fpstate.h
+++ b/include/asm-arm/fpstate.h
@@ -55,8 +55,10 @@ struct fp_soft_struct {
 	unsigned int save[FP_SOFT_SIZE];		/* undefined information */
 };
 
+#define IWMMXT_SIZE	0x98
+
 struct iwmmxt_struct {
-	unsigned int save[0x98/sizeof(int) + 1];
+	unsigned int save[IWMMXT_SIZE / sizeof(unsigned int)];
 };
 
 union fp_state {
diff --git a/include/asm-arm/thread_info.h b/include/asm-arm/thread_info.h
index 33a33cbb63295640fc5664aa7ba69255eecbdd6f..cfbccb63c67b4df54523fa3942b2ba6b096bd09b 100644
--- a/include/asm-arm/thread_info.h
+++ b/include/asm-arm/thread_info.h
@@ -59,7 +59,7 @@ struct thread_info {
 	struct cpu_context_save	cpu_context;	/* cpu context */
 	__u8			used_cp[16];	/* thread used copro */
 	unsigned long		tp_value;
-	union fp_state		fpstate;
+	union fp_state		fpstate __attribute__((aligned(8)));
 	union vfp_state		vfpstate;
 	struct restart_block	restart_block;
 };