Browse Source

mikrotik-rb4xx: update kernel patches

* fix conflict in existing patch
* add build fix for newer binutils

Signed-off-by: Phil Sutter <phil@nwl.cc>
Phil Sutter 9 years ago
parent
commit
d50ef63b1d

+ 13 - 13
target/mips/mikrotik-rb4xx/patches/3.14.45/0018-net-allow-PHY-drivers-to-insert-packet-mangle-hooks.patch

@@ -1,4 +1,4 @@
-From ebca842041d737b7441748a17ffd535aab851fce Mon Sep 17 00:00:00 2001
+From 110f32cb37fa86ce1c6459227ba3b57df7283b85 Mon Sep 17 00:00:00 2001
 From: Phil Sutter <phil@nwl.cc>
 Date: Tue, 13 May 2014 01:32:11 +0200
 Subject: [PATCH] net: allow PHY drivers to insert packet mangle hooks
@@ -14,7 +14,7 @@ Subject: [PATCH] net: allow PHY drivers to insert packet mangle hooks
  7 files changed, 70 insertions(+), 18 deletions(-)
 
 diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
-index 911718f..8e8dd46 100644
+index bf46cc8..7d31bd6 100644
 --- a/include/linux/netdevice.h
 +++ b/include/linux/netdevice.h
 @@ -1245,6 +1245,11 @@ struct net_device {
@@ -40,10 +40,10 @@ index 911718f..8e8dd46 100644
  /*
   * Cache lines mostly used on receive path (including eth_type_trans())
 diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
-index 15ede6a..5530766 100644
+index ab31337..ecc124d 100644
 --- a/include/linux/skbuff.h
 +++ b/include/linux/skbuff.h
-@@ -1858,6 +1858,10 @@ static inline int pskb_trim(struct sk_buff *skb, unsigned int len)
+@@ -1859,6 +1859,10 @@ static inline int pskb_trim(struct sk_buff *skb, unsigned int len)
  	return (len < skb->len) ? __pskb_trim(skb, len) : 0;
  }
  
@@ -54,7 +54,7 @@ index 15ede6a..5530766 100644
  /**
   *	pskb_trim_unique - remove end from a paged unique (not cloned) buffer
   *	@skb: buffer to alter
-@@ -1966,16 +1970,6 @@ static inline struct sk_buff *dev_alloc_skb(unsigned int length)
+@@ -1967,16 +1971,6 @@ static inline struct sk_buff *dev_alloc_skb(unsigned int length)
  }
  
  
@@ -101,10 +101,10 @@ index e411046..970c52a 100644
  	bool
  	help
 diff --git a/net/core/dev.c b/net/core/dev.c
-index fccc195..2e0ba23 100644
+index 1b9e700..fb08c2a 100644
 --- a/net/core/dev.c
 +++ b/net/core/dev.c
-@@ -2607,10 +2607,20 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
+@@ -2618,10 +2618,20 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
  		if (!list_empty(&ptype_all))
  			dev_queue_xmit_nit(skb, dev);
  
@@ -129,7 +129,7 @@ index fccc195..2e0ba23 100644
  		if (rc == NETDEV_TX_OK)
  			txq_trans_update(txq);
  		return rc;
-@@ -2626,10 +2636,20 @@ gso:
+@@ -2637,10 +2647,20 @@ gso:
  		if (!list_empty(&ptype_all))
  			dev_queue_xmit_nit(nskb, dev);
  
@@ -155,18 +155,18 @@ index fccc195..2e0ba23 100644
  			if (rc & ~NETDEV_TX_MASK)
  				goto out_kfree_gso_skb;
 diff --git a/net/core/skbuff.c b/net/core/skbuff.c
-index e5ae776e..400ff2a 100644
+index 69ec61a..0299dff 100644
 --- a/net/core/skbuff.c
 +++ b/net/core/skbuff.c
-@@ -62,6 +62,7 @@
- #include <linux/scatterlist.h>
+@@ -63,6 +63,7 @@
  #include <linux/errqueue.h>
  #include <linux/prefetch.h>
+ #include <linux/if_vlan.h>
 +#include <uapi/linux/if.h>
  
  #include <net/protocol.h>
  #include <net/dst.h>
-@@ -439,6 +440,22 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
+@@ -458,6 +459,22 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
  }
  EXPORT_SYMBOL(__netdev_alloc_skb);
  
@@ -207,5 +207,5 @@ index 5dc638c..f4fd124 100644
  	skb_pull_inline(skb, ETH_HLEN);
  	eth = eth_hdr(skb);
 -- 
-1.8.5.3
+2.4.5
 

+ 474 - 0
target/mips/mikrotik-rb4xx/patches/3.14.45/0029-MIPS-Fix-build-with-binutils-2.24.51.patch

@@ -0,0 +1,474 @@
+From d339550fcb6a2048b829634612da96b186d97dfe Mon Sep 17 00:00:00 2001
+From: Manuel Lauss <manuel.lauss@gmail.com>
+Date: Fri, 7 Nov 2014 14:13:54 +0100
+Subject: [PATCH] MIPS: Fix build with binutils 2.24.51+
+
+Starting with version 2.24.51.20140728 MIPS binutils complain loudly
+about mixing soft-float and hard-float object files, leading to this
+build failure since GCC is invoked with "-msoft-float" on MIPS:
+
+{standard input}: Warning: .gnu_attribute 4,3 requires `softfloat'
+  LD      arch/mips/alchemy/common/built-in.o
+mipsel-softfloat-linux-gnu-ld: Warning: arch/mips/alchemy/common/built-in.o
+ uses -msoft-float (set by arch/mips/alchemy/common/prom.o),
+ arch/mips/alchemy/common/sleeper.o uses -mhard-float
+
+To fix this, we detect if GAS is new enough to support "-msoft-float" command
+option, and if it does, we can let GCC pass it to GAS;  but then we also need
+to sprinkle the files which make use of floating point registers with the
+necessary ".set hardfloat" directives.
+
+Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com>
+Cc: Linux-MIPS <linux-mips@linux-mips.org>
+Cc: Matthew Fortune <Matthew.Fortune@imgtec.com>
+Cc: Markos Chandras <Markos.Chandras@imgtec.com>
+Cc: Maciej W. Rozycki <macro@linux-mips.org>
+Patchwork: https://patchwork.linux-mips.org/patch/8355/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+---
+ arch/mips/Makefile                  |  9 +++++++++
+ arch/mips/include/asm/asmmacro-32.h |  6 ++++++
+ arch/mips/include/asm/asmmacro.h    |  7 +++++++
+ arch/mips/include/asm/fpregdef.h    | 14 ++++++++++++++
+ arch/mips/include/asm/mipsregs.h    | 11 ++++++++++-
+ arch/mips/kernel/branch.c           |  2 +-
+ arch/mips/kernel/genex.S            |  1 +
+ arch/mips/kernel/r2300_fpu.S        |  6 ++++++
+ arch/mips/kernel/r2300_switch.S     |  5 +++++
+ arch/mips/kernel/r4k_fpu.S          | 27 +++++++++++++++++++++++++--
+ arch/mips/kernel/r4k_switch.S       | 11 ++++++++++-
+ arch/mips/kernel/r6000_fpu.S        |  5 +++++
+ arch/mips/math-emu/cp1emu.c         |  2 +-
+ 13 files changed, 100 insertions(+), 6 deletions(-)
+
+diff --git a/arch/mips/Makefile b/arch/mips/Makefile
+index 9b8556d..20f6379 100644
+--- a/arch/mips/Makefile
++++ b/arch/mips/Makefile
+@@ -93,6 +93,15 @@ LDFLAGS_vmlinux			+= -G 0 -static -n -nostdlib
+ KBUILD_AFLAGS_MODULE		+= -mlong-calls
+ KBUILD_CFLAGS_MODULE		+= -mlong-calls
+ 
++#
++# pass -msoft-float to GAS if it supports it.  However on newer binutils
++# (specifically newer than 2.24.51.20140728) we then also need to explicitly
++# set ".set hardfloat" in all files which manipulate floating point registers.
++#
++ifneq ($(call as-option,-Wa$(comma)-msoft-float,),)
++	cflags-y		+= -DGAS_HAS_SET_HARDFLOAT -Wa,-msoft-float
++endif
++
+ cflags-y += -ffreestanding
+ 
+ #
+diff --git a/arch/mips/include/asm/asmmacro-32.h b/arch/mips/include/asm/asmmacro-32.h
+index 70e1f17..8038647 100644
+--- a/arch/mips/include/asm/asmmacro-32.h
++++ b/arch/mips/include/asm/asmmacro-32.h
+@@ -13,6 +13,8 @@
+ #include <asm/mipsregs.h>
+ 
+ 	.macro	fpu_save_single thread tmp=t0
++	.set push
++	SET_HARDFLOAT
+ 	cfc1	\tmp,  fcr31
+ 	swc1	$f0,  THREAD_FPR0(\thread)
+ 	swc1	$f1,  THREAD_FPR1(\thread)
+@@ -47,9 +49,12 @@
+ 	swc1	$f30, THREAD_FPR30(\thread)
+ 	swc1	$f31, THREAD_FPR31(\thread)
+ 	sw	\tmp, THREAD_FCR31(\thread)
++	.set pop
+ 	.endm
+ 
+ 	.macro	fpu_restore_single thread tmp=t0
++	.set push
++	SET_HARDFLOAT
+ 	lw	\tmp, THREAD_FCR31(\thread)
+ 	lwc1	$f0,  THREAD_FPR0(\thread)
+ 	lwc1	$f1,  THREAD_FPR1(\thread)
+@@ -84,6 +89,7 @@
+ 	lwc1	$f30, THREAD_FPR30(\thread)
+ 	lwc1	$f31, THREAD_FPR31(\thread)
+ 	ctc1	\tmp, fcr31
++	.set pop
+ 	.endm
+ 
+ 	.macro	cpu_save_nonscratch thread
+diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h
+index 4225e99..d6d5b19 100644
+--- a/arch/mips/include/asm/asmmacro.h
++++ b/arch/mips/include/asm/asmmacro.h
+@@ -74,6 +74,8 @@
+ #endif /* CONFIG_MIPS_MT_SMTC */
+ 
+ 	.macro	fpu_save_16even thread tmp=t0
++	.set	push
++	SET_HARDFLOAT
+ 	cfc1	\tmp, fcr31
+ 	sdc1	$f0,  THREAD_FPR0(\thread)
+ 	sdc1	$f2,  THREAD_FPR2(\thread)
+@@ -92,11 +94,13 @@
+ 	sdc1	$f28, THREAD_FPR28(\thread)
+ 	sdc1	$f30, THREAD_FPR30(\thread)
+ 	sw	\tmp, THREAD_FCR31(\thread)
++	.set	pop
+ 	.endm
+ 
+ 	.macro	fpu_save_16odd thread
+ 	.set	push
+ 	.set	mips64r2
++	SET_HARDFLOAT
+ 	sdc1	$f1,  THREAD_FPR1(\thread)
+ 	sdc1	$f3,  THREAD_FPR3(\thread)
+ 	sdc1	$f5,  THREAD_FPR5(\thread)
+@@ -127,6 +131,8 @@
+ 	.endm
+ 
+ 	.macro	fpu_restore_16even thread tmp=t0
++	.set	push
++	SET_HARDFLOAT
+ 	lw	\tmp, THREAD_FCR31(\thread)
+ 	ldc1	$f0,  THREAD_FPR0(\thread)
+ 	ldc1	$f2,  THREAD_FPR2(\thread)
+@@ -150,6 +156,7 @@
+ 	.macro	fpu_restore_16odd thread
+ 	.set	push
+ 	.set	mips64r2
++	SET_HARDFLOAT
+ 	ldc1	$f1,  THREAD_FPR1(\thread)
+ 	ldc1	$f3,  THREAD_FPR3(\thread)
+ 	ldc1	$f5,  THREAD_FPR5(\thread)
+diff --git a/arch/mips/include/asm/fpregdef.h b/arch/mips/include/asm/fpregdef.h
+index 429481f..f184ba0 100644
+--- a/arch/mips/include/asm/fpregdef.h
++++ b/arch/mips/include/asm/fpregdef.h
+@@ -14,6 +14,20 @@
+ 
+ #include <asm/sgidefs.h>
+ 
++/*
++ * starting with binutils 2.24.51.20140729, MIPS binutils warn about mixing
++ * hardfloat and softfloat object files.  The kernel build uses soft-float by
++ * default, so we also need to pass -msoft-float along to GAS if it supports it.
++ * But this in turn causes assembler errors in files which access hardfloat
++ * registers.  We detect if GAS supports "-msoft-float" in the Makefile and
++ * explicitly put ".set hardfloat" where floating point registers are touched.
++ */
++#ifdef GAS_HAS_SET_HARDFLOAT
++#define SET_HARDFLOAT .set hardfloat
++#else
++#define SET_HARDFLOAT
++#endif
++
+ #if _MIPS_SIM == _MIPS_SIM_ABI32
+ 
+ /*
+diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
+index bbc3dd4..d68ad1e 100644
+--- a/arch/mips/include/asm/mipsregs.h
++++ b/arch/mips/include/asm/mipsregs.h
+@@ -1251,7 +1251,7 @@ do {									\
+ /*
+  * Macros to access the floating point coprocessor control registers
+  */
+-#define read_32bit_cp1_register(source)					\
++#define _read_32bit_cp1_register(source, gas_hardfloat)			\
+ ({									\
+ 	int __res;							\
+ 									\
+@@ -1261,12 +1261,21 @@ do {									\
+ 	"	# gas fails to assemble cfc1 for some archs,	\n"	\
+ 	"	# like Octeon.					\n"	\
+ 	"	.set	mips1					\n"	\
++	"	"STR(gas_hardfloat)"				\n"	\
+ 	"	cfc1	%0,"STR(source)"			\n"	\
+ 	"	.set	pop					\n"	\
+ 	: "=r" (__res));						\
+ 	__res;								\
+ })
+ 
++#ifdef GAS_HAS_SET_HARDFLOAT
++#define read_32bit_cp1_register(source)					\
++	_read_32bit_cp1_register(source, .set hardfloat)
++#else
++#define read_32bit_cp1_register(source)					\
++	_read_32bit_cp1_register(source, )
++#endif
++
+ #ifdef HAVE_AS_DSP
+ #define rddsp(mask)							\
+ ({									\
+diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c
+index 4d78bf4..aa5dbd3 100644
+--- a/arch/mips/kernel/branch.c
++++ b/arch/mips/kernel/branch.c
+@@ -366,7 +366,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
+ 	case cop1_op:
+ 		preempt_disable();
+ 		if (is_fpu_owner())
+-			asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
++		        fcr31 = read_32bit_cp1_register(CP1_STATUS);
+ 		else
+ 			fcr31 = current->thread.fpu.fcr31;
+ 		preempt_enable();
+diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
+index d84f6a5..00b507f 100644
+--- a/arch/mips/kernel/genex.S
++++ b/arch/mips/kernel/genex.S
+@@ -408,6 +408,7 @@ NESTED(nmi_handler, PT_SIZE, sp)
+ 	.set	push
+ 	/* gas fails to assemble cfc1 for some archs (octeon).*/ \
+ 	.set	mips1
++	SET_HARDFLOAT
+ 	cfc1	a1, fcr31
+ 	li	a2, ~(0x3f << 12)
+ 	and	a2, a1
+diff --git a/arch/mips/kernel/r2300_fpu.S b/arch/mips/kernel/r2300_fpu.S
+index f31063d..5ce3b74 100644
+--- a/arch/mips/kernel/r2300_fpu.S
++++ b/arch/mips/kernel/r2300_fpu.S
+@@ -28,6 +28,8 @@
+ 	.set	mips1
+ 	/* Save floating point context */
+ LEAF(_save_fp_context)
++	.set	push
++	SET_HARDFLOAT
+ 	li	v0, 0					# assume success
+ 	cfc1	t1,fcr31
+ 	EX(swc1 $f0,(SC_FPREGS+0)(a0))
+@@ -65,6 +67,7 @@ LEAF(_save_fp_context)
+ 	EX(sw	t1,(SC_FPC_CSR)(a0))
+ 	cfc1	t0,$0				# implementation/version
+ 	jr	ra
++	.set	pop
+ 	.set	nomacro
+ 	 EX(sw	t0,(SC_FPC_EIR)(a0))
+ 	.set	macro
+@@ -80,6 +83,8 @@ LEAF(_save_fp_context)
+  * stack frame which might have been changed by the user.
+  */
+ LEAF(_restore_fp_context)
++	.set	push
++	SET_HARDFLOAT
+ 	li	v0, 0					# assume success
+ 	EX(lw t0,(SC_FPC_CSR)(a0))
+ 	EX(lwc1 $f0,(SC_FPREGS+0)(a0))
+@@ -116,6 +121,7 @@ LEAF(_restore_fp_context)
+ 	EX(lwc1 $f31,(SC_FPREGS+248)(a0))
+ 	jr	ra
+ 	 ctc1	t0,fcr31
++	.set	pop
+ 	END(_restore_fp_context)
+ 	.set	reorder
+ 
+diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S
+index 20b7b04..435ea65 100644
+--- a/arch/mips/kernel/r2300_switch.S
++++ b/arch/mips/kernel/r2300_switch.S
+@@ -120,6 +120,9 @@ LEAF(_restore_fp)
+ 
+ #define FPU_DEFAULT  0x00000000
+ 
++	.set push
++	SET_HARDFLOAT
++
+ LEAF(_init_fpu)
+ 	mfc0	t0, CP0_STATUS
+ 	li	t1, ST0_CU1
+@@ -165,3 +168,5 @@ LEAF(_init_fpu)
+ 	mtc1	t0, $f31
+ 	jr	ra
+ 	END(_init_fpu)
++
++	.set pop
+diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S
+index 73b0ddf..06f8b2a 100644
+--- a/arch/mips/kernel/r4k_fpu.S
++++ b/arch/mips/kernel/r4k_fpu.S
+@@ -19,8 +19,12 @@
+ #include <asm/asm-offsets.h>
+ #include <asm/regdef.h>
+ 
++/* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */
++#undef fp
++
+ 	.macro	EX insn, reg, src
+ 	.set	push
++	SET_HARDFLOAT
+ 	.set	nomacro
+ .ex\@:	\insn	\reg, \src
+ 	.set	pop
+@@ -33,12 +37,17 @@
+ 	.set	mips3
+ 
+ LEAF(_save_fp_context)
++	.set	push
++	SET_HARDFLOAT
+ 	cfc1	t1, fcr31
++	.set	pop
+ 
+ #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2)
+ 	.set	push
++	SET_HARDFLOAT
+ #ifdef CONFIG_CPU_MIPS32_R2
+-	.set	mips64r2
++	.set	mips32r2
++	.set	fp=64
+ 	mfc0	t0, CP0_STATUS
+ 	sll	t0, t0, 5
+ 	bgez	t0, 1f			# skip storing odd if FR=0
+@@ -64,6 +73,8 @@ LEAF(_save_fp_context)
+ 1:	.set	pop
+ #endif
+ 
++	.set push
++	SET_HARDFLOAT
+ 	/* Store the 16 even double precision registers */
+ 	EX	sdc1 $f0, SC_FPREGS+0(a0)
+ 	EX	sdc1 $f2, SC_FPREGS+16(a0)
+@@ -84,11 +95,14 @@ LEAF(_save_fp_context)
+ 	EX	sw t1, SC_FPC_CSR(a0)
+ 	jr	ra
+ 	 li	v0, 0					# success
++	.set pop
+ 	END(_save_fp_context)
+ 
+ #ifdef CONFIG_MIPS32_COMPAT
+ 	/* Save 32-bit process floating point context */
+ LEAF(_save_fp_context32)
++	.set push
++	SET_HARDFLOAT
+ 	cfc1	t1, fcr31
+ 
+ 	mfc0	t0, CP0_STATUS
+@@ -134,6 +148,7 @@ LEAF(_save_fp_context32)
+ 	EX	sw t1, SC32_FPC_CSR(a0)
+ 	cfc1	t0, $0				# implementation/version
+ 	EX	sw t0, SC32_FPC_EIR(a0)
++	.set pop
+ 
+ 	jr	ra
+ 	 li	v0, 0					# success
+@@ -150,8 +165,10 @@ LEAF(_restore_fp_context)
+ 
+ #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2)
+ 	.set	push
++	SET_HARDFLOAT
+ #ifdef CONFIG_CPU_MIPS32_R2
+-	.set	mips64r2
++	.set	mips32r2
++	.set	fp=64
+ 	mfc0	t0, CP0_STATUS
+ 	sll	t0, t0, 5
+ 	bgez	t0, 1f			# skip loading odd if FR=0
+@@ -175,6 +192,8 @@ LEAF(_restore_fp_context)
+ 	EX	ldc1 $f31, SC_FPREGS+248(a0)
+ 1:	.set pop
+ #endif
++	.set push
++	SET_HARDFLOAT
+ 	EX	ldc1 $f0, SC_FPREGS+0(a0)
+ 	EX	ldc1 $f2, SC_FPREGS+16(a0)
+ 	EX	ldc1 $f4, SC_FPREGS+32(a0)
+@@ -192,6 +211,7 @@ LEAF(_restore_fp_context)
+ 	EX	ldc1 $f28, SC_FPREGS+224(a0)
+ 	EX	ldc1 $f30, SC_FPREGS+240(a0)
+ 	ctc1	t1, fcr31
++	.set pop
+ 	jr	ra
+ 	 li	v0, 0					# success
+ 	END(_restore_fp_context)
+@@ -199,6 +219,8 @@ LEAF(_restore_fp_context)
+ #ifdef CONFIG_MIPS32_COMPAT
+ LEAF(_restore_fp_context32)
+ 	/* Restore an o32 sigcontext.  */
++	.set push
++	SET_HARDFLOAT
+ 	EX	lw t1, SC32_FPC_CSR(a0)
+ 
+ 	mfc0	t0, CP0_STATUS
+@@ -242,6 +264,7 @@ LEAF(_restore_fp_context32)
+ 	ctc1	t1, fcr31
+ 	jr	ra
+ 	 li	v0, 0					# success
++	.set pop
+ 	END(_restore_fp_context32)
+ #endif
+ 
+diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
+index cc78dd9..83b4f05 100644
+--- a/arch/mips/kernel/r4k_switch.S
++++ b/arch/mips/kernel/r4k_switch.S
+@@ -22,6 +22,9 @@
+ 
+ #include <asm/asmmacro.h>
+ 
++/* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */
++#undef fp
++
+ /*
+  * Offset to the current process status flags, the first 32 bytes of the
+  * stack are not used.
+@@ -151,6 +154,9 @@ LEAF(_restore_fp)
+ 
+ #define FPU_DEFAULT  0x00000000
+ 
++	.set push
++	SET_HARDFLOAT
++
+ LEAF(_init_fpu)
+ #ifdef CONFIG_MIPS_MT_SMTC
+ 	/* Rather than manipulate per-VPE Status, set per-TC bit in TCStatus */
+@@ -231,7 +237,8 @@ LEAF(_init_fpu)
+ 
+ #ifdef CONFIG_CPU_MIPS32_R2
+ 	.set    push
+-	.set    mips64r2
++	.set    mips32r2
++	.set	fp=64
+ 	sll     t0, t0, 5			# is Status.FR set?
+ 	bgez    t0, 1f				# no: skip setting upper 32b
+ 
+@@ -290,3 +297,5 @@ LEAF(_init_fpu)
+ #endif
+ 	jr	ra
+ 	END(_init_fpu)
++
++	.set pop	/* SET_HARDFLOAT */
+diff --git a/arch/mips/kernel/r6000_fpu.S b/arch/mips/kernel/r6000_fpu.S
+index da0fbe4..4707738 100644
+--- a/arch/mips/kernel/r6000_fpu.S
++++ b/arch/mips/kernel/r6000_fpu.S
+@@ -18,6 +18,9 @@
+ 
+ 	.set	noreorder
+ 	.set	mips2
++	.set	push
++	SET_HARDFLOAT
++
+ 	/* Save floating point context */
+ 	LEAF(_save_fp_context)
+ 	mfc0	t0,CP0_STATUS
+@@ -85,3 +88,5 @@
+ 1:	jr	ra
+ 	 nop
+ 	END(_restore_fp_context)
++
++	.set pop	/* SET_HARDFLOAT */
+diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
+index 0b4e2e3..c0a0914 100644
+--- a/arch/mips/math-emu/cp1emu.c
++++ b/arch/mips/math-emu/cp1emu.c
+@@ -817,7 +817,7 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
+ 		if (insn.i_format.rs == bc_op) {
+ 			preempt_disable();
+ 			if (is_fpu_owner())
+-				asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
++			        fcr31 = read_32bit_cp1_register(CP1_STATUS);
+ 			else
+ 				fcr31 = current->thread.fpu.fcr31;
+ 			preempt_enable();
+-- 
+2.4.5
+