diff options
author | Paul Mackerras <paulus@samba.org> | 2013-09-10 06:20:42 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2013-10-11 02:26:49 -0400 |
commit | de79f7b9f6f92ec1bd6f61fa1f20de60728a5b5e (patch) | |
tree | 452b24060a36bf7c57a3a484c6ff981539259ea2 /arch/powerpc/kernel/traps.c | |
parent | 8e0a1611cb891e72a9affc4a8ee4795c634896a6 (diff) |
powerpc: Put FP/VSX and VR state into structures
This creates new 'thread_fp_state' and 'thread_vr_state' structures
to store FP/VSX state (including FPSCR) and Altivec/VSX state
(including VSCR), and uses them in the thread_struct. In the
thread_fp_state, the FPRs and VSRs are represented as u64 rather
than double, since we rarely perform floating-point computations
on the values, and this will enable the structures to be used
in KVM code as well. Similarly FPSCR is now a u64 rather than
a structure of two 32-bit values.
This takes the offsets out of the macros such as SAVE_32FPRS,
REST_32FPRS, etc. This enables the same macros to be used for normal
and transactional state, enabling us to delete the transactional
versions of the macros. This also removes the unused do_load_up_fpu
and do_load_up_altivec, which were in fact buggy since they didn't
create large enough stack frames to account for the fact that
load_up_fpu and load_up_altivec are not designed to be called from C
and assume that their caller's stack frame is an interrupt frame.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/traps.c')
-rw-r--r-- | arch/powerpc/kernel/traps.c | 10 |
1 files changed, 3 insertions, 7 deletions
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index f783c932faeb..f0a6814007a5 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -816,7 +816,7 @@ static void parse_fpe(struct pt_regs *regs) | |||
816 | 816 | ||
817 | flush_fp_to_thread(current); | 817 | flush_fp_to_thread(current); |
818 | 818 | ||
819 | code = __parse_fpscr(current->thread.fpscr.val); | 819 | code = __parse_fpscr(current->thread.fp_state.fpscr); |
820 | 820 | ||
821 | _exception(SIGFPE, regs, code, regs->nip); | 821 | _exception(SIGFPE, regs, code, regs->nip); |
822 | } | 822 | } |
@@ -1069,7 +1069,7 @@ static int emulate_math(struct pt_regs *regs) | |||
1069 | return 0; | 1069 | return 0; |
1070 | case 1: { | 1070 | case 1: { |
1071 | int code = 0; | 1071 | int code = 0; |
1072 | code = __parse_fpscr(current->thread.fpscr.val); | 1072 | code = __parse_fpscr(current->thread.fp_state.fpscr); |
1073 | _exception(SIGFPE, regs, code, regs->nip); | 1073 | _exception(SIGFPE, regs, code, regs->nip); |
1074 | return 0; | 1074 | return 0; |
1075 | } | 1075 | } |
@@ -1371,8 +1371,6 @@ void facility_unavailable_exception(struct pt_regs *regs) | |||
1371 | 1371 | ||
1372 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 1372 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
1373 | 1373 | ||
1374 | extern void do_load_up_fpu(struct pt_regs *regs); | ||
1375 | |||
1376 | void fp_unavailable_tm(struct pt_regs *regs) | 1374 | void fp_unavailable_tm(struct pt_regs *regs) |
1377 | { | 1375 | { |
1378 | /* Note: This does not handle any kind of FP laziness. */ | 1376 | /* Note: This does not handle any kind of FP laziness. */ |
@@ -1403,8 +1401,6 @@ void fp_unavailable_tm(struct pt_regs *regs) | |||
1403 | } | 1401 | } |
1404 | 1402 | ||
1405 | #ifdef CONFIG_ALTIVEC | 1403 | #ifdef CONFIG_ALTIVEC |
1406 | extern void do_load_up_altivec(struct pt_regs *regs); | ||
1407 | |||
1408 | void altivec_unavailable_tm(struct pt_regs *regs) | 1404 | void altivec_unavailable_tm(struct pt_regs *regs) |
1409 | { | 1405 | { |
1410 | /* See the comments in fp_unavailable_tm(). This function operates | 1406 | /* See the comments in fp_unavailable_tm(). This function operates |
@@ -1634,7 +1630,7 @@ void altivec_assist_exception(struct pt_regs *regs) | |||
1634 | /* XXX quick hack for now: set the non-Java bit in the VSCR */ | 1630 | /* XXX quick hack for now: set the non-Java bit in the VSCR */ |
1635 | printk_ratelimited(KERN_ERR "Unrecognized altivec instruction " | 1631 | printk_ratelimited(KERN_ERR "Unrecognized altivec instruction " |
1636 | "in %s at %lx\n", current->comm, regs->nip); | 1632 | "in %s at %lx\n", current->comm, regs->nip); |
1637 | current->thread.vscr.u[3] |= 0x10000; | 1633 | current->thread.vr_state.vscr.u[3] |= 0x10000; |
1638 | } | 1634 | } |
1639 | } | 1635 | } |
1640 | #endif /* CONFIG_ALTIVEC */ | 1636 | #endif /* CONFIG_ALTIVEC */ |