예제 #1
0
void vector_exception(struct pt_regs *regs)
{
    int si_code, vic;

    if (!MACHINE_HAS_VX) {
        do_trap(regs, SIGILL, ILL_ILLOPN, "illegal operation");
        return;
    }

    /* get vector interrupt code from fpc */
    save_fpu_regs();
    vic = (current->thread.fpu.fpc & 0xf00) >> 8;
    switch (vic) {
    case 1: /* invalid vector operation */
        si_code = FPE_FLTINV;
        break;
    case 2: /* division by zero */
        si_code = FPE_FLTDIV;
        break;
    case 3: /* overflow */
        si_code = FPE_FLTOVF;
        break;
    case 4: /* underflow */
        si_code = FPE_FLTUND;
        break;
    case 5:	/* inexact */
        si_code = FPE_FLTRES;
        break;
    default: /* unknown cause */
        si_code = 0;
    }
    do_trap(regs, SIGFPE, si_code, "vector exception");
}
예제 #2
0
파일: process.c 프로젝트: 0-T-0/ps4-linux
int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
{
	size_t fpu_regs_size;

	*dst = *src;

	/*
	 * If the vector extension is available, it is enabled for all tasks,
	 * and, thus, the FPU register save area must be allocated accordingly.
	 */
	fpu_regs_size = MACHINE_HAS_VX ? sizeof(__vector128) * __NUM_VXRS
				       : sizeof(freg_t) * __NUM_FPRS;
	dst->thread.fpu.regs = kzalloc(fpu_regs_size, GFP_KERNEL|__GFP_REPEAT);
	if (!dst->thread.fpu.regs)
		return -ENOMEM;

	/*
	 * Save the floating-point or vector register state of the current
	 * task and set the CIF_FPU flag to lazy restore the FPU register
	 * state when returning to user space.
	 */
	save_fpu_regs();
	dst->thread.fpu.fpc = current->thread.fpu.fpc;
	memcpy(dst->thread.fpu.regs, current->thread.fpu.regs, fpu_regs_size);

	return 0;
}
예제 #3
0
void data_exception(struct pt_regs *regs)
{
    __u16 __user *location;
    int signal = 0;

    location = get_trap_ip(regs);

    save_fpu_regs();
    /* Check for vector register enablement */
    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;
    }
예제 #4
0
int alloc_vector_registers(struct task_struct *tsk)
{
    __vector128 *vxrs;
    freg_t *fprs;

    /* Allocate vector register save area. */
    vxrs = kzalloc(sizeof(__vector128) * __NUM_VXRS,
                   GFP_KERNEL|__GFP_REPEAT);
    if (!vxrs)
        return -ENOMEM;
    preempt_disable();
    if (tsk == current)
        save_fpu_regs();
    /* Copy the 16 floating point registers */
    convert_fp_to_vx(vxrs, tsk->thread.fpu.fprs);
    fprs = tsk->thread.fpu.fprs;
    tsk->thread.fpu.vxrs = vxrs;
    tsk->thread.fpu.flags |= FPU_USE_VX;
    kfree(fprs);
    preempt_enable();
    return 0;
}
예제 #5
0
파일: signal.c 프로젝트: 020gzh/linux
/* Store registers needed to create the signal frame */
static void store_sigregs(void)
{
	save_access_regs(current->thread.acrs);
	save_fpu_regs();
}