Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 620de2f5 authored by Jan Beulich's avatar Jan Beulich Committed by Tony Luck
Browse files

[IA64] honor notify_die() returning NOTIFY_STOP



This requires making die() and die_if_kernel() return a value, and their
callers to honor this (and be prepared that it returns).

Signed-off-by: default avatarJan Beulich <jbeulich@novell.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
parent ef3c4cb9
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@

#include "ia32priv.h"

extern void die_if_kernel (char *str, struct pt_regs *regs, long err);
extern int die_if_kernel (char *str, struct pt_regs *regs, long err);

struct exec_domain ia32_exec_domain;
struct page *ia32_shared_page[NR_CPUS];
@@ -217,7 +217,8 @@ ia32_bad_interrupt (unsigned long int_num, struct pt_regs *regs)
{
	siginfo_t siginfo;

	die_if_kernel("Bad IA-32 interrupt", regs, int_num);
	if (die_if_kernel("Bad IA-32 interrupt", regs, int_num))
		return;

	siginfo.si_signo = SIGTRAP;
	siginfo.si_errno = int_num;	/* XXX is it OK to abuse si_errno like this? */
+23 −12
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ trap_init (void)
		fpswa_interface = __va(ia64_boot_param->fpswa);
}

void
int
die (const char *str, struct pt_regs *regs, long err)
{
	static struct {
@@ -62,8 +62,11 @@ die (const char *str, struct pt_regs *regs, long err)
	if (++die.lock_owner_depth < 3) {
		printk("%s[%d]: %s %ld [%d]\n",
		current->comm, task_pid_nr(current), str, err, ++die_counter);
		(void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
		if (notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV)
	            != NOTIFY_STOP)
			show_regs(regs);
		else
			regs = NULL;
  	} else
		printk(KERN_ERR "Recursive die() failure, output suppressed\n");

@@ -72,17 +75,22 @@ die (const char *str, struct pt_regs *regs, long err)
	add_taint(TAINT_DIE);
	spin_unlock_irq(&die.lock);

	if (!regs)
		return 1;

	if (panic_on_oops)
		panic("Fatal exception");

  	do_exit(SIGSEGV);
	return 0;
}

void
int
die_if_kernel (char *str, struct pt_regs *regs, long err)
{
	if (!user_mode(regs))
		die(str, regs, err);
		return die(str, regs, err);
	return 0;
}

void
@@ -102,7 +110,8 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
		if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP)
			       	== NOTIFY_STOP)
			return;
		die_if_kernel("bugcheck!", regs, break_num);
		if (die_if_kernel("bugcheck!", regs, break_num))
			return;
		sig = SIGILL; code = ILL_ILLOPC;
		break;

@@ -155,8 +164,9 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
		break;

	      default:
		if (break_num < 0x40000 || break_num > 0x100000)
			die_if_kernel("Bad break", regs, break_num);
		if ((break_num < 0x40000 || break_num > 0x100000)
		    && die_if_kernel("Bad break", regs, break_num))
			return;

		if (break_num < 0x80000) {
			sig = SIGILL; code = __ILL_BREAK;
@@ -402,14 +412,15 @@ ia64_illegal_op_fault (unsigned long ec, long arg1, long arg2, long arg3,
#endif

	sprintf(buf, "IA-64 Illegal operation fault");
	die_if_kernel(buf, &regs, 0);
	rv.fkt = 0;
	if (die_if_kernel(buf, &regs, 0))
		return rv;

	memset(&si, 0, sizeof(si));
	si.si_signo = SIGILL;
	si.si_code = ILL_ILLOPC;
	si.si_addr = (void __user *) (regs.cr_iip + ia64_psr(&regs)->ri);
	force_sig_info(SIGILL, &si, current);
	rv.fkt = 0;
	return rv;
}

@@ -644,6 +655,6 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
		sprintf(buf, "Fault %lu", vector);
		break;
	}
	die_if_kernel(buf, &regs, error);
	if (!die_if_kernel(buf, &regs, error))
		force_sig(SIGILL, current);
}
+8 −5
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@
#include <asm/uaccess.h>
#include <asm/unaligned.h>

extern void die_if_kernel(char *str, struct pt_regs *regs, long err);
extern int die_if_kernel(char *str, struct pt_regs *regs, long err);

#undef DEBUG_UNALIGNED_TRAP

@@ -675,8 +675,9 @@ emulate_load_updates (update_t type, load_store_t ld, struct pt_regs *regs, unsi
	 */
	if (ld.x6_op == 1 || ld.x6_op == 3) {
		printk(KERN_ERR "%s: register update on speculative load, error\n", __FUNCTION__);
		die_if_kernel("unaligned reference on speculative load with register update\n",
			      regs, 30);
		if (die_if_kernel("unaligned reference on speculative load with register update\n",
				  regs, 30))
			return;
	}


@@ -1317,7 +1318,8 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)

	if (ia64_psr(regs)->be) {
		/* we don't support big-endian accesses */
		die_if_kernel("big-endian unaligned accesses are not supported", regs, 0);
		if (die_if_kernel("big-endian unaligned accesses are not supported", regs, 0))
			return;
		goto force_sigbus;
	}

@@ -1534,7 +1536,8 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
			ia64_handle_exception(regs, eh);
			goto done;
		}
		die_if_kernel("error during unaligned kernel access\n", regs, ret);
		if (die_if_kernel("error during unaligned kernel access\n", regs, ret))
			return;
		/* NOT_REACHED */
	}
  force_sigbus:
+5 −3
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@
#include <asm/system.h>
#include <asm/uaccess.h>

extern void die (char *, struct pt_regs *, long);
extern int die(char *, struct pt_regs *, long);

#ifdef CONFIG_KPROBES
static inline int notify_page_fault(struct pt_regs *regs, int trap)
@@ -267,8 +267,10 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
	else
		printk(KERN_ALERT "Unable to handle kernel paging request at "
		       "virtual address %016lx\n", address);
	die("Oops", regs, isr);
	if (die("Oops", regs, isr))
		regs = NULL;
	bust_spinlocks(0);
	if (regs)
		do_exit(SIGKILL);
	return;