summaryrefslogtreecommitdiff
path: root/arch/mips
diff options
context:
space:
mode:
authorPaul Burton <paul.burton@imgtec.com>2014-07-11 19:44:28 +0400
committerRalf Baechle <ralf@linux-mips.org>2014-08-02 02:06:43 +0400
commitf7a46fa7bb0047d3e226702a0c4b786862fe6843 (patch)
tree5b0ffc5e784eae55821d9fe9948e5c61b52f1f30 /arch/mips
parent558155a0a731b4f56846559a57ca7ca921230497 (diff)
downloadlinux-f7a46fa7bb0047d3e226702a0c4b786862fe6843.tar.xz
MIPS: save/restore MSACSR register on context switch
I added a field for the MSACSR register in struct mips_fpu_struct, but never actually made use of it... This is a clear bug. Save and restore the MSACSR register along with the vector registers. Signed-off-by: Paul Burton <paul.burton@imgtec.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/7300/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/include/asm/asmmacro.h11
-rw-r--r--arch/mips/kernel/asm-offsets.c1
2 files changed, 12 insertions, 0 deletions
diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h
index 935543f14538..4986bf5ffd29 100644
--- a/arch/mips/include/asm/asmmacro.h
+++ b/arch/mips/include/asm/asmmacro.h
@@ -10,6 +10,7 @@
#include <asm/hazards.h>
#include <asm/asm-offsets.h>
+#include <asm/msa.h>
#ifdef CONFIG_32BIT
#include <asm/asmmacro-32.h>
@@ -378,9 +379,19 @@
st_d 29, THREAD_FPR29, \thread
st_d 30, THREAD_FPR30, \thread
st_d 31, THREAD_FPR31, \thread
+ .set push
+ .set noat
+ cfcmsa $1, MSA_CSR
+ sw $1, THREAD_MSA_CSR(\thread)
+ .set pop
.endm
.macro msa_restore_all thread
+ .set push
+ .set noat
+ lw $1, THREAD_MSA_CSR(\thread)
+ ctcmsa MSA_CSR, $1
+ .set pop
ld_d 0, THREAD_FPR0, \thread
ld_d 1, THREAD_FPR1, \thread
ld_d 2, THREAD_FPR2, \thread
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index 4bb5107511e2..b1d84bd4efb3 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -234,6 +234,7 @@ void output_thread_fpu_defines(void)
thread.fpu.fpr[31].val64[FPR_IDX(64, 0)]);
OFFSET(THREAD_FCR31, task_struct, thread.fpu.fcr31);
+ OFFSET(THREAD_MSA_CSR, task_struct, thread.fpu.msacsr);
BLANK();
}