summaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/traps.c
diff options
context:
space:
mode:
authorHendrik Brueckner <brueckner@linux.vnet.ibm.com>2015-06-11 15:33:54 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2015-07-22 09:58:00 +0200
commit904818e2f229f3d94ec95f6932a6358c81e73d78 (patch)
tree8e08f576b000b18b181b617cd0d12a6649a26556 /arch/s390/kernel/traps.c
parents390/kvm: validate the floating-point control before restoring it (diff)
downloadlinux-904818e2f229f3d94ec95f6932a6358c81e73d78.tar.xz
linux-904818e2f229f3d94ec95f6932a6358c81e73d78.zip
s390/kernel: introduce fpu-internal.h with fpu helper functions
Introduce a new structure to manage FP and VX registers. Refactor the save and restore of floating point and vector registers with a set of helper functions in fpu-internal.h. Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/traps.c')
-rw-r--r--arch/s390/kernel/traps.c24
1 files changed, 11 insertions, 13 deletions
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 7bea81d8a363..97598d1876c7 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -19,7 +19,7 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/slab.h>
-#include <asm/switch_to.h>
+#include <asm/fpu-internal.h>
#include "entry.h"
int show_unhandled_signals = 1;
@@ -227,7 +227,6 @@ DO_ERROR_INFO(specification_exception, SIGILL, ILL_ILLOPN,
int alloc_vector_registers(struct task_struct *tsk)
{
__vector128 *vxrs;
- int i;
/* Allocate vector register save area. */
vxrs = kzalloc(sizeof(__vector128) * __NUM_VXRS,
@@ -236,11 +235,10 @@ int alloc_vector_registers(struct task_struct *tsk)
return -ENOMEM;
preempt_disable();
if (tsk == current)
- save_fp_regs(tsk->thread.fp_regs.fprs);
+ save_fp_regs(tsk->thread.fpu.fprs);
/* Copy the 16 floating point registers */
- for (i = 0; i < 16; i++)
- *(freg_t *) &vxrs[i] = tsk->thread.fp_regs.fprs[i];
- tsk->thread.vxrs = vxrs;
+ convert_fp_to_vx(vxrs, tsk->thread.fpu.fprs);
+ tsk->thread.fpu.vxrs = vxrs;
if (tsk == current) {
__ctl_set_bit(0, 17);
restore_vx_regs(vxrs);
@@ -259,8 +257,8 @@ void vector_exception(struct pt_regs *regs)
}
/* get vector interrupt code from fpc */
- asm volatile("stfpc %0" : "=Q" (current->thread.fp_regs.fpc));
- vic = (current->thread.fp_regs.fpc & 0xf00) >> 8;
+ asm volatile("stfpc %0" : "=Q" (current->thread.fpu.fpc));
+ vic = (current->thread.fpu.fpc & 0xf00) >> 8;
switch (vic) {
case 1: /* invalid vector operation */
si_code = FPE_FLTINV;
@@ -297,22 +295,22 @@ void data_exception(struct pt_regs *regs)
location = get_trap_ip(regs);
- asm volatile("stfpc %0" : "=Q" (current->thread.fp_regs.fpc));
+ asm volatile("stfpc %0" : "=Q" (current->thread.fpu.fpc));
/* Check for vector register enablement */
- if (MACHINE_HAS_VX && !current->thread.vxrs &&
- (current->thread.fp_regs.fpc & FPC_DXC_MASK) == 0xfe00) {
+ if (MACHINE_HAS_VX && !is_vx_task(current) &&
+ (current->thread.fpu.fpc & FPC_DXC_MASK) == 0xfe00) {
alloc_vector_registers(current);
/* Vector data exception is suppressing, rewind psw. */
regs->psw.addr = __rewind_psw(regs->psw, regs->int_code >> 16);
clear_pt_regs_flag(regs, PIF_PER_TRAP);
return;
}
- if (current->thread.fp_regs.fpc & FPC_DXC_MASK)
+ if (current->thread.fpu.fpc & FPC_DXC_MASK)
signal = SIGFPE;
else
signal = SIGILL;
if (signal == SIGFPE)
- do_fp_trap(regs, current->thread.fp_regs.fpc);
+ do_fp_trap(regs, current->thread.fpu.fpc);
else if (signal)
do_trap(regs, signal, ILL_ILLOPN, "data exception");
}