mirror of
https://github.com/torvalds/linux.git
synced 2024-11-14 16:12:02 +00:00
xtensa: support artificial division by 0 exception
On xtensa cores wihout hardware division option division support functions from libgcc react to division by 0 attempt by executing illegal instruction followed by the characters 'DIV0'. Recognize this pattern in illegal instruction exception handler and convert it to division by 0. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
This commit is contained in:
parent
408b1d3c0e
commit
d74862007e
@ -293,12 +293,35 @@ static void do_interrupt(struct pt_regs *regs)
|
||||
set_irq_regs(old_regs);
|
||||
}
|
||||
|
||||
static bool check_div0(struct pt_regs *regs)
|
||||
{
|
||||
static const u8 pattern[] = {'D', 'I', 'V', '0'};
|
||||
const u8 *p;
|
||||
u8 buf[5];
|
||||
|
||||
if (user_mode(regs)) {
|
||||
if (copy_from_user(buf, (void __user *)regs->pc + 2, 5))
|
||||
return 0;
|
||||
p = buf;
|
||||
} else {
|
||||
p = (const u8 *)regs->pc + 2;
|
||||
}
|
||||
|
||||
return memcmp(p, pattern, sizeof(pattern)) == 0 ||
|
||||
memcmp(p + 1, pattern, sizeof(pattern)) == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Illegal instruction. Fatal if in kernel space.
|
||||
*/
|
||||
|
||||
static void do_illegal_instruction(struct pt_regs *regs)
|
||||
{
|
||||
if (check_div0(regs)) {
|
||||
do_div0(regs);
|
||||
return;
|
||||
}
|
||||
|
||||
__die_if_kernel("Illegal instruction in kernel", regs, SIGKILL);
|
||||
|
||||
/* If in user mode, send SIGILL signal to current process. */
|
||||
|
Loading…
Reference in New Issue
Block a user