Commit d7486200 authored by Max Filippov's avatar Max Filippov
Browse files

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: default avatarMax Filippov <jcmvbkbc@gmail.com>
parent 408b1d3c
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -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. */