Commit ce6d70eb authored by Peter Bergner's avatar Peter Bergner

Catch illegal FP use within the kernel since it can cause data integrity errors in userland code.

parent 8c7da99c
......@@ -309,6 +309,7 @@ fix_alignment(struct pt_regs *regs)
/* Doing stfs, have to convert to single */
enable_kernel_fp();
cvt_df(&current->thread.fpr[reg], (float *)&data.v[4], &current->thread.fpscr);
disable_kernel_fp();
}
else
data.dd = current->thread.fpr[reg];
......@@ -342,6 +343,7 @@ fix_alignment(struct pt_regs *regs)
/* Doing lfs, have to convert to double */
enable_kernel_fp();
cvt_fd((float *)&data.v[4], &current->thread.fpr[reg], &current->thread.fpscr);
disable_kernel_fp();
}
else
current->thread.fpr[reg] = data.dd;
......
......@@ -792,11 +792,16 @@ ProgramCheck_common:
FPUnavailable_common:
EXCEPTION_PROLOG_COMMON
bne .load_up_fpu /* if from user, just load it up */
li r20,0
addi r3,r1,STACK_FRAME_OVERHEAD
#ifdef DO_SOFT_DISABLE
ld r20,SOFTE(r1)
#else
rldicl r20,r23,49,63 /* copy EE bit from saved MSR */
#endif
li r6,0x800
bl .save_remaining_regs /* if from kernel, take a trap */
bl .KernelFP
b .ret_from_except
bl .save_remaining_regs
bl .KernelFPUnavailableException
BUG_OPCODE
.globl SystemCall_common
SystemCall_common:
......@@ -1483,19 +1488,16 @@ _STATIC(load_up_fpu)
b fast_exception_return
/*
* FP unavailable trap from kernel - print a message, but let
* the task use FP in the kernel until it returns to user mode.
* disable_kernel_fp()
* Disable the FPU.
*/
_GLOBAL(KernelFP)
ld r3,_MSR(r1)
ori r3,r3,MSR_FP
std r3,_MSR(r1) /* enable use of FP after return */
LOADADDR(r3,86f)
ld r4,PACACURRENT(r13) /* current */
ld r5,_NIP(r1)
b .ret_from_except
86: .string "floating point used in kernel (task=%p, pc=%x)\n"
.align 4
_GLOBAL(disable_kernel_fp)
mfmsr r3
rldicl r0,r3,(63-MSR_FP_LG),1
rldicl r3,r0,(MSR_FP_LG+1),0
mtmsrd r3 /* disable use of fpu now */
isync
blr
/*
* giveup_fpu(tsk)
......
......@@ -345,6 +345,14 @@ ProgramCheckException(struct pt_regs *regs)
}
}
void
KernelFPUnavailableException(struct pt_regs *regs)
{
printk("Illegal floating point used in kernel (task=0x%016lx, pc=0x%016lx, trap=0x%08x)\n",
current, regs->nip, regs->trap);
panic("Unrecoverable FP Unavailable Exception in Kernel");
}
void
SingleStepException(struct pt_regs *regs)
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment