2012-03-05 11:49:27 +00:00
|
|
|
/*
|
|
|
|
* Based on arch/arm/kernel/traps.c
|
|
|
|
*
|
|
|
|
* Copyright (C) 1995-2009 Russell King
|
|
|
|
* Copyright (C) 2012 ARM Ltd.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
|
|
* published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2015-07-24 16:37:48 +01:00
|
|
|
#include <linux/bug.h>
|
2012-03-05 11:49:27 +00:00
|
|
|
#include <linux/signal.h>
|
|
|
|
#include <linux/personality.h>
|
|
|
|
#include <linux/kallsyms.h>
|
|
|
|
#include <linux/spinlock.h>
|
|
|
|
#include <linux/uaccess.h>
|
|
|
|
#include <linux/hardirq.h>
|
|
|
|
#include <linux/kdebug.h>
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/kexec.h>
|
|
|
|
#include <linux/delay.h>
|
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/sched.h>
|
|
|
|
#include <linux/syscalls.h>
|
|
|
|
|
|
|
|
#include <asm/atomic.h>
|
2015-07-24 16:37:48 +01:00
|
|
|
#include <asm/bug.h>
|
2013-03-16 08:48:13 +00:00
|
|
|
#include <asm/debug-monitors.h>
|
2014-11-18 12:16:30 +00:00
|
|
|
#include <asm/esr.h>
|
2015-07-24 16:37:48 +01:00
|
|
|
#include <asm/insn.h>
|
2012-03-05 11:49:27 +00:00
|
|
|
#include <asm/traps.h>
|
|
|
|
#include <asm/stacktrace.h>
|
|
|
|
#include <asm/exception.h>
|
|
|
|
#include <asm/system_misc.h>
|
2014-05-14 16:51:06 -07:00
|
|
|
#include <asm/esr.h>
|
|
|
|
#include <asm/edac.h>
|
2012-03-05 11:49:27 +00:00
|
|
|
|
2016-06-27 12:39:34 -07:00
|
|
|
#include <trace/events/exception.h>
|
|
|
|
|
2012-03-05 11:49:27 +00:00
|
|
|
static const char *handler[]= {
|
|
|
|
"Synchronous Abort",
|
|
|
|
"IRQ",
|
|
|
|
"FIQ",
|
|
|
|
"Error"
|
|
|
|
};
|
|
|
|
|
|
|
|
int show_unhandled_signals = 1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Dump out the contents of some memory nicely...
|
|
|
|
*/
|
|
|
|
static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
|
2015-07-10 09:23:59 +01:00
|
|
|
unsigned long top, bool compat)
|
2012-03-05 11:49:27 +00:00
|
|
|
{
|
|
|
|
unsigned long first;
|
|
|
|
mm_segment_t fs;
|
|
|
|
int i;
|
2015-07-10 09:23:59 +01:00
|
|
|
unsigned int width = compat ? 4 : 8;
|
2012-03-05 11:49:27 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* We need to switch to kernel mode so that we can use __get_user
|
2016-06-13 11:15:14 +01:00
|
|
|
* to safely read from kernel space.
|
2012-03-05 11:49:27 +00:00
|
|
|
*/
|
|
|
|
fs = get_fs();
|
|
|
|
set_fs(KERNEL_DS);
|
|
|
|
|
|
|
|
printk("%s%s(0x%016lx to 0x%016lx)\n", lvl, str, bottom, top);
|
|
|
|
|
|
|
|
for (first = bottom & ~31; first < top; first += 32) {
|
|
|
|
unsigned long p;
|
|
|
|
char str[sizeof(" 12345678") * 8 + 1];
|
|
|
|
|
|
|
|
memset(str, ' ', sizeof(str));
|
|
|
|
str[sizeof(str) - 1] = '\0';
|
|
|
|
|
2015-07-10 09:23:59 +01:00
|
|
|
for (p = first, i = 0; i < (32 / width)
|
|
|
|
&& p < top; i++, p += width) {
|
2012-03-05 11:49:27 +00:00
|
|
|
if (p >= bottom && p < top) {
|
2015-07-10 09:23:59 +01:00
|
|
|
unsigned long val;
|
|
|
|
|
|
|
|
if (width == 8) {
|
|
|
|
if (__get_user(val, (unsigned long *)p) == 0)
|
|
|
|
sprintf(str + i * 17, " %016lx", val);
|
|
|
|
else
|
|
|
|
sprintf(str + i * 17, " ????????????????");
|
|
|
|
} else {
|
|
|
|
if (__get_user(val, (unsigned int *)p) == 0)
|
|
|
|
sprintf(str + i * 9, " %08lx", val);
|
|
|
|
else
|
|
|
|
sprintf(str + i * 9, " ????????");
|
|
|
|
}
|
2012-03-05 11:49:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
printk("%s%04lx:%s\n", lvl, first & 0xffff, str);
|
|
|
|
}
|
|
|
|
|
|
|
|
set_fs(fs);
|
|
|
|
}
|
|
|
|
|
2015-10-17 14:28:11 +00:00
|
|
|
static void dump_backtrace_entry(unsigned long where)
|
2012-03-05 11:49:27 +00:00
|
|
|
{
|
2015-10-17 14:28:11 +00:00
|
|
|
/*
|
|
|
|
* Note that 'where' can have a physical address, but it's not handled.
|
|
|
|
*/
|
2012-03-05 11:49:27 +00:00
|
|
|
print_ip_sym(where);
|
|
|
|
}
|
|
|
|
|
2016-06-13 11:15:14 +01:00
|
|
|
static void __dump_instr(const char *lvl, struct pt_regs *regs)
|
2012-03-05 11:49:27 +00:00
|
|
|
{
|
|
|
|
unsigned long addr = instruction_pointer(regs);
|
|
|
|
char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = -4; i < 1; i++) {
|
|
|
|
unsigned int val, bad;
|
|
|
|
|
|
|
|
bad = __get_user(val, &((u32 *)addr)[i]);
|
|
|
|
|
|
|
|
if (!bad)
|
|
|
|
p += sprintf(p, i == 0 ? "(%08x) " : "%08x ", val);
|
|
|
|
else {
|
|
|
|
p += sprintf(p, "bad PC value");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
printk("%sCode: %s\n", lvl, str);
|
2016-06-13 11:15:14 +01:00
|
|
|
}
|
2012-03-05 11:49:27 +00:00
|
|
|
|
2016-06-13 11:15:14 +01:00
|
|
|
static void dump_instr(const char *lvl, struct pt_regs *regs)
|
|
|
|
{
|
|
|
|
if (!user_mode(regs)) {
|
|
|
|
mm_segment_t fs = get_fs();
|
|
|
|
set_fs(KERNEL_DS);
|
|
|
|
__dump_instr(lvl, regs);
|
|
|
|
set_fs(fs);
|
|
|
|
} else {
|
|
|
|
__dump_instr(lvl, regs);
|
|
|
|
}
|
2012-03-05 11:49:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
|
|
|
|
{
|
|
|
|
struct stackframe frame;
|
2016-02-11 13:53:10 -08:00
|
|
|
unsigned long irq_stack_ptr;
|
2015-12-15 17:33:41 +09:00
|
|
|
int skip;
|
2012-03-05 11:49:27 +00:00
|
|
|
|
2016-02-11 13:53:10 -08:00
|
|
|
/*
|
|
|
|
* Switching between stacks is valid when tracing current and in
|
|
|
|
* non-preemptible context.
|
|
|
|
*/
|
|
|
|
if (tsk == current && !preemptible())
|
|
|
|
irq_stack_ptr = IRQ_STACK_PTR(smp_processor_id());
|
|
|
|
else
|
|
|
|
irq_stack_ptr = 0;
|
2012-03-05 11:49:27 +00:00
|
|
|
|
|
|
|
pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
|
|
|
|
|
|
|
|
if (!tsk)
|
|
|
|
tsk = current;
|
|
|
|
|
2015-12-15 17:33:41 +09:00
|
|
|
if (tsk == current) {
|
2012-03-05 11:49:27 +00:00
|
|
|
frame.fp = (unsigned long)__builtin_frame_address(0);
|
2014-08-27 05:29:32 +01:00
|
|
|
frame.sp = current_stack_pointer;
|
2012-03-05 11:49:27 +00:00
|
|
|
frame.pc = (unsigned long)dump_backtrace;
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* task blocked in __switch_to
|
|
|
|
*/
|
|
|
|
frame.fp = thread_saved_fp(tsk);
|
|
|
|
frame.sp = thread_saved_sp(tsk);
|
|
|
|
frame.pc = thread_saved_pc(tsk);
|
|
|
|
}
|
2015-12-15 17:33:41 +09:00
|
|
|
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
|
|
|
frame.graph = tsk->curr_ret_stack;
|
|
|
|
#endif
|
2012-03-05 11:49:27 +00:00
|
|
|
|
2015-12-15 17:33:41 +09:00
|
|
|
skip = !!regs;
|
2015-12-21 16:44:27 +00:00
|
|
|
printk("Call trace:\n");
|
2012-03-05 11:49:27 +00:00
|
|
|
while (1) {
|
|
|
|
unsigned long where = frame.pc;
|
2015-10-17 14:28:11 +00:00
|
|
|
unsigned long stack;
|
2012-03-05 11:49:27 +00:00
|
|
|
int ret;
|
|
|
|
|
2015-12-15 17:33:41 +09:00
|
|
|
/* skip until specified stack frame */
|
|
|
|
if (!skip) {
|
|
|
|
dump_backtrace_entry(where);
|
|
|
|
} else if (frame.fp == regs->regs[29]) {
|
|
|
|
skip = 0;
|
|
|
|
/*
|
|
|
|
* Mostly, this is the case where this function is
|
|
|
|
* called in panic/abort. As exception handler's
|
|
|
|
* stack frame does not contain the corresponding pc
|
|
|
|
* at which an exception has taken place, use regs->pc
|
|
|
|
* instead.
|
|
|
|
*/
|
|
|
|
dump_backtrace_entry(regs->pc);
|
|
|
|
}
|
2015-12-15 17:33:40 +09:00
|
|
|
ret = unwind_frame(tsk, &frame);
|
2012-03-05 11:49:27 +00:00
|
|
|
if (ret < 0)
|
|
|
|
break;
|
2015-10-17 14:28:11 +00:00
|
|
|
stack = frame.sp;
|
2015-12-04 11:02:26 +00:00
|
|
|
if (in_exception_text(where)) {
|
|
|
|
/*
|
|
|
|
* If we switched to the irq_stack before calling this
|
|
|
|
* exception handler, then the pt_regs will be on the
|
|
|
|
* task stack. The easiest way to tell is if the large
|
|
|
|
* pt_regs would overlap with the end of the irq_stack.
|
|
|
|
*/
|
|
|
|
if (stack < irq_stack_ptr &&
|
|
|
|
(stack + sizeof(struct pt_regs)) > irq_stack_ptr)
|
|
|
|
stack = IRQ_STACK_TO_TASK_STACK(irq_stack_ptr);
|
|
|
|
|
2015-10-17 14:28:11 +00:00
|
|
|
dump_mem("", "Exception stack", stack,
|
|
|
|
stack + sizeof(struct pt_regs), false);
|
2015-12-04 11:02:26 +00:00
|
|
|
}
|
2012-03-05 11:49:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void show_stack(struct task_struct *tsk, unsigned long *sp)
|
|
|
|
{
|
|
|
|
dump_backtrace(NULL, tsk);
|
|
|
|
barrier();
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef CONFIG_PREEMPT
|
|
|
|
#define S_PREEMPT " PREEMPT"
|
|
|
|
#else
|
|
|
|
#define S_PREEMPT ""
|
|
|
|
#endif
|
|
|
|
#define S_SMP " SMP"
|
|
|
|
|
|
|
|
static int __die(const char *str, int err, struct thread_info *thread,
|
|
|
|
struct pt_regs *regs)
|
|
|
|
{
|
|
|
|
struct task_struct *tsk = thread->task;
|
|
|
|
static int die_counter;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
pr_emerg("Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
|
|
|
|
str, err, ++die_counter);
|
|
|
|
|
|
|
|
/* trap and error numbers are mostly meaningless on ARM */
|
|
|
|
ret = notify_die(DIE_OOPS, str, regs, err, 0, SIGSEGV);
|
|
|
|
if (ret == NOTIFY_STOP)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
print_modules();
|
|
|
|
__show_regs(regs);
|
|
|
|
pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n",
|
|
|
|
TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), thread + 1);
|
|
|
|
|
|
|
|
if (!user_mode(regs) || in_interrupt()) {
|
|
|
|
dump_backtrace(regs, tsk);
|
|
|
|
dump_instr(KERN_EMERG, regs);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2014-11-13 16:53:38 -08:00
|
|
|
static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED;
|
|
|
|
static int die_owner = -1;
|
|
|
|
static unsigned int die_nest_count;
|
2012-03-05 11:49:27 +00:00
|
|
|
|
2014-11-13 16:53:38 -08:00
|
|
|
static unsigned long oops_begin(void)
|
2012-03-05 11:49:27 +00:00
|
|
|
{
|
2014-11-13 16:53:38 -08:00
|
|
|
int cpu;
|
|
|
|
unsigned long flags;
|
2012-03-05 11:49:27 +00:00
|
|
|
|
|
|
|
oops_enter();
|
|
|
|
|
2014-11-13 16:53:38 -08:00
|
|
|
/* racy, but better than risking deadlock. */
|
|
|
|
raw_local_irq_save(flags);
|
|
|
|
cpu = smp_processor_id();
|
|
|
|
if (!arch_spin_trylock(&die_lock)) {
|
|
|
|
if (cpu == die_owner)
|
|
|
|
/* nested oops. should stop eventually */;
|
|
|
|
else
|
|
|
|
arch_spin_lock(&die_lock);
|
|
|
|
}
|
|
|
|
die_nest_count++;
|
|
|
|
die_owner = cpu;
|
2012-03-05 11:49:27 +00:00
|
|
|
console_verbose();
|
|
|
|
bust_spinlocks(1);
|
2014-11-13 16:53:38 -08:00
|
|
|
return flags;
|
|
|
|
}
|
2012-03-05 11:49:27 +00:00
|
|
|
|
2014-11-13 16:53:38 -08:00
|
|
|
static void oops_end(unsigned long flags, struct pt_regs *regs, int notify)
|
|
|
|
{
|
|
|
|
if (regs && kexec_should_crash(current))
|
2012-03-05 11:49:27 +00:00
|
|
|
crash_kexec(regs);
|
|
|
|
|
|
|
|
bust_spinlocks(0);
|
2014-11-13 16:53:38 -08:00
|
|
|
die_owner = -1;
|
2013-01-21 17:17:39 +10:30
|
|
|
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
2014-11-13 16:53:38 -08:00
|
|
|
die_nest_count--;
|
|
|
|
if (!die_nest_count)
|
|
|
|
/* Nest count reaches zero, release the lock. */
|
|
|
|
arch_spin_unlock(&die_lock);
|
|
|
|
raw_local_irq_restore(flags);
|
2012-03-05 11:49:27 +00:00
|
|
|
oops_exit();
|
|
|
|
|
|
|
|
if (in_interrupt())
|
|
|
|
panic("Fatal exception in interrupt");
|
|
|
|
if (panic_on_oops)
|
|
|
|
panic("Fatal exception");
|
2014-11-13 16:53:38 -08:00
|
|
|
if (notify != NOTIFY_STOP)
|
2012-03-05 11:49:27 +00:00
|
|
|
do_exit(SIGSEGV);
|
|
|
|
}
|
|
|
|
|
2014-11-13 16:53:38 -08:00
|
|
|
/*
|
|
|
|
* This function is protected against re-entrancy.
|
|
|
|
*/
|
|
|
|
void die(const char *str, struct pt_regs *regs, int err)
|
|
|
|
{
|
|
|
|
struct thread_info *thread = current_thread_info();
|
|
|
|
enum bug_trap_type bug_type = BUG_TRAP_TYPE_NONE;
|
|
|
|
unsigned long flags = oops_begin();
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!user_mode(regs))
|
|
|
|
bug_type = report_bug(regs->pc, regs);
|
|
|
|
if (bug_type != BUG_TRAP_TYPE_NONE)
|
|
|
|
str = "Oops - BUG";
|
|
|
|
|
|
|
|
ret = __die(str, err, thread, regs);
|
|
|
|
|
|
|
|
oops_end(flags, regs, ret);
|
|
|
|
}
|
|
|
|
|
2012-03-05 11:49:27 +00:00
|
|
|
void arm64_notify_die(const char *str, struct pt_regs *regs,
|
|
|
|
struct siginfo *info, int err)
|
|
|
|
{
|
2014-04-06 23:04:12 +01:00
|
|
|
if (user_mode(regs)) {
|
|
|
|
current->thread.fault_address = 0;
|
|
|
|
current->thread.fault_code = err;
|
2012-03-05 11:49:27 +00:00
|
|
|
force_sig_info(info->si_signo, info, current);
|
2014-04-06 23:04:12 +01:00
|
|
|
} else {
|
2012-03-05 11:49:27 +00:00
|
|
|
die(str, regs, err);
|
2014-04-06 23:04:12 +01:00
|
|
|
}
|
2012-03-05 11:49:27 +00:00
|
|
|
}
|
|
|
|
|
2014-11-18 11:41:22 +00:00
|
|
|
static LIST_HEAD(undef_hook);
|
|
|
|
static DEFINE_RAW_SPINLOCK(undef_lock);
|
|
|
|
|
|
|
|
void register_undef_hook(struct undef_hook *hook)
|
|
|
|
{
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
raw_spin_lock_irqsave(&undef_lock, flags);
|
|
|
|
list_add(&hook->node, &undef_hook);
|
|
|
|
raw_spin_unlock_irqrestore(&undef_lock, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
void unregister_undef_hook(struct undef_hook *hook)
|
|
|
|
{
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
raw_spin_lock_irqsave(&undef_lock, flags);
|
|
|
|
list_del(&hook->node);
|
|
|
|
raw_spin_unlock_irqrestore(&undef_lock, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int call_undef_hook(struct pt_regs *regs)
|
|
|
|
{
|
|
|
|
struct undef_hook *hook;
|
|
|
|
unsigned long flags;
|
|
|
|
u32 instr;
|
|
|
|
int (*fn)(struct pt_regs *regs, u32 instr) = NULL;
|
|
|
|
void __user *pc = (void __user *)instruction_pointer(regs);
|
|
|
|
|
|
|
|
if (!user_mode(regs))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (compat_thumb_mode(regs)) {
|
|
|
|
/* 16-bit Thumb instruction */
|
|
|
|
if (get_user(instr, (u16 __user *)pc))
|
|
|
|
goto exit;
|
|
|
|
instr = le16_to_cpu(instr);
|
|
|
|
if (aarch32_insn_is_wide(instr)) {
|
|
|
|
u32 instr2;
|
|
|
|
|
|
|
|
if (get_user(instr2, (u16 __user *)(pc + 2)))
|
|
|
|
goto exit;
|
|
|
|
instr2 = le16_to_cpu(instr2);
|
|
|
|
instr = (instr << 16) | instr2;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* 32-bit ARM instruction */
|
|
|
|
if (get_user(instr, (u32 __user *)pc))
|
|
|
|
goto exit;
|
|
|
|
instr = le32_to_cpu(instr);
|
|
|
|
}
|
|
|
|
|
|
|
|
raw_spin_lock_irqsave(&undef_lock, flags);
|
|
|
|
list_for_each_entry(hook, &undef_hook, node)
|
|
|
|
if ((instr & hook->instr_mask) == hook->instr_val &&
|
|
|
|
(regs->pstate & hook->pstate_mask) == hook->pstate_val)
|
|
|
|
fn = hook->fn;
|
|
|
|
|
|
|
|
raw_spin_unlock_irqrestore(&undef_lock, flags);
|
|
|
|
exit:
|
|
|
|
return fn ? fn(regs, instr) : 1;
|
|
|
|
}
|
|
|
|
|
2012-03-05 11:49:27 +00:00
|
|
|
asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
|
|
|
|
{
|
|
|
|
siginfo_t info;
|
|
|
|
void __user *pc = (void __user *)instruction_pointer(regs);
|
|
|
|
|
|
|
|
/* check for AArch32 breakpoint instructions */
|
2013-03-16 08:48:13 +00:00
|
|
|
if (!aarch32_break_handler(regs))
|
2012-03-05 11:49:27 +00:00
|
|
|
return;
|
|
|
|
|
2014-11-18 11:41:22 +00:00
|
|
|
if (call_undef_hook(regs) == 0)
|
|
|
|
return;
|
|
|
|
|
2016-06-27 12:39:34 -07:00
|
|
|
trace_undef_instr(regs, (void *)pc);
|
|
|
|
|
2015-07-03 15:08:08 +01:00
|
|
|
if (unhandled_signal(current, SIGILL) && show_unhandled_signals_ratelimited()) {
|
2012-03-05 11:49:27 +00:00
|
|
|
pr_info("%s[%d]: undefined instruction: pc=%p\n",
|
|
|
|
current->comm, task_pid_nr(current), pc);
|
|
|
|
dump_instr(KERN_INFO, regs);
|
|
|
|
}
|
|
|
|
|
|
|
|
info.si_signo = SIGILL;
|
|
|
|
info.si_errno = 0;
|
|
|
|
info.si_code = ILL_ILLOPC;
|
|
|
|
info.si_addr = pc;
|
|
|
|
|
|
|
|
arm64_notify_die("Oops - undefined instruction", regs, &info, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
long compat_arm_syscall(struct pt_regs *regs);
|
|
|
|
|
|
|
|
asmlinkage long do_ni_syscall(struct pt_regs *regs)
|
|
|
|
{
|
|
|
|
#ifdef CONFIG_COMPAT
|
|
|
|
long ret;
|
|
|
|
if (is_compat_task()) {
|
|
|
|
ret = compat_arm_syscall(regs);
|
|
|
|
if (ret != -ENOSYS)
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-06-19 15:28:03 +01:00
|
|
|
if (show_unhandled_signals_ratelimited()) {
|
2012-03-05 11:49:27 +00:00
|
|
|
pr_info("%s[%d]: syscall %d\n", current->comm,
|
|
|
|
task_pid_nr(current), (int)regs->syscallno);
|
|
|
|
dump_instr("", regs);
|
|
|
|
if (user_mode(regs))
|
|
|
|
__show_regs(regs);
|
|
|
|
}
|
|
|
|
|
|
|
|
return sys_ni_syscall();
|
|
|
|
}
|
|
|
|
|
2014-11-18 12:16:30 +00:00
|
|
|
static const char *esr_class_str[] = {
|
|
|
|
[0 ... ESR_ELx_EC_MAX] = "UNRECOGNIZED EC",
|
|
|
|
[ESR_ELx_EC_UNKNOWN] = "Unknown/Uncategorized",
|
|
|
|
[ESR_ELx_EC_WFx] = "WFI/WFE",
|
|
|
|
[ESR_ELx_EC_CP15_32] = "CP15 MCR/MRC",
|
|
|
|
[ESR_ELx_EC_CP15_64] = "CP15 MCRR/MRRC",
|
|
|
|
[ESR_ELx_EC_CP14_MR] = "CP14 MCR/MRC",
|
|
|
|
[ESR_ELx_EC_CP14_LS] = "CP14 LDC/STC",
|
|
|
|
[ESR_ELx_EC_FP_ASIMD] = "ASIMD",
|
|
|
|
[ESR_ELx_EC_CP10_ID] = "CP10 MRC/VMRS",
|
|
|
|
[ESR_ELx_EC_CP14_64] = "CP14 MCRR/MRRC",
|
|
|
|
[ESR_ELx_EC_ILL] = "PSTATE.IL",
|
|
|
|
[ESR_ELx_EC_SVC32] = "SVC (AArch32)",
|
|
|
|
[ESR_ELx_EC_HVC32] = "HVC (AArch32)",
|
|
|
|
[ESR_ELx_EC_SMC32] = "SMC (AArch32)",
|
|
|
|
[ESR_ELx_EC_SVC64] = "SVC (AArch64)",
|
|
|
|
[ESR_ELx_EC_HVC64] = "HVC (AArch64)",
|
|
|
|
[ESR_ELx_EC_SMC64] = "SMC (AArch64)",
|
|
|
|
[ESR_ELx_EC_SYS64] = "MSR/MRS (AArch64)",
|
|
|
|
[ESR_ELx_EC_IMP_DEF] = "EL3 IMP DEF",
|
|
|
|
[ESR_ELx_EC_IABT_LOW] = "IABT (lower EL)",
|
|
|
|
[ESR_ELx_EC_IABT_CUR] = "IABT (current EL)",
|
|
|
|
[ESR_ELx_EC_PC_ALIGN] = "PC Alignment",
|
|
|
|
[ESR_ELx_EC_DABT_LOW] = "DABT (lower EL)",
|
|
|
|
[ESR_ELx_EC_DABT_CUR] = "DABT (current EL)",
|
|
|
|
[ESR_ELx_EC_SP_ALIGN] = "SP Alignment",
|
|
|
|
[ESR_ELx_EC_FP_EXC32] = "FP (AArch32)",
|
|
|
|
[ESR_ELx_EC_FP_EXC64] = "FP (AArch64)",
|
|
|
|
[ESR_ELx_EC_SERROR] = "SError",
|
|
|
|
[ESR_ELx_EC_BREAKPT_LOW] = "Breakpoint (lower EL)",
|
|
|
|
[ESR_ELx_EC_BREAKPT_CUR] = "Breakpoint (current EL)",
|
|
|
|
[ESR_ELx_EC_SOFTSTP_LOW] = "Software Step (lower EL)",
|
|
|
|
[ESR_ELx_EC_SOFTSTP_CUR] = "Software Step (current EL)",
|
|
|
|
[ESR_ELx_EC_WATCHPT_LOW] = "Watchpoint (lower EL)",
|
|
|
|
[ESR_ELx_EC_WATCHPT_CUR] = "Watchpoint (current EL)",
|
|
|
|
[ESR_ELx_EC_BKPT32] = "BKPT (AArch32)",
|
|
|
|
[ESR_ELx_EC_VECTOR32] = "Vector catch (AArch32)",
|
|
|
|
[ESR_ELx_EC_BRK64] = "BRK (AArch64)",
|
|
|
|
};
|
|
|
|
|
|
|
|
const char *esr_get_class_string(u32 esr)
|
|
|
|
{
|
2016-05-31 12:33:01 +01:00
|
|
|
return esr_class_str[ESR_ELx_EC(esr)];
|
2014-11-18 12:16:30 +00:00
|
|
|
}
|
|
|
|
|
2012-03-05 11:49:27 +00:00
|
|
|
/*
|
arm64: avoid returning from bad_mode
commit 7d9e8f71b989230bc613d121ca38507d34ada849 upstream.
Generally, taking an unexpected exception should be a fatal event, and
bad_mode is intended to cater for this. However, it should be possible
to contain unexpected synchronous exceptions from EL0 without bringing
the kernel down, by sending a SIGILL to the task.
We tried to apply this approach in commit 9955ac47f4ba1c95 ("arm64:
don't kill the kernel on a bad esr from el0"), by sending a signal for
any bad_mode call resulting from an EL0 exception.
However, this also applies to other unexpected exceptions, such as
SError and FIQ. The entry paths for these exceptions branch to bad_mode
without configuring the link register, and have no kernel_exit. Thus, if
we take one of these exceptions from EL0, bad_mode will eventually
return to the original user link register value.
This patch fixes this by introducing a new bad_el0_sync handler to cater
for the recoverable case, and restoring bad_mode to its original state,
whereby it calls panic() and never returns. The recoverable case
branches to bad_el0_sync with a bl, and returns to userspace via the
usual ret_to_user mechanism.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Fixes: 9955ac47f4ba1c95 ("arm64: don't kill the kernel on a bad esr from el0")
Reported-by: Mark Salter <msalter@redhat.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-01-18 17:23:41 +00:00
|
|
|
* bad_mode handles the impossible case in the exception vector. This is always
|
|
|
|
* fatal.
|
2012-03-05 11:49:27 +00:00
|
|
|
*/
|
|
|
|
asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr)
|
|
|
|
{
|
|
|
|
console_verbose();
|
|
|
|
|
2014-11-18 12:16:30 +00:00
|
|
|
pr_crit("Bad mode in %s handler detected, code 0x%08x -- %s\n",
|
|
|
|
handler[reason], esr, esr_get_class_string(esr));
|
arm64: avoid returning from bad_mode
commit 7d9e8f71b989230bc613d121ca38507d34ada849 upstream.
Generally, taking an unexpected exception should be a fatal event, and
bad_mode is intended to cater for this. However, it should be possible
to contain unexpected synchronous exceptions from EL0 without bringing
the kernel down, by sending a SIGILL to the task.
We tried to apply this approach in commit 9955ac47f4ba1c95 ("arm64:
don't kill the kernel on a bad esr from el0"), by sending a signal for
any bad_mode call resulting from an EL0 exception.
However, this also applies to other unexpected exceptions, such as
SError and FIQ. The entry paths for these exceptions branch to bad_mode
without configuring the link register, and have no kernel_exit. Thus, if
we take one of these exceptions from EL0, bad_mode will eventually
return to the original user link register value.
This patch fixes this by introducing a new bad_el0_sync handler to cater
for the recoverable case, and restoring bad_mode to its original state,
whereby it calls panic() and never returns. The recoverable case
branches to bad_el0_sync with a bl, and returns to userspace via the
usual ret_to_user mechanism.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Fixes: 9955ac47f4ba1c95 ("arm64: don't kill the kernel on a bad esr from el0")
Reported-by: Mark Salter <msalter@redhat.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-01-18 17:23:41 +00:00
|
|
|
|
Merge tag 'lsk-v4.4-17.02-android' into branch 'msm-4.4'
* refs/heads/tmp-26c8156:
Linux 4.4.49
drm/i915: fix use-after-free in page_flip_completed()
ALSA: seq: Don't handle loop timeout at snd_seq_pool_done()
ALSA: seq: Fix race at creating a queue
xen-netfront: Delete rx_refill_timer in xennet_disconnect_backend()
scsi: mpt3sas: disable ASPM for MPI2 controllers
scsi: aacraid: Fix INTx/MSI-x issue with older controllers
scsi: zfcp: fix use-after-free by not tracing WKA port open/close on failed send
netvsc: Set maximum GSO size in the right place
mac80211: Fix adding of mesh vendor IEs
ARM: 8642/1: LPAE: catch pending imprecise abort on unmask
target: Fix COMPARE_AND_WRITE ref leak for non GOOD status
target: Fix early transport_generic_handle_tmr abort scenario
target: Use correct SCSI status during EXTENDED_COPY exception
target: Don't BUG_ON during NodeACL dynamic -> explicit conversion
ARM: 8643/3: arm/ptrace: Preserve previous registers for short regset write
hns: avoid stack overflow with CONFIG_KASAN
cpumask: use nr_cpumask_bits for parsing functions
Revert "x86/ioapic: Restore IO-APIC irq_chip retrigger callback"
selinux: fix off-by-one in setprocattr
ARC: [arcompact] brown paper bag bug in unaligned access delay slot fixup
Linux 4.4.48
base/memory, hotplug: fix a kernel oops in show_valid_zones()
x86/irq: Make irq activate operations symmetric
USB: serial: option: add device ID for HP lt2523 (Novatel E371)
usb: gadget: f_fs: Assorted buffer overflow checks.
USB: Add quirk for WORLDE easykey.25 MIDI keyboard
USB: serial: pl2303: add ATEN device ID
USB: serial: qcserial: add Dell DW5570 QDL
KVM: x86: do not save guest-unsupported XSAVE state
HID: wacom: Fix poor prox handling in 'wacom_pl_irq'
percpu-refcount: fix reference leak during percpu-atomic transition
mmc: sdhci: Ignore unexpected CARD_INT interrupts
can: bcm: fix hrtimer/tasklet termination in bcm op removal
mm, fs: check for fatal signals in do_generic_file_read()
mm/memory_hotplug.c: check start_pfn in test_pages_in_a_zone()
cifs: initialize file_info_lock
zswap: disable changing params if init fails
svcrpc: fix oops in absence of krb5 module
NFSD: Fix a null reference case in find_or_create_lock_stateid()
powerpc: Add missing error check to prom_find_boot_cpu()
powerpc/eeh: Fix wrong flag passed to eeh_unfreeze_pe()
libata: apply MAX_SEC_1024 to all CX1-JB*-HP devices
ata: sata_mv:- Handle return value of devm_ioremap.
perf/core: Fix PERF_RECORD_MMAP2 prot/flags for anonymous memory
crypto: arm64/aes-blk - honour iv_out requirement in CBC and CTR modes
crypto: api - Clear CRYPTO_ALG_DEAD bit before registering an alg
drm/nouveau/nv1a,nv1f/disp: fix memory clock rate retrieval
drm/nouveau/disp/gt215: Fix HDA ELD handling (thus, HDMI audio) on gt215
ext4: validate s_first_meta_bg at mount time
PCI/ASPM: Handle PCI-to-PCIe bridges as roots of PCIe hierarchies
ANDROID: security: export security_path_chown()
Linux 4.4.47
net: dsa: Bring back device detaching in dsa_slave_suspend()
qmi_wwan/cdc_ether: add device ID for HP lt2523 (Novatel E371) WWAN card
af_unix: move unix_mknod() out of bindlock
r8152: don't execute runtime suspend if the tx is not empty
bridge: netlink: call br_changelink() during br_dev_newlink()
tcp: initialize max window for a new fastopen socket
ipv6: addrconf: Avoid addrconf_disable_change() using RCU read-side lock
net: phy: bcm63xx: Utilize correct config_intr function
net: fix harmonize_features() vs NETIF_F_HIGHDMA
ax25: Fix segfault after sock connection timeout
ravb: do not use zero-length alignment DMA descriptor
openvswitch: maintain correct checksum state in conntrack actions
tcp: fix tcp_fastopen unaligned access complaints on sparc
net: systemport: Decouple flow control from __bcm_sysport_tx_reclaim
net: ipv4: fix table id in getroute response
net: lwtunnel: Handle lwtunnel_fill_encap failure
mlxsw: pci: Fix EQE structure definition
mlxsw: switchx2: Fix memory leak at skb reallocation
mlxsw: spectrum: Fix memory leak at skb reallocation
r8152: fix the sw rx checksum is unavailable
ANDROID: sdcardfs: Switch strcasecmp for internal call
ANDROID: sdcardfs: switch to full_name_hash and qstr
ANDROID: sdcardfs: Add GID Derivation to sdcardfs
ANDROID: sdcardfs: Remove redundant operation
ANDROID: sdcardfs: add support for user permission isolation
ANDROID: sdcardfs: Refactor configfs interface
ANDROID: sdcardfs: Allow non-owners to touch
ANDROID: binder: fix format specifier for type binder_size_t
ANDROID: fs: Export vfs_rmdir2
ANDROID: fs: Export free_fs_struct and set_fs_pwd
ANDROID: mnt: remount should propagate to slaves of slaves
ANDROID: sdcardfs: Switch ->d_inode to d_inode()
ANDROID: sdcardfs: Fix locking issue with permision fix up
ANDROID: sdcardfs: Change magic value
ANDROID: sdcardfs: Use per mount permissions
ANDROID: sdcardfs: Add gid and mask to private mount data
ANDROID: sdcardfs: User new permission2 functions
ANDROID: vfs: Add setattr2 for filesystems with per mount permissions
ANDROID: vfs: Add permission2 for filesystems with per mount permissions
ANDROID: vfs: Allow filesystems to access their private mount data
ANDROID: mnt: Add filesystem private data to mount points
ANDROID: sdcardfs: Move directory unlock before touch
ANDROID: sdcardfs: fix external storage exporting incorrect uid
ANDROID: sdcardfs: Added top to sdcardfs_inode_info
ANDROID: sdcardfs: Switch package list to RCU
ANDROID: sdcardfs: Fix locking for permission fix up
ANDROID: sdcardfs: Check for other cases on path lookup
ANDROID: sdcardfs: override umask on mkdir and create
Linux 4.4.46
mm, memcg: do not retry precharge charges
platform/x86: intel_mid_powerbtn: Set IRQ_ONESHOT
pinctrl: broxton: Use correct PADCFGLOCK offset
s5k4ecgx: select CRC32 helper
IB/umem: Release pid in error and ODP flow
IB/ipoib: move back IB LL address into the hard header
drm/i915: Don't leak edid in intel_crt_detect_ddc()
SUNRPC: cleanup ida information when removing sunrpc module
NFSv4.0: always send mode in SETATTR after EXCLUSIVE4
nfs: Don't increment lock sequence ID after NFS4ERR_MOVED
parisc: Don't use BITS_PER_LONG in userspace-exported swab.h header
ARC: [arcompact] handle unaligned access delay slot corner case
ARC: udelay: fix inline assembler by adding LP_COUNT to clobber list
can: ti_hecc: add missing prepare and unprepare of the clock
can: c_can_pci: fix null-pointer-deref in c_can_start() - set device pointer
s390/ptrace: Preserve previous registers for short regset write
RDMA/cma: Fix unknown symbol when CONFIG_IPV6 is not enabled
ISDN: eicon: silence misleading array-bounds warning
sysctl: fix proc_doulongvec_ms_jiffies_minmax()
mm/mempolicy.c: do not put mempolicy before using its nodemask
drm: Fix broken VT switch with video=1366x768 option
tile/ptrace: Preserve previous registers for short regset write
fbdev: color map copying bounds checking
Linux 4.4.45
arm64: avoid returning from bad_mode
selftest/powerpc: Wrong PMC initialized in pmc56_overflow test
dmaengine: pl330: Fix runtime PM support for terminated transfers
ite-cir: initialize use_demodulator before using it
blackfin: check devm_pinctrl_get() for errors
ARM: 8613/1: Fix the uaccess crash on PB11MPCore
ARM: ux500: fix prcmu_is_cpu_in_wfi() calculation
ARM: dts: imx6qdl-nitrogen6_max: fix sgtl5000 pinctrl init
arm64/ptrace: Reject attempts to set incomplete hardware breakpoint fields
arm64/ptrace: Avoid uninitialised struct padding in fpr_set()
arm64/ptrace: Preserve previous registers for short regset write - 3
arm64/ptrace: Preserve previous registers for short regset write - 2
arm64/ptrace: Preserve previous registers for short regset write
ARM: dts: da850-evm: fix read access to SPI flash
ceph: fix bad endianness handling in parse_reply_info_extra
ARM: 8634/1: hw_breakpoint: blacklist Scorpion CPUs
svcrdma: avoid duplicate dma unmapping during error recovery
clocksource/exynos_mct: Clear interrupt when cpu is shut down
ubifs: Fix journal replay wrt. xattr nodes
qla2xxx: Fix crash due to null pointer access
x86/ioapic: Restore IO-APIC irq_chip retrigger callback
mtd: nand: xway: disable module support
ieee802154: atusb: do not use the stack for buffers to make them DMA able
mmc: mxs-mmc: Fix additional cycles after transmission stop
HID: corsair: fix control-transfer error handling
HID: corsair: fix DMA buffers on stack
PCI: Enumerate switches below PCI-to-PCIe bridges
fuse: clear FR_PENDING flag when moving requests out of pending queue
svcrpc: don't leak contexts on PROC_DESTROY
x86/PCI: Ignore _CRS on Supermicro X8DTH-i/6/iF/6F
tmpfs: clear S_ISGID when setting posix ACLs
ARM: dts: imx31: fix AVIC base address
ARM: dts: imx31: move CCM device node to AIPS2 bus devices
ARM: dts: imx31: fix clock control module interrupts description
perf scripting: Avoid leaking the scripting_context variable
IB/IPoIB: Remove can't use GFP_NOIO warning
IB/mlx4: When no DMFS for IPoIB, don't allow NET_IF QPs
IB/mlx4: Fix port query for 56Gb Ethernet links
IB/mlx4: Fix out-of-range array index in destroy qp flow
IB/mlx4: Set traffic class in AH
IB/mlx5: Wait for all async command completions to complete
ftrace/x86: Set ftrace_stub to weak to prevent gcc from using short jumps to it
Linux 4.4.44
pinctrl: sh-pfc: Do not unconditionally support PIN_CONFIG_BIAS_DISABLE
powerpc/ibmebus: Fix device reference leaks in sysfs interface
powerpc/ibmebus: Fix further device reference leaks
bus: vexpress-config: fix device reference leak
blk-mq: Always schedule hctx->next_cpu
ACPI / APEI: Fix NMI notification handling
block: cfq_cpd_alloc() should use @gfp
cpufreq: powernv: Disable preemption while checking CPU throttling state
NFSv4.1: nfs4_fl_prepare_ds must be careful about reporting success.
NFS: Fix a performance regression in readdir
pNFS: Fix race in pnfs_wait_on_layoutreturn
pinctrl: meson: fix gpio request disabling other modes
btrfs: fix error handling when run_delayed_extent_op fails
btrfs: fix locking when we put back a delayed ref that's too new
x86/cpu: Fix bootup crashes by sanitizing the argument of the 'clearcpuid=' command-line option
USB: serial: ch341: fix modem-control and B0 handling
USB: serial: ch341: fix resume after reset
drm/radeon: drop verde dpm quirks
sysctl: Drop reference added by grab_header in proc_sys_readdir
sysrq: attach sysrq handler correctly for 32-bit kernel
tty/serial: atmel_serial: BUG: stop DMA from transmitting in stop_tx
mnt: Protect the mountpoint hashtable with mount_lock
vme: Fix wrong pointer utilization in ca91cx42_slave_get
xhci: fix deadlock at host remove by running watchdog correctly
i2c: fix kernel memory disclosure in dev interface
i2c: print correct device invalid address
Input: elants_i2c - avoid divide by 0 errors on bad touchscreen data
USB: serial: ch341: fix open and resume after B0
USB: serial: ch341: fix control-message error handling
USB: serial: ch341: fix open error handling
USB: serial: ch341: fix initial modem-control state
USB: serial: kl5kusb105: fix line-state error handling
nl80211: fix sched scan netlink socket owner destruction
KVM: x86: Introduce segmented_write_std
KVM: x86: emulate FXSAVE and FXRSTOR
KVM: x86: add asm_safe wrapper
KVM: x86: add Align16 instruction flag
KVM: x86: flush pending lapic jump label updates on module unload
jump_labels: API for flushing deferred jump label updates
KVM: eventfd: fix NULL deref irqbypass consumer
KVM: x86: fix emulation of "MOV SS, null selector"
mm/hugetlb.c: fix reservation race when freeing surplus pages
ocfs2: fix crash caused by stale lvb with fsdlm plugin
mm: fix devm_memremap_pages crash, use mem_hotplug_{begin, done}
selftests: do not require bash for the generated test
selftests: do not require bash to run netsocktests testcase
Input: i8042 - add Pegatron touchpad to noloop table
Input: xpad - use correct product id for x360w controllers
DEBUG: sched/fair: Fix sched_load_avg_cpu events for task_groups
DEBUG: sched/fair: Fix missing sched_load_avg_cpu events
net: socket: don't set sk_uid to garbage value in ->setattr()
ANDROID: configs: CONFIG_ARM64_SW_TTBR0_PAN=y
UPSTREAM: arm64: Disable PAN on uaccess_enable()
UPSTREAM: arm64: Enable CONFIG_ARM64_SW_TTBR0_PAN
UPSTREAM: arm64: xen: Enable user access before a privcmd hvc call
UPSTREAM: arm64: Handle faults caused by inadvertent user access with PAN enabled
BACKPORT: arm64: Disable TTBR0_EL1 during normal kernel execution
BACKPORT: arm64: Introduce uaccess_{disable,enable} functionality based on TTBR0_EL1
BACKPORT: arm64: Factor out TTBR0_EL1 post-update workaround into a specific asm macro
BACKPORT: arm64: Factor out PAN enabling/disabling into separate uaccess_* macros
UPSTREAM: arm64: alternative: add auto-nop infrastructure
UPSTREAM: arm64: barriers: introduce nops and __nops macros for NOP sequences
Revert "FROMLIST: arm64: Factor out PAN enabling/disabling into separate uaccess_* macros"
Revert "FROMLIST: arm64: Factor out TTBR0_EL1 post-update workaround into a specific asm macro"
Revert "FROMLIST: arm64: Introduce uaccess_{disable,enable} functionality based on TTBR0_EL1"
Revert "FROMLIST: arm64: Disable TTBR0_EL1 during normal kernel execution"
Revert "FROMLIST: arm64: Handle faults caused by inadvertent user access with PAN enabled"
Revert "FROMLIST: arm64: xen: Enable user access before a privcmd hvc call"
Revert "FROMLIST: arm64: Enable CONFIG_ARM64_SW_TTBR0_PAN"
ANDROID: sched/walt: fix build failure if FAIR_GROUP_SCHED=n
Linux 4.4.43
mm/init: fix zone boundary creation
ALSA: usb-audio: Add a quirk for Plantronics BT600
spi: mvebu: fix baudrate calculation for armada variant
ARM: OMAP4+: Fix bad fallthrough for cpuidle
ARM: zynq: Reserve correct amount of non-DMA RAM
powerpc: Fix build warning on 32-bit PPC
ALSA: firewire-tascam: Fix to handle error from initialization of stream data
HID: hid-cypress: validate length of report
net: vrf: do not allow table id 0
net: ipv4: Fix multipath selection with vrf
gro: Disable frag0 optimization on IPv6 ext headers
gro: use min_t() in skb_gro_reset_offset()
gro: Enter slow-path if there is no tailroom
r8152: fix rx issue for runtime suspend
r8152: split rtl8152_suspend function
ipv4: Do not allow MAIN to be alias for new LOCAL w/ custom rules
igmp: Make igmp group member RFC 3376 compliant
drop_monitor: consider inserted data in genlmsg_end
drop_monitor: add missing call to genlmsg_end
net/mlx5: Avoid shadowing numa_node
net/mlx5: Check FW limitations on log_max_qp before setting it
net: stmmac: Fix race between stmmac_drv_probe and stmmac_open
net, sched: fix soft lockup in tc_classify
ipv6: handle -EFAULT from skb_copy_bits
net: vrf: Drop conntrack data after pass through VRF device on Tx
ser_gigaset: return -ENOMEM on error instead of success
netvsc: reduce maximum GSO size
Linux 4.4.42
usb: gadget: composite: always set ep->mult to a sensible value
Revert "usb: gadget: composite: always set ep->mult to a sensible value"
tick/broadcast: Prevent NULL pointer dereference
drm/radeon: Always store CRTC relative radeon_crtc->cursor_x/y values
cx23885-dvb: move initialization of a8293_pdata
net: vxge: avoid unused function warnings
net: ti: cpmac: Fix compiler warning due to type confusion
cred/userns: define current_user_ns() as a function
staging: comedi: dt282x: tidy up register bit defines
powerpc/pci/rpadlpar: Fix device reference leaks
md: MD_RECOVERY_NEEDED is set for mddev->recovery
crypto: arm64/aes-ce - fix for big endian
crypto: arm64/aes-xts-ce: fix for big endian
crypto: arm64/sha1-ce - fix for big endian
crypto: arm64/aes-neon - fix for big endian
crypto: arm64/aes-ccm-ce: fix for big endian
crypto: arm/aes-ce - fix for big endian
crypto: arm64/ghash-ce - fix for big endian
crypto: arm64/sha2-ce - fix for big endian
s390/crypto: unlock on error in prng_tdes_read()
mmc: mmc_test: Uninitialized return value
PM / wakeirq: Fix dedicated wakeirq for drivers not using autosuspend
irqchip/bcm7038-l1: Implement irq_cpu_offline() callback
target/iscsi: Fix double free in lio_target_tiqn_addtpg()
scsi: mvsas: fix command_active typo
ASoC: samsung: i2s: Fixup last IRQ unsafe spin lock call
iommu/vt-d: Flush old iommu caches for kdump when the device gets context mapped
iommu/vt-d: Fix pasid table size encoding
iommu/amd: Fix the left value check of cmd buffer
iommu/amd: Missing error code in amd_iommu_init_device()
clk: imx31: fix rewritten input argument of mx31_clocks_init()
clk: clk-wm831x: fix a logic error
hwmon: (g762) Fix overflows and crash seen when writing limit attributes
hwmon: (nct7802) Fix overflows seen when writing into limit attributes
hwmon: (ds620) Fix overflows seen when writing temperature limits
hwmon: (amc6821) sign extension temperature
hwmon: (scpi) Fix module autoload
cris: Only build flash rescue image if CONFIG_ETRAX_AXISFLASHMAP is selected
ath10k: use the right length of "background"
stable-fixup: hotplug: fix unused function warning
usb: dwc3: ep0: explicitly call dwc3_ep0_prepare_one_trb()
usb: dwc3: ep0: add dwc3_ep0_prepare_one_trb()
usb: dwc3: gadget: always unmap EP0 requests
staging: iio: ad7606: fix improper setting of oversampling pins
mei: bus: fix mei_cldev_enable KDoc
USB: serial: io_ti: bind to interface after fw download
USB: phy: am335x-control: fix device and of_node leaks
ARM: dts: r8a7794: Correct hsusb parent clock
USB: serial: kl5kusb105: abort on open exception path
ALSA: usb-audio: Fix bogus error return in snd_usb_create_stream()
usb: musb: blackfin: add bfin_fifo_offset in bfin_ops
usb: hub: Move hub_port_disable() to fix warning if PM is disabled
usb: musb: Fix trying to free already-free IRQ 4
usb: dwc3: pci: add Intel Gemini Lake PCI ID
xhci: Fix race related to abort operation
xhci: Use delayed_work instead of timer for command timeout
usb: xhci-mem: use passed in GFP flags instead of GFP_KERNEL
USB: serial: mos7720: fix parallel probe
USB: serial: mos7720: fix parport use-after-free on probe errors
USB: serial: mos7720: fix use-after-free on probe errors
USB: serial: mos7720: fix NULL-deref at open
USB: serial: mos7840: fix NULL-deref at open
USB: serial: kobil_sct: fix NULL-deref in write
USB: serial: cyberjack: fix NULL-deref at open
USB: serial: oti6858: fix NULL-deref at open
USB: serial: io_edgeport: fix NULL-deref at open
USB: serial: ti_usb_3410_5052: fix NULL-deref at open
USB: serial: garmin_gps: fix memory leak on failed URB submit
USB: serial: iuu_phoenix: fix NULL-deref at open
USB: serial: io_ti: fix I/O after disconnect
USB: serial: io_ti: fix another NULL-deref at open
USB: serial: io_ti: fix NULL-deref at open
USB: serial: spcp8x5: fix NULL-deref at open
USB: serial: keyspan_pda: verify endpoints at probe
USB: serial: pl2303: fix NULL-deref at open
USB: serial: quatech2: fix sleep-while-atomic in close
USB: serial: omninet: fix NULL-derefs at open and disconnect
usb: xhci: hold lock over xhci_abort_cmd_ring()
xhci: Handle command completion and timeout race
usb: host: xhci: Fix possible wild pointer when handling abort command
usb: xhci: fix return value of xhci_setup_device()
xhci: free xhci virtual devices with leaf nodes first
usb: xhci: apply XHCI_PME_STUCK_QUIRK to Intel Apollo Lake
xhci: workaround for hosts missing CAS bit
usb: xhci: fix possible wild pointer
usb: dwc3: core: avoid Overflow events
usb: gadget: composite: Test get_alt() presence instead of set_alt()
USB: dummy-hcd: fix bug in stop_activity (handle ep0)
USB: fix problems with duplicate endpoint addresses
USB: gadgetfs: fix checks of wTotalLength in config descriptors
USB: gadgetfs: fix use-after-free bug
USB: gadgetfs: fix unbounded memory allocation bug
usb: gadgetfs: restrict upper bound on device configuration size
usb: storage: unusual_uas: Add JMicron JMS56x to unusual device
usb: musb: dsps: implement clear_ep_rxintr() callback
usb: musb: core: add clear_ep_rxintr() to musb_platform_ops
KVM: MIPS: Flush KVM entry code from icache globally
KVM: x86: reset MMU on KVM_SET_VCPU_EVENTS
mac80211: initialize fast-xmit 'info' later
ARM: davinci: da850: don't add emac clock to lookup table twice
ALSA: usb-audio: Fix irq/process data synchronization
ALSA: hda - Apply asus-mode8 fixup to ASUS X71SL
ALSA: hda - Fix up GPIO for ASUS ROG Ranger
Linux 4.4.41
net: mvpp2: fix dma unmapping of TX buffers for fragments
sg_write()/bsg_write() is not fit to be called under KERNEL_DS
kconfig/nconf: Fix hang when editing symbol with a long prompt
target/user: Fix use-after-free of tcmu_cmds if they are expired
powerpc: Convert cmp to cmpd in idle enter sequence
powerpc/ps3: Fix system hang with GCC 5 builds
nfs_write_end(): fix handling of short copies
libceph: verify authorize reply on connect
PCI: Check for PME in targeted sleep state
Input: drv260x - fix input device's parent assignment
media: solo6x10: fix lockup by avoiding delayed register write
IB/cma: Fix a race condition in iboe_addr_get_sgid()
IB/multicast: Check ib_find_pkey() return value
IPoIB: Avoid reading an uninitialized member variable
IB/mad: Fix an array index check
fgraph: Handle a case where a tracer ignores set_graph_notrace
platform/x86: asus-nb-wmi.c: Add X45U quirk
ftrace/x86_32: Set ftrace_stub to weak to prevent gcc from using short jumps to it
kvm: nVMX: Allow L1 to intercept software exceptions (#BP and #OF)
KVM: PPC: Book3S HV: Don't lose hardware R/C bit updates in H_PROTECT
KVM: PPC: Book3S HV: Save/restore XER in checkpointed register state
md/raid5: limit request size according to implementation limits
sc16is7xx: Drop bogus use of IRQF_ONESHOT
s390/vmlogrdr: fix IUCV buffer allocation
firmware: fix usermode helper fallback loading
ARC: mm: arc700: Don't assume 2 colours for aliasing VIPT dcache
scsi: avoid a permanent stop of the scsi device's request queue
scsi: zfcp: fix rport unblock race with LUN recovery
scsi: zfcp: do not trace pure benign residual HBA responses at default level
scsi: zfcp: fix use-after-"free" in FC ingress path after TMF
scsi: megaraid_sas: Do not set MPI2_TYPE_CUDA for JBOD FP path for FW which does not support JBOD sequence map
scsi: megaraid_sas: For SRIOV enabled firmware, ensure VF driver waits for 30secs before reset
vt: fix Scroll Lock LED trigger name
block: protect iterate_bdevs() against concurrent close
mei: request async autosuspend at the end of enumeration
drivers/gpu/drm/ast: Fix infinite loop if read fails
drm/gma500: Add compat ioctl
drm/radeon: add additional pci revision to dpm workaround
drm/radeon: Hide the HW cursor while it's out of bounds
drm/radeon: Also call cursor_move_locked when the cursor size changes
drm/nouveau/i2c/gk110b,gm10x: use the correct implementation
drm/nouveau/fifo/gf100-: protect channel preempt with subdev mutex
drm/nouveau/ltc: protect clearing of comptags with mutex
drm/nouveau/bios: require checksum to match for fast acpi shadow method
drm/nouveau/kms: lvds panel strap moved again on maxwell
ACPI / video: Add force_native quirk for HP Pavilion dv6
ACPI / video: Add force_native quirk for Dell XPS 17 L702X
staging: comedi: ni_mio_common: fix E series ni_ai_insn_read() data
staging: comedi: ni_mio_common: fix M Series ni_ai_insn_read() data mask
thermal: hwmon: Properly report critical temperature in sysfs
clk: bcm2835: Avoid overwriting the div info when disabling a pll_div clk
timekeeping_Force_unsigned_clocksource_to_nanoseconds_conversion
regulator: stw481x-vmmc: fix ages old enable error
mmc: sdhci: Fix recovery from tuning timeout
ath9k: Really fix LED polarity for some Mini PCI AR9220 MB92 cards.
cfg80211/mac80211: fix BSS leaks when abandoning assoc attempts
rtlwifi: Fix enter/exit power_save
ssb: Fix error routine when fallback SPROM fails
Linux 4.4.40
ppp: defer netns reference release for ppp channel
driver core: fix race between creating/querying glue dir and its cleanup
xfs: set AGI buffer type in xlog_recover_clear_agi_bucket
arm/xen: Use alloc_percpu rather than __alloc_percpu
xen/gntdev: Use VM_MIXEDMAP instead of VM_IO to avoid NUMA balancing
tpm xen: Remove bogus tpm_chip_unregister
kernel/debug/debug_core.c: more properly delay for secondary CPUs
kernel/watchdog: use nmi registers snapshot in hardlockup handler
CIFS: Fix a possible memory corruption in push locks
CIFS: Fix missing nls unload in smb2_reconnect()
CIFS: Fix a possible memory corruption during reconnect
ASoC: intel: Fix crash at suspend/resume without card registration
dm space map metadata: fix 'struct sm_metadata' leak on failed create
dm crypt: mark key as invalid until properly loaded
dm flakey: return -EINVAL on interval bounds error in flakey_ctr()
blk-mq: Do not invoke .queue_rq() for a stopped queue
usb: gadget: composite: always set ep->mult to a sensible value
exec: Ensure mm->user_ns contains the execed files
fs: exec: apply CLOEXEC before changing dumpable task flags
mm/vmscan.c: set correct defer count for shrinker
loop: return proper error from loop_queue_rq()
f2fs: set ->owner for debugfs status file's file_operations
ext4: do not perform data journaling when data is encrypted
ext4: return -ENOMEM instead of success
ext4: reject inodes with negative size
ext4: add sanity checking to count_overhead()
ext4: fix in-superblock mount options processing
ext4: use more strict checks for inodes_per_block on mount
ext4: fix stack memory corruption with 64k block size
ext4: fix mballoc breakage with 64k block size
crypto: caam - fix AEAD givenc descriptors
ptrace: Capture the ptracer's creds not PT_PTRACE_CAP
mm: Add a user_ns owner to mm_struct and fix ptrace permission checks
block_dev: don't test bdev->bd_contains when it is not stable
btrfs: make file clone aware of fatal signals
Btrfs: don't BUG() during drop snapshot
Btrfs: fix memory leak in do_walk_down
Btrfs: don't leak reloc root nodes on error
Btrfs: return gracefully from balance if fs tree is corrupted
Btrfs: bail out if block group has different mixed flag
Btrfs: fix memory leak in reading btree blocks
clk: ti: omap36xx: Work around sprz319 advisory 2.1
ALSA: hda: when comparing pin configurations, ignore assoc in addition to seq
ALSA: hda - Gate the mic jack on HP Z1 Gen3 AiO
ALSA: hda - fix headset-mic problem on a Dell laptop
ALSA: hda - ignore the assoc and seq when comparing pin configurations
ALSA: hda/ca0132 - Add quirk for Alienware 15 R2 2016
ALSA: hiface: Fix M2Tech hiFace driver sampling rate change
ALSA: usb-audio: Add QuickCam Communicate Deluxe/S7500 to volume_control_quirks
USB: UHCI: report non-PME wakeup signalling for Intel hardware
usb: gadget: composite: correctly initialize ep->maxpacket
usb: gadget: f_uac2: fix error handling at afunc_bind
usb: hub: Fix auto-remount of safely removed or ejected USB-3 devices
USB: cdc-acm: add device id for GW Instek AFG-125
USB: serial: kl5kusb105: fix open error path
USB: serial: option: add dlink dwm-158
USB: serial: option: add support for Telit LE922A PIDs 0x1040, 0x1041
Btrfs: fix qgroup rescan worker initialization
btrfs: store and load values of stripes_min/stripes_max in balance status item
Btrfs: fix tree search logic when replaying directory entry deletes
btrfs: limit async_work allocation and worker func duration
ANDROID: trace: net: use %pK for kernel pointers
ANDROID: android-base: Enable QUOTA related configs
net: ipv4: Don't crash if passing a null sk to ip_rt_update_pmtu.
net: inet: Support UID-based routing in IP protocols.
Revert "net: ipv6: fix virtual tunneling build"
net: core: add UID to flows, rules, and routes
net: core: Add a UID field to struct sock.
Revert "net: core: Support UID-based routing."
Revert "net: core: Handle 'sk' being NULL in UID-based routing"
Revert "ANDROID: net: fix 'const' warnings"
Revert "ANDROID: net: fib: remove duplicate assignment"
Revert "ANDROID: net: core: fix UID-based routing"
UPSTREAM: efi/arm64: Don't apply MEMBLOCK_NOMAP to UEFI memory map mapping
UPSTREAM: arm64: enable CONFIG_DEBUG_RODATA by default
goldfish: enable CONFIG_INET_DIAG_DESTROY
sched/walt: kill {min,max}_capacity
sched: fix wrong truncation of walt_avg
ANDROID: dm verity: add minimum prefetch size
Linux 4.4.39
crypto: rsa - Add Makefile dependencies to fix parallel builds
hotplug: Make register and unregister notifier API symmetric
batman-adv: Check for alloc errors when preparing TT local data
m68k: Fix ndelay() macro
arm64: futex.h: Add missing PAN toggling
can: peak: fix bad memory access and free sequence
can: raw: raw_setsockopt: limit number of can_filter that can be set
crypto: mcryptd - Check mcryptd algorithm compatibility
perf/x86: Fix full width counter, counter overflow
locking/rtmutex: Use READ_ONCE() in rt_mutex_owner()
locking/rtmutex: Prevent dequeue vs. unlock race
zram: restrict add/remove attributes to root only
parisc: Fix TLB related boot crash on SMP machines
parisc: Remove unnecessary TLB purges from flush_dcache_page_asm and flush_icache_page_asm
parisc: Purge TLB before setting PTE
powerpc/eeh: Fix deadlock when PE frozen state can't be cleared
Conflicts:
arch/arm64/kernel/traps.c
drivers/usb/dwc3/core.h
drivers/usb/dwc3/ep0.c
drivers/usb/gadget/function/f_fs.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/video/fbdev/core/fbcmap.c
include/trace/events/sched.h
mm/vmscan.c
Change-Id: I3faa0010ecb98972cd8e6470377a493b56d95f89
Signed-off-by: Blagovest Kolenichev <bkolenichev@codeaurora.org>
Signed-off-by: Runmin Wang <runminw@codeaurora.org>
2017-03-16 14:44:48 -07:00
|
|
|
if (esr >> ESR_ELx_EC_SHIFT == ESR_ELx_EC_SERROR) {
|
|
|
|
pr_crit("System error detected. ESR.ISS = %08x\n",
|
|
|
|
esr & 0xffffff);
|
|
|
|
arm64_check_cache_ecc(NULL);
|
|
|
|
}
|
|
|
|
|
arm64: avoid returning from bad_mode
commit 7d9e8f71b989230bc613d121ca38507d34ada849 upstream.
Generally, taking an unexpected exception should be a fatal event, and
bad_mode is intended to cater for this. However, it should be possible
to contain unexpected synchronous exceptions from EL0 without bringing
the kernel down, by sending a SIGILL to the task.
We tried to apply this approach in commit 9955ac47f4ba1c95 ("arm64:
don't kill the kernel on a bad esr from el0"), by sending a signal for
any bad_mode call resulting from an EL0 exception.
However, this also applies to other unexpected exceptions, such as
SError and FIQ. The entry paths for these exceptions branch to bad_mode
without configuring the link register, and have no kernel_exit. Thus, if
we take one of these exceptions from EL0, bad_mode will eventually
return to the original user link register value.
This patch fixes this by introducing a new bad_el0_sync handler to cater
for the recoverable case, and restoring bad_mode to its original state,
whereby it calls panic() and never returns. The recoverable case
branches to bad_el0_sync with a bl, and returns to userspace via the
usual ret_to_user mechanism.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Fixes: 9955ac47f4ba1c95 ("arm64: don't kill the kernel on a bad esr from el0")
Reported-by: Mark Salter <msalter@redhat.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-01-18 17:23:41 +00:00
|
|
|
die("Oops - bad mode", regs, 0);
|
|
|
|
local_irq_disable();
|
|
|
|
panic("bad mode");
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* bad_el0_sync handles unexpected, but potentially recoverable synchronous
|
|
|
|
* exceptions taken from EL0. Unlike bad_mode, this returns.
|
|
|
|
*/
|
|
|
|
asmlinkage void bad_el0_sync(struct pt_regs *regs, int reason, unsigned int esr)
|
|
|
|
{
|
|
|
|
siginfo_t info;
|
|
|
|
void __user *pc = (void __user *)instruction_pointer(regs);
|
|
|
|
console_verbose();
|
|
|
|
|
|
|
|
pr_crit("Bad EL0 synchronous exception detected on CPU%d, code 0x%08x -- %s\n",
|
|
|
|
smp_processor_id(), esr, esr_get_class_string(esr));
|
2013-05-28 15:54:15 +01:00
|
|
|
__show_regs(regs);
|
|
|
|
|
|
|
|
info.si_signo = SIGILL;
|
|
|
|
info.si_errno = 0;
|
|
|
|
info.si_code = ILL_ILLOPC;
|
|
|
|
info.si_addr = pc;
|
2012-03-05 11:49:27 +00:00
|
|
|
|
arm64: avoid returning from bad_mode
commit 7d9e8f71b989230bc613d121ca38507d34ada849 upstream.
Generally, taking an unexpected exception should be a fatal event, and
bad_mode is intended to cater for this. However, it should be possible
to contain unexpected synchronous exceptions from EL0 without bringing
the kernel down, by sending a SIGILL to the task.
We tried to apply this approach in commit 9955ac47f4ba1c95 ("arm64:
don't kill the kernel on a bad esr from el0"), by sending a signal for
any bad_mode call resulting from an EL0 exception.
However, this also applies to other unexpected exceptions, such as
SError and FIQ. The entry paths for these exceptions branch to bad_mode
without configuring the link register, and have no kernel_exit. Thus, if
we take one of these exceptions from EL0, bad_mode will eventually
return to the original user link register value.
This patch fixes this by introducing a new bad_el0_sync handler to cater
for the recoverable case, and restoring bad_mode to its original state,
whereby it calls panic() and never returns. The recoverable case
branches to bad_el0_sync with a bl, and returns to userspace via the
usual ret_to_user mechanism.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Fixes: 9955ac47f4ba1c95 ("arm64: don't kill the kernel on a bad esr from el0")
Reported-by: Mark Salter <msalter@redhat.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-01-18 17:23:41 +00:00
|
|
|
current->thread.fault_address = 0;
|
|
|
|
current->thread.fault_code = 0;
|
2014-05-14 16:51:06 -07:00
|
|
|
|
arm64: avoid returning from bad_mode
commit 7d9e8f71b989230bc613d121ca38507d34ada849 upstream.
Generally, taking an unexpected exception should be a fatal event, and
bad_mode is intended to cater for this. However, it should be possible
to contain unexpected synchronous exceptions from EL0 without bringing
the kernel down, by sending a SIGILL to the task.
We tried to apply this approach in commit 9955ac47f4ba1c95 ("arm64:
don't kill the kernel on a bad esr from el0"), by sending a signal for
any bad_mode call resulting from an EL0 exception.
However, this also applies to other unexpected exceptions, such as
SError and FIQ. The entry paths for these exceptions branch to bad_mode
without configuring the link register, and have no kernel_exit. Thus, if
we take one of these exceptions from EL0, bad_mode will eventually
return to the original user link register value.
This patch fixes this by introducing a new bad_el0_sync handler to cater
for the recoverable case, and restoring bad_mode to its original state,
whereby it calls panic() and never returns. The recoverable case
branches to bad_el0_sync with a bl, and returns to userspace via the
usual ret_to_user mechanism.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Fixes: 9955ac47f4ba1c95 ("arm64: don't kill the kernel on a bad esr from el0")
Reported-by: Mark Salter <msalter@redhat.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-01-18 17:23:41 +00:00
|
|
|
force_sig_info(info.si_signo, &info, current);
|
2012-03-05 11:49:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void __pte_error(const char *file, int line, unsigned long val)
|
|
|
|
{
|
2015-12-21 16:44:27 +00:00
|
|
|
pr_err("%s:%d: bad pte %016lx.\n", file, line, val);
|
2012-03-05 11:49:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void __pmd_error(const char *file, int line, unsigned long val)
|
|
|
|
{
|
2015-12-21 16:44:27 +00:00
|
|
|
pr_err("%s:%d: bad pmd %016lx.\n", file, line, val);
|
2012-03-05 11:49:27 +00:00
|
|
|
}
|
|
|
|
|
2014-05-12 18:40:51 +09:00
|
|
|
void __pud_error(const char *file, int line, unsigned long val)
|
|
|
|
{
|
2015-12-21 16:44:27 +00:00
|
|
|
pr_err("%s:%d: bad pud %016lx.\n", file, line, val);
|
2014-05-12 18:40:51 +09:00
|
|
|
}
|
|
|
|
|
2012-03-05 11:49:27 +00:00
|
|
|
void __pgd_error(const char *file, int line, unsigned long val)
|
|
|
|
{
|
2015-12-21 16:44:27 +00:00
|
|
|
pr_err("%s:%d: bad pgd %016lx.\n", file, line, val);
|
2012-03-05 11:49:27 +00:00
|
|
|
}
|
|
|
|
|
2015-07-24 16:37:48 +01:00
|
|
|
/* GENERIC_BUG traps */
|
|
|
|
|
|
|
|
int is_valid_bugaddr(unsigned long addr)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* bug_handler() only called for BRK #BUG_BRK_IMM.
|
|
|
|
* So the answer is trivial -- any spurious instances with no
|
|
|
|
* bug table entry will be rejected by report_bug() and passed
|
|
|
|
* back to the debug-monitors code and handled as a fatal
|
|
|
|
* unexpected debug exception.
|
|
|
|
*/
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int bug_handler(struct pt_regs *regs, unsigned int esr)
|
|
|
|
{
|
|
|
|
if (user_mode(regs))
|
|
|
|
return DBG_HOOK_ERROR;
|
|
|
|
|
|
|
|
switch (report_bug(regs->pc, regs)) {
|
|
|
|
case BUG_TRAP_TYPE_BUG:
|
|
|
|
die("Oops - BUG", regs, 0);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BUG_TRAP_TYPE_WARN:
|
2015-07-24 16:37:49 +01:00
|
|
|
/* Ideally, report_bug() should backtrace for us... but no. */
|
|
|
|
dump_backtrace(regs, NULL);
|
2015-07-24 16:37:48 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
/* unknown/unrecognised bug trap type */
|
|
|
|
return DBG_HOOK_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If thread survives, skip over the BUG instruction and continue: */
|
|
|
|
regs->pc += AARCH64_INSN_SIZE; /* skip BRK and resume */
|
|
|
|
return DBG_HOOK_HANDLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct break_hook bug_break_hook = {
|
|
|
|
.esr_val = 0xf2000000 | BUG_BRK_IMM,
|
|
|
|
.esr_mask = 0xffffffff,
|
|
|
|
.fn = bug_handler,
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initial handler for AArch64 BRK exceptions
|
|
|
|
* This handler only used until debug_traps_init().
|
|
|
|
*/
|
|
|
|
int __init early_brk64(unsigned long addr, unsigned int esr,
|
|
|
|
struct pt_regs *regs)
|
|
|
|
{
|
|
|
|
return bug_handler(regs, esr) != DBG_HOOK_HANDLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This registration must happen early, before debug_traps_init(). */
|
2012-03-05 11:49:27 +00:00
|
|
|
void __init trap_init(void)
|
|
|
|
{
|
2015-07-24 16:37:48 +01:00
|
|
|
register_break_hook(&bug_break_hook);
|
2012-03-05 11:49:27 +00:00
|
|
|
}
|