* refs/heads/tmp-ed0b11d:
Linux 4.9.149
spi: bcm2835: Unbreak the build of esoteric configs
tpm: tpm_i2c_nuvoton: use correct command duration for TPM 2.x
rtc: m41t80: Correct alarm month range with RTC reads
arm64: KVM: Avoid setting the upper 32 bits of VTCR_EL2 to 1
x86/kvm/vmx: do not use vm-exit instruction length for fast MMIO when running nested
CIFS: Fix error mapping for SMB2_LOCK command which caused OFD lock problem
MIPS: OCTEON: mark RGMII interface disabled on OCTEON III
MIPS: Align kernel load address to 64KB
MIPS: Ensure pmd_present() returns false after pmd_mknotpresent()
media: v4l2-tpg: array index could become negative
media: vivid: free bitmap_cap when updating std/timings/etc.
serial: uartps: Fix interrupt mask issue to handle the RX interrupts properly
f2fs: fix validation of the block count in sanity_check_raw_super
cdc-acm: fix abnormal DATA RX issue for Mediatek Preloader.
clk: rockchip: fix typo in rk3188 spdif_frac parent
spi: bcm2835: Avoid finishing transfer prematurely in IRQ mode
spi: bcm2835: Fix book-keeping of DMA termination
spi: bcm2835: Fix race on DMA termination
ext4: force inode writes when nfsd calls commit_metadata()
ext4: include terminating u32 in size of xattr entries when expanding inodes
ext4: fix EXT4_IOC_GROUP_ADD ioctl
ext4: missing unlock/put_page() in ext4_try_to_write_inline_data()
ext4: fix possible use after free in ext4_quota_enable
perf pmu: Suppress potential format-truncation warning
platform-msi: Free descriptors in platform_msi_domain_free()
KVM: x86: Use jmp to invoke kvm_spurious_fault() from .fixup
Input: elan_i2c - add ACPI ID for touchpad in ASUS Aspire F5-573G
qmi_wwan: apply SET_DTR quirk to the SIMCOM shared device ID
staging: wilc1000: fix missing read_write setting when reading data
usb: r8a66597: Fix a possible concurrency use-after-free bug in r8a66597_endpoint_disable()
USB: serial: option: add Fibocom NL678 series
USB: serial: pl2303: add ids for Hewlett-Packard HP POS pole displays
ALSA: hda/tegra: clear pending irq handlers
ALSA: hda: add mute LED support for HP EliteBook 840 G4
mtd: atmel-quadspi: disallow building on ebsa110
ALSA: emux: Fix potential Spectre v1 vulnerabilities
ALSA: pcm: Fix potential Spectre v1 vulnerability
ALSA: emu10k1: Fix potential Spectre v1 vulnerabilities
ALSA: rme9652: Fix potential Spectre v1 vulnerability
ptr_ring: wrap back ->producer in __ptr_ring_swap_queue()
sock: Make sock->sk_stamp thread-safe
net/mlx5: Typo fix in del_sw_hw_rule
net/mlx5e: Remove the false indication of software timestamping support
gro_cell: add napi_disable in gro_cells_destroy
tipc: compare remote and local protocols in tipc_udp_enable()
tipc: use lock_sock() in tipc_sk_reinit()
xen/netfront: tolerate frags with no data
VSOCK: Send reset control packet when socket is partially bound
vhost: make sure used idx is seen before log in vhost_add_used_n()
tipc: fix a double kfree_skb()
sctp: initialize sin6_flowinfo for ipv6 addrs in sctp_inet6addr_event
packet: validate address length if non-zero
packet: validate address length
net/wan: fix a double free in x25_asy_open_tty()
netrom: fix locking in nr_find_socket()
net: phy: Fix the issue that netif always links up after resuming
net: ipv4: do not handle duplicate fragments as overlapping
isdn: fix kernel-infoleak in capi_unlocked_ioctl
ipv6: tunnels: fix two use-after-free
ipv6: explicitly initialize udp6_addr in udp_sock_create6()
ieee802154: lowpan_header_create check must check daddr
ibmveth: fix DMA unmap error in ibmveth_xmit_start error path
ax25: fix a use-after-free in ax25_fillin_cb()
ipv4: Fix potential Spectre v1 vulnerability
ip6mr: Fix potential Spectre v1 vulnerability
NFC: nxp-nci: Include unaligned.h instead of access_ok.h
UPSTREAM: mm: /proc/pid/smaps_rollup: fix NULL pointer deref in smaps_pte_range()
BACKPORT: fs/proc/task_mmu.c: fix Locked field in /proc/pid/smaps*
BACKPORT: mm: add /proc/pid/smaps_rollup
ANDROID: cuttlefish_defconfig: Enable VIRTIO_INPUT
Linux 4.9.148
drm/ioctl: Fix Spectre v1 vulnerabilities
proc/sysctl: don't return ENOMEM on lookup when a table is unregistering
panic: avoid deadlocks in re-entrant console drivers
ubifs: Handle re-linking of inodes correctly while recovery
x86/fpu: Disable bottom halves while loading FPU registers
x86/mtrr: Don't copy uninitialized gentry fields back to userspace
Drivers: hv: vmbus: Return -EINVAL for the sys files for unopened channels
gpio: max7301: fix driver for use with CONFIG_VMAP_STACK
mmc: omap_hsmmc: fix DMA API warning
mmc: core: Use a minimum 1600ms timeout when enabling CACHE ctrl
mmc: core: Allow BKOPS and CACHE ctrl even if no HPI support
mmc: core: Reset HPI enabled state during re-init and in case of errors
USB: serial: option: add Telit LN940 series
USB: serial: option: add Fibocom NL668 series
USB: serial: option: add Simcom SIM7500/SIM7600 (MBIM mode)
USB: serial: option: add HP lt4132
USB: serial: option: add GosunCn ZTE WeLink ME3630
xhci: Don't prevent USB2 bus suspend in state check intended for USB3 only
USB: hso: Fix OOB memory access in hso_probe/hso_get_config_data
ib_srpt: Fix a use-after-free in __srpt_close_all_ch()
block: fix infinite loop if the device loses discard capability
block: break discard submissions into the user defined size
Linux 4.9.147
rtc: snvs: Add timeouts to avoid kernel lockups
rtc: snvs: add a missing write sync
nvmet-rdma: fix response use after free
i2c: scmi: Fix probe error on devices with an empty SMB0001 ACPI device node
i2c: axxia: properly handle master timeout
vhost/vsock: fix reset orphans race with close timeout
cifs: In Kconfig CONFIG_CIFS_POSIX needs depends on legacy (insecure cifs)
drm/ast: Fix connector leak during driver unload
ethernet: fman: fix wrong of_node_put() in probe function
ARM: 8815/1: V7M: align v7m_dma_inv_range() with v7 counterpart
ARM: 8814/1: mm: improve/fix ARM v7_dma_inv_range() unaligned address handling
bpf: check pending signals while verifying programs
net/mlx4_en: Fix build break when CONFIG_INET is off
mv88e6060: disable hardware level MAC learning
libata: whitelist all SAMSUNG MZ7KM* solid-state disks
Input: omap-keypad - fix keyboard debounce configuration
clk: mmp: Off by one in mmp_clk_add()
clk: mvebu: Off by one bugs in cp110_of_clk_get()
ide: pmac: add of_node_put()
drivers/tty: add missing of_node_put()
drivers/sbus/char: add of_node_put()
sbus: char: add of_node_put()
SUNRPC: Fix a potential race in xprt_connect()
nfs: don't dirty kernel pages read by direct-io
bonding: fix 802.3ad state sent to partner when unbinding slave
ARC: io.h: Implement reads{x}()/writes{x}()
drm/msm: Grab a vblank reference when waiting for commit_done
x86/earlyprintk/efi: Fix infinite loop on some screen widths
scsi: vmw_pscsi: Rearrange code to avoid multiple calls to free_irq during unload
scsi: libiscsi: Fix NULL pointer dereference in iscsi_eh_session_reset
mac80211_hwsim: fix module init error paths for netlink
locking/qspinlock: Fix build for anonymous union in older GCC compilers
locking/qspinlock, x86: Provide liveness guarantee
locking/qspinlock/x86: Increase _Q_PENDING_LOOPS upper bound
locking/qspinlock: Re-order code
locking/qspinlock: Kill cmpxchg() loop when claiming lock from head of queue
locking/qspinlock: Remove duplicate clear_pending() function from PV code
locking/qspinlock: Remove unbounded cmpxchg() loop from locking slowpath
locking/qspinlock: Merge 'struct __qspinlock' into 'struct qspinlock'
locking/qspinlock: Bound spinning on pending->locked transition in slowpath
locking/qspinlock: Ensure node is initialised before updating prev->next
locking: Remove smp_read_barrier_depends() from queued_spin_lock_slowpath()
IB/hfi1: Remove race conditions in user_sdma send path
mac80211: Fix condition validating WMM IE
mac80211: don't WARN on bad WMM parameters from buggy APs
drm/i915/execlists: Apply a full mb before execution for Braswell
Revert "drm/rockchip: Allow driver to be shutdown on reboot/kexec"
powerpc/msi: Fix NULL pointer access in teardown code
tracing: Fix memory leak of instance function hash filters
tracing: Fix memory leak in set_trigger_filter()
ARM: mmp/mmp2: fix cpu_is_mmp2() on mmp2-dt
MMC: OMAP: fix broken MMC on OMAP15XX/OMAP5910/OMAP310
aio: fix spectre gadget in lookup_ioctx
pinctrl: sunxi: a83t: Fix IRQ offset typo for PH11
timer/debug: Change /proc/timer_list from 0444 to 0400
lib/interval_tree_test.c: allow users to limit scope of endpoint
lib/rbtree-test: lower default params
lib/rbtree_test.c: make input module parameters
lib/interval_tree_test.c: allow full tree search
lib/interval_tree_test.c: make test options module parameters
signal: Introduce COMPAT_SIGMINSTKSZ for use in compat_sys_sigaltstack
ANDROID: Revert fs/squashfs back to linux-4.9.y
BACKPORT, FROMGIT: dm verity: log the hash algorithm implementation
BACKPORT, FROMGIT: dm crypt: log the encryption algorithm implementation
Linux 4.9.146
staging: speakup: Replace strncpy with memcpy
pstore: Convert console write to use ->write_buf
ocfs2: fix potential use after free
debugobjects: avoid recursive calls with kmemleak
hfsplus: do not free node before using
hfs: do not free node before using
ocfs2: fix deadlock caused by ocfs2_defrag_extent()
fscache, cachefiles: remove redundant variable 'cache'
fscache: fix race between enablement and dropping of object
xen: xlate_mmu: add missing header to fix 'W=1' warning
drm/ast: fixed reading monitor EDID not stable issue
net: hisilicon: remove unexpected free_netdev
ixgbe: recognize 1000BaseLX SFP modules as 1Gbps
igb: fix uninitialized variables
cachefiles: Fix page leak in cachefiles_read_backing_file while vmscan is active
net: thunderx: fix NULL pointer dereference in nic_remove
x86/kvm/vmx: fix old-style function declaration
KVM: x86: fix empty-body warnings
USB: omap_udc: fix USB gadget functionality on Palm Tungsten E
USB: omap_udc: fix omap_udc_start() on 15xx machines
USB: omap_udc: fix crashes on probe error and module removal
USB: omap_udc: use devm_request_irq()
ipvs: call ip_vs_dst_notifier earlier than ipv6_dev_notf
bpf: fix check of allowed specifiers in bpf_trace_printk
exportfs: do not read dentry after free
ASoC: omap-dmic: Add pm_qos handling to avoid overruns with CPU_IDLE
ASoC: omap-mcpdm: Add pm_qos handling to avoid under/overruns with CPU_IDLE
RDMA/mlx5: Fix fence type for IB_WR_LOCAL_INV WR
Btrfs: send, fix infinite loop due to directory rename dependencies
objtool: Fix segfault in .cold detection with -ffunction-sections
objtool: Fix double-free in .cold detection error path
hwmon: (w83795) temp4_type has writable permission
ASoC: dapm: Recalculate audio map forcely when card instantiated
ASoC: omap-abe-twl6040: Fix missing audio card caused by deferred probing
hwmon: (ina2xx) Fix current value calculation
s390/cpum_cf: Reject request for sampling in event initialization
selftests: add script to stress-test nft packet path vs. control plane
sysv: return 'err' instead of 0 in __sysv_write_inode
ARM: OMAP1: ams-delta: Fix possible use of uninitialized field
ARM: dts: logicpd-somlv: Fix interrupt on mmc3_dat1
ARM: OMAP2+: prm44xx: Fix section annotation on omap44xx_prm_enable_io_wakeup
neighbour: Avoid writing before skb->head in neigh_hh_output()
tun: forbid iface creation with rtnl ops
tcp: fix NULL ref in tail loss probe
rtnetlink: ndo_dflt_fdb_dump() only work for ARPHRD_ETHER devices
net: Prevent invalid access to skb->prev in __qdisc_drop_all
net: phy: don't allow __set_phy_supported to add unsupported modes
net/mlx4_core: Correctly set PFC param if global pause is turned off.
net: 8139cp: fix a BUG triggered by changing mtu with network traffic
ipv6: Check available headroom in ip6_xmit() even without options
Makefile: Properly resolve conflict from 4.9.145
ANDROID: cuttlefish_defconfig: Enable CONFIG_CRYPTO_ADIANTUM
UPSTREAM: dm crypt: don't decrease device limits
BACKPORT: dm crypt: allow unaligned bv_offset
BACKPORT: dm crypt: reject sector_size feature if device length is not aligned to it
BACKPORT: dm crypt: use shifts instead of sector_div
BACKPORT: dm crypt: optionally support larger encryption sector size
BACKPORT, FROMGIT: fscrypt: add Adiantum support
BACKPORT, FROMGIT: crypto: adiantum - add Adiantum support
FROMGIT: crypto: arm/nhpoly1305 - add NEON-accelerated NHPoly1305
BACKPORT, FROMGIT: crypto: nhpoly1305 - add NHPoly1305 support
FROMGIT: crypto: poly1305 - add Poly1305 core API
FROMGIT: crypto: poly1305 - use structures for key and accumulator
BACKPORT, FROMGIT: crypto: arm/chacha - add XChaCha12 support
BACKPORT, FROMGIT: crypto: arm/chacha20 - refactor to allow varying number of rounds
BACKPORT, FROMGIT: crypto: arm/chacha20 - add XChaCha20 support
BACKPORT, FROMGIT: crypto: arm/chacha20 - limit the preemption-disabled section
BACKPORT, FROMGIT: crypto: chacha - add XChaCha12 support
BACKPORT, FROMGIT: crypto: chacha20-generic - refactor to allow varying number of rounds
BACKPORT, FROMGIT: crypto: chacha20-generic - add XChaCha20 support
FROMGIT: crypto: chacha20-generic - add HChaCha20 library function
FROMGIT: crypto: arm/aes - add some hardening against cache-timing attacks
UPSTREAM: crypto: arm/aes-cipher - move S-box to .rodata section
UPSTREAM: crypto: arm/aes - avoid expanded lookup tables in the final round
UPSTREAM: crypto: arm/aes - avoid reserved 'tt' mnemonic in asm code
BACKPORT: crypto: arm/aes - replace scalar AES cipher
UPSTREAM: crypto: poly1305 - use unaligned access macros to output digest
UPSTREAM: crypto: poly1305 - Use unaligned access where required
UPSTREAM: crypto: arm/chacha20 - faster 8-bit rotations and other optimizations
UPSTREAM: crypto: arm/chacha20 - always use vrev for 16-bit rotates
BACKPORT: crypto: arm/chacha20 - implement NEON version based on SSE3 code
BACKPORT: crypto: chacha20 - Fix chacha20_block() keystream alignment (again)
UPSTREAM: crypto: chacha20 - use rol32() macro from bitops.h
BACKPORT: crypto: chacha20 - Fix keystream alignment for chacha20_block()
UPSTREAM: crypto: chacha20 - Use unaligned access macros when loading key and IV
UPSTREAM: crypto: chacha20 - Fix unaligned access when loading constants
UPSTREAM: crypto: testmgr - fix overlap in chunked tests again
UPSTREAM: crypto: testmgr - avoid overlap in chunked tests
ANDROID: cuttlefish_defconfig: Enable VIRT_WIFI
FROMGIT, BACKPORT: mac80211-next: rtnetlink wifi simulation device
ANDROID: cuttlefish_defconfig: Enable CONFIG_ARM64_LSE_ATOMICS
ANDROID: Move from clang r328903 to r346389b.
ANDROID: arm64 defconfig / build config for cuttlefish
Conflicts:
drivers/char/random.c
drivers/md/dm-crypt.c
drivers/mmc/core/mmc.c
drivers/net/wireless/Kconfig
drivers/net/wireless/Makefile
fs/crypto/fscrypt_private.h
fs/crypto/keyinfo.c
include/uapi/linux/fs.h
Change-Id: I3f7617ac7ab346b0650757e25ef3e7daf4d97a1e
Signed-off-by: jianzhou <jianzhou@codeaurora.org>
631 lines
16 KiB
C
631 lines
16 KiB
C
/*
|
|
* linux/kernel/panic.c
|
|
*
|
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
|
*/
|
|
|
|
/*
|
|
* This function is used through-out the kernel (including mm and fs)
|
|
* to indicate a major problem.
|
|
*/
|
|
#include <linux/debug_locks.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/kmsg_dump.h>
|
|
#include <linux/kallsyms.h>
|
|
#include <linux/notifier.h>
|
|
#include <linux/vt_kern.h>
|
|
#include <linux/module.h>
|
|
#include <linux/random.h>
|
|
#include <linux/ftrace.h>
|
|
#include <linux/reboot.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/kexec.h>
|
|
#include <linux/sched.h>
|
|
#include <linux/sysrq.h>
|
|
#include <linux/init.h>
|
|
#include <linux/nmi.h>
|
|
#include <linux/console.h>
|
|
#include <linux/bug.h>
|
|
#define CREATE_TRACE_POINTS
|
|
#include <trace/events/exception.h>
|
|
#include <soc/qcom/minidump.h>
|
|
|
|
#define PANIC_TIMER_STEP 100
|
|
#define PANIC_BLINK_SPD 18
|
|
|
|
int panic_on_oops = CONFIG_PANIC_ON_OOPS_VALUE;
|
|
static unsigned long tainted_mask;
|
|
static int pause_on_oops;
|
|
static int pause_on_oops_flag;
|
|
static DEFINE_SPINLOCK(pause_on_oops_lock);
|
|
bool crash_kexec_post_notifiers;
|
|
int panic_on_warn __read_mostly;
|
|
|
|
int panic_timeout = CONFIG_PANIC_TIMEOUT;
|
|
EXPORT_SYMBOL_GPL(panic_timeout);
|
|
|
|
ATOMIC_NOTIFIER_HEAD(panic_notifier_list);
|
|
|
|
EXPORT_SYMBOL(panic_notifier_list);
|
|
|
|
static long no_blink(int state)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* Returns how long it waited in ms */
|
|
long (*panic_blink)(int state);
|
|
EXPORT_SYMBOL(panic_blink);
|
|
|
|
/*
|
|
* Stop ourself in panic -- architecture code may override this
|
|
*/
|
|
void __weak panic_smp_self_stop(void)
|
|
{
|
|
while (1)
|
|
cpu_relax();
|
|
}
|
|
|
|
/*
|
|
* Stop ourselves in NMI context if another CPU has already panicked. Arch code
|
|
* may override this to prepare for crash dumping, e.g. save regs info.
|
|
*/
|
|
void __weak nmi_panic_self_stop(struct pt_regs *regs)
|
|
{
|
|
panic_smp_self_stop();
|
|
}
|
|
|
|
/*
|
|
* Stop other CPUs in panic. Architecture dependent code may override this
|
|
* with more suitable version. For example, if the architecture supports
|
|
* crash dump, it should save registers of each stopped CPU and disable
|
|
* per-CPU features such as virtualization extensions.
|
|
*/
|
|
void __weak crash_smp_send_stop(void)
|
|
{
|
|
static int cpus_stopped;
|
|
|
|
/*
|
|
* This function can be called twice in panic path, but obviously
|
|
* we execute this only once.
|
|
*/
|
|
if (cpus_stopped)
|
|
return;
|
|
|
|
/*
|
|
* Note smp_send_stop is the usual smp shutdown function, which
|
|
* unfortunately means it may not be hardened to work in a panic
|
|
* situation.
|
|
*/
|
|
smp_send_stop();
|
|
cpus_stopped = 1;
|
|
}
|
|
|
|
atomic_t panic_cpu = ATOMIC_INIT(PANIC_CPU_INVALID);
|
|
|
|
/*
|
|
* A variant of panic() called from NMI context. We return if we've already
|
|
* panicked on this CPU. If another CPU already panicked, loop in
|
|
* nmi_panic_self_stop() which can provide architecture dependent code such
|
|
* as saving register state for crash dump.
|
|
*/
|
|
void nmi_panic(struct pt_regs *regs, const char *msg)
|
|
{
|
|
int old_cpu, cpu;
|
|
|
|
cpu = raw_smp_processor_id();
|
|
old_cpu = atomic_cmpxchg(&panic_cpu, PANIC_CPU_INVALID, cpu);
|
|
|
|
if (old_cpu == PANIC_CPU_INVALID)
|
|
panic("%s", msg);
|
|
else if (old_cpu != cpu)
|
|
nmi_panic_self_stop(regs);
|
|
}
|
|
EXPORT_SYMBOL(nmi_panic);
|
|
|
|
/**
|
|
* panic - halt the system
|
|
* @fmt: The text string to print
|
|
*
|
|
* Display a message, then perform cleanups.
|
|
*
|
|
* This function never returns.
|
|
*/
|
|
void panic(const char *fmt, ...)
|
|
{
|
|
static char buf[1024];
|
|
va_list args;
|
|
long i, i_next = 0;
|
|
int state = 0;
|
|
int old_cpu, this_cpu;
|
|
bool _crash_kexec_post_notifiers = crash_kexec_post_notifiers;
|
|
|
|
trace_kernel_panic(0);
|
|
|
|
/*
|
|
* Disable local interrupts. This will prevent panic_smp_self_stop
|
|
* from deadlocking the first cpu that invokes the panic, since
|
|
* there is nothing to prevent an interrupt handler (that runs
|
|
* after setting panic_cpu) from invoking panic() again.
|
|
*/
|
|
local_irq_disable();
|
|
|
|
/*
|
|
* It's possible to come here directly from a panic-assertion and
|
|
* not have preempt disabled. Some functions called from here want
|
|
* preempt to be disabled. No point enabling it later though...
|
|
*
|
|
* Only one CPU is allowed to execute the panic code from here. For
|
|
* multiple parallel invocations of panic, all other CPUs either
|
|
* stop themself or will wait until they are stopped by the 1st CPU
|
|
* with smp_send_stop().
|
|
*
|
|
* `old_cpu == PANIC_CPU_INVALID' means this is the 1st CPU which
|
|
* comes here, so go ahead.
|
|
* `old_cpu == this_cpu' means we came from nmi_panic() which sets
|
|
* panic_cpu to this CPU. In this case, this is also the 1st CPU.
|
|
*/
|
|
this_cpu = raw_smp_processor_id();
|
|
old_cpu = atomic_cmpxchg(&panic_cpu, PANIC_CPU_INVALID, this_cpu);
|
|
|
|
if (old_cpu != PANIC_CPU_INVALID && old_cpu != this_cpu)
|
|
panic_smp_self_stop();
|
|
|
|
console_verbose();
|
|
bust_spinlocks(1);
|
|
va_start(args, fmt);
|
|
vsnprintf(buf, sizeof(buf), fmt, args);
|
|
va_end(args);
|
|
dump_stack_minidump(0);
|
|
pr_emerg("Kernel panic - not syncing: %s\n", buf);
|
|
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
|
/*
|
|
* Avoid nested stack-dumping if a panic occurs during oops processing
|
|
*/
|
|
if (!test_taint(TAINT_DIE) && oops_in_progress <= 1)
|
|
dump_stack();
|
|
#endif
|
|
|
|
/*
|
|
* If we have crashed and we have a crash kernel loaded let it handle
|
|
* everything else.
|
|
* If we want to run this after calling panic_notifiers, pass
|
|
* the "crash_kexec_post_notifiers" option to the kernel.
|
|
*
|
|
* Bypass the panic_cpu check and call __crash_kexec directly.
|
|
*/
|
|
if (!_crash_kexec_post_notifiers) {
|
|
printk_nmi_flush_on_panic();
|
|
__crash_kexec(NULL);
|
|
|
|
/*
|
|
* Note smp_send_stop is the usual smp shutdown function, which
|
|
* unfortunately means it may not be hardened to work in a
|
|
* panic situation.
|
|
*/
|
|
smp_send_stop();
|
|
} else {
|
|
/*
|
|
* If we want to do crash dump after notifier calls and
|
|
* kmsg_dump, we will need architecture dependent extra
|
|
* works in addition to stopping other CPUs.
|
|
*/
|
|
crash_smp_send_stop();
|
|
}
|
|
|
|
/*
|
|
* Run any panic handlers, including those that might need to
|
|
* add information to the kmsg dump output.
|
|
*/
|
|
atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
|
|
|
|
/* Call flush even twice. It tries harder with a single online CPU */
|
|
printk_nmi_flush_on_panic();
|
|
kmsg_dump(KMSG_DUMP_PANIC);
|
|
|
|
/*
|
|
* If you doubt kdump always works fine in any situation,
|
|
* "crash_kexec_post_notifiers" offers you a chance to run
|
|
* panic_notifiers and dumping kmsg before kdump.
|
|
* Note: since some panic_notifiers can make crashed kernel
|
|
* more unstable, it can increase risks of the kdump failure too.
|
|
*
|
|
* Bypass the panic_cpu check and call __crash_kexec directly.
|
|
*/
|
|
if (_crash_kexec_post_notifiers)
|
|
__crash_kexec(NULL);
|
|
|
|
#ifdef CONFIG_VT
|
|
unblank_screen();
|
|
#endif
|
|
console_unblank();
|
|
|
|
/*
|
|
* We may have ended up stopping the CPU holding the lock (in
|
|
* smp_send_stop()) while still having some valuable data in the console
|
|
* buffer. Try to acquire the lock then release it regardless of the
|
|
* result. The release will also print the buffers out. Locks debug
|
|
* should be disabled to avoid reporting bad unlock balance when
|
|
* panic() is not being callled from OOPS.
|
|
*/
|
|
debug_locks_off();
|
|
console_flush_on_panic();
|
|
|
|
if (!panic_blink)
|
|
panic_blink = no_blink;
|
|
|
|
if (panic_timeout > 0) {
|
|
/*
|
|
* Delay timeout seconds before rebooting the machine.
|
|
* We can't use the "normal" timers since we just panicked.
|
|
*/
|
|
pr_emerg("Rebooting in %d seconds..\n", panic_timeout);
|
|
|
|
for (i = 0; i < panic_timeout * 1000; i += PANIC_TIMER_STEP) {
|
|
touch_nmi_watchdog();
|
|
if (i >= i_next) {
|
|
i += panic_blink(state ^= 1);
|
|
i_next = i + 3600 / PANIC_BLINK_SPD;
|
|
}
|
|
mdelay(PANIC_TIMER_STEP);
|
|
}
|
|
}
|
|
|
|
trace_kernel_panic_late(0);
|
|
|
|
if (panic_timeout != 0) {
|
|
/*
|
|
* This will not be a clean reboot, with everything
|
|
* shutting down. But if there is a chance of
|
|
* rebooting the system it will be rebooted.
|
|
*/
|
|
emergency_restart();
|
|
}
|
|
#ifdef __sparc__
|
|
{
|
|
extern int stop_a_enabled;
|
|
/* Make sure the user can actually press Stop-A (L1-A) */
|
|
stop_a_enabled = 1;
|
|
pr_emerg("Press Stop-A (L1-A) to return to the boot prom\n");
|
|
}
|
|
#endif
|
|
#if defined(CONFIG_S390)
|
|
{
|
|
unsigned long caller;
|
|
|
|
caller = (unsigned long)__builtin_return_address(0);
|
|
disabled_wait(caller);
|
|
}
|
|
#endif
|
|
pr_emerg("---[ end Kernel panic - not syncing: %s\n", buf);
|
|
local_irq_enable();
|
|
for (i = 0; ; i += PANIC_TIMER_STEP) {
|
|
touch_softlockup_watchdog();
|
|
if (i >= i_next) {
|
|
i += panic_blink(state ^= 1);
|
|
i_next = i + 3600 / PANIC_BLINK_SPD;
|
|
}
|
|
mdelay(PANIC_TIMER_STEP);
|
|
}
|
|
}
|
|
|
|
EXPORT_SYMBOL(panic);
|
|
|
|
|
|
struct tnt {
|
|
u8 bit;
|
|
char true;
|
|
char false;
|
|
};
|
|
|
|
static const struct tnt tnts[] = {
|
|
{ TAINT_PROPRIETARY_MODULE, 'P', 'G' },
|
|
{ TAINT_FORCED_MODULE, 'F', ' ' },
|
|
{ TAINT_CPU_OUT_OF_SPEC, 'S', ' ' },
|
|
{ TAINT_FORCED_RMMOD, 'R', ' ' },
|
|
{ TAINT_MACHINE_CHECK, 'M', ' ' },
|
|
{ TAINT_BAD_PAGE, 'B', ' ' },
|
|
{ TAINT_USER, 'U', ' ' },
|
|
{ TAINT_DIE, 'D', ' ' },
|
|
{ TAINT_OVERRIDDEN_ACPI_TABLE, 'A', ' ' },
|
|
{ TAINT_WARN, 'W', ' ' },
|
|
{ TAINT_CRAP, 'C', ' ' },
|
|
{ TAINT_FIRMWARE_WORKAROUND, 'I', ' ' },
|
|
{ TAINT_OOT_MODULE, 'O', ' ' },
|
|
{ TAINT_UNSIGNED_MODULE, 'E', ' ' },
|
|
{ TAINT_SOFTLOCKUP, 'L', ' ' },
|
|
{ TAINT_LIVEPATCH, 'K', ' ' },
|
|
};
|
|
|
|
/**
|
|
* print_tainted - return a string to represent the kernel taint state.
|
|
*
|
|
* 'P' - Proprietary module has been loaded.
|
|
* 'F' - Module has been forcibly loaded.
|
|
* 'S' - SMP with CPUs not designed for SMP.
|
|
* 'R' - User forced a module unload.
|
|
* 'M' - System experienced a machine check exception.
|
|
* 'B' - System has hit bad_page.
|
|
* 'U' - Userspace-defined naughtiness.
|
|
* 'D' - Kernel has oopsed before
|
|
* 'A' - ACPI table overridden.
|
|
* 'W' - Taint on warning.
|
|
* 'C' - modules from drivers/staging are loaded.
|
|
* 'I' - Working around severe firmware bug.
|
|
* 'O' - Out-of-tree module has been loaded.
|
|
* 'E' - Unsigned module has been loaded.
|
|
* 'L' - A soft lockup has previously occurred.
|
|
* 'K' - Kernel has been live patched.
|
|
*
|
|
* The string is overwritten by the next call to print_tainted().
|
|
*/
|
|
const char *print_tainted(void)
|
|
{
|
|
static char buf[ARRAY_SIZE(tnts) + sizeof("Tainted: ")];
|
|
|
|
if (tainted_mask) {
|
|
char *s;
|
|
int i;
|
|
|
|
s = buf + sprintf(buf, "Tainted: ");
|
|
for (i = 0; i < ARRAY_SIZE(tnts); i++) {
|
|
const struct tnt *t = &tnts[i];
|
|
*s++ = test_bit(t->bit, &tainted_mask) ?
|
|
t->true : t->false;
|
|
}
|
|
*s = 0;
|
|
} else
|
|
snprintf(buf, sizeof(buf), "Not tainted");
|
|
|
|
return buf;
|
|
}
|
|
|
|
int test_taint(unsigned flag)
|
|
{
|
|
return test_bit(flag, &tainted_mask);
|
|
}
|
|
EXPORT_SYMBOL(test_taint);
|
|
|
|
unsigned long get_taint(void)
|
|
{
|
|
return tainted_mask;
|
|
}
|
|
|
|
/**
|
|
* add_taint: add a taint flag if not already set.
|
|
* @flag: one of the TAINT_* constants.
|
|
* @lockdep_ok: whether lock debugging is still OK.
|
|
*
|
|
* If something bad has gone wrong, you'll want @lockdebug_ok = false, but for
|
|
* some notewortht-but-not-corrupting cases, it can be set to true.
|
|
*/
|
|
void add_taint(unsigned flag, enum lockdep_ok lockdep_ok)
|
|
{
|
|
if (lockdep_ok == LOCKDEP_NOW_UNRELIABLE && __debug_locks_off())
|
|
pr_warn("Disabling lock debugging due to kernel taint\n");
|
|
|
|
set_bit(flag, &tainted_mask);
|
|
}
|
|
EXPORT_SYMBOL(add_taint);
|
|
|
|
static void spin_msec(int msecs)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < msecs; i++) {
|
|
touch_nmi_watchdog();
|
|
mdelay(1);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* It just happens that oops_enter() and oops_exit() are identically
|
|
* implemented...
|
|
*/
|
|
static void do_oops_enter_exit(void)
|
|
{
|
|
unsigned long flags;
|
|
static int spin_counter;
|
|
|
|
if (!pause_on_oops)
|
|
return;
|
|
|
|
spin_lock_irqsave(&pause_on_oops_lock, flags);
|
|
if (pause_on_oops_flag == 0) {
|
|
/* This CPU may now print the oops message */
|
|
pause_on_oops_flag = 1;
|
|
} else {
|
|
/* We need to stall this CPU */
|
|
if (!spin_counter) {
|
|
/* This CPU gets to do the counting */
|
|
spin_counter = pause_on_oops;
|
|
do {
|
|
spin_unlock(&pause_on_oops_lock);
|
|
spin_msec(MSEC_PER_SEC);
|
|
spin_lock(&pause_on_oops_lock);
|
|
} while (--spin_counter);
|
|
pause_on_oops_flag = 0;
|
|
} else {
|
|
/* This CPU waits for a different one */
|
|
while (spin_counter) {
|
|
spin_unlock(&pause_on_oops_lock);
|
|
spin_msec(1);
|
|
spin_lock(&pause_on_oops_lock);
|
|
}
|
|
}
|
|
}
|
|
spin_unlock_irqrestore(&pause_on_oops_lock, flags);
|
|
}
|
|
|
|
/*
|
|
* Return true if the calling CPU is allowed to print oops-related info.
|
|
* This is a bit racy..
|
|
*/
|
|
int oops_may_print(void)
|
|
{
|
|
return pause_on_oops_flag == 0;
|
|
}
|
|
|
|
/*
|
|
* Called when the architecture enters its oops handler, before it prints
|
|
* anything. If this is the first CPU to oops, and it's oopsing the first
|
|
* time then let it proceed.
|
|
*
|
|
* This is all enabled by the pause_on_oops kernel boot option. We do all
|
|
* this to ensure that oopses don't scroll off the screen. It has the
|
|
* side-effect of preventing later-oopsing CPUs from mucking up the display,
|
|
* too.
|
|
*
|
|
* It turns out that the CPU which is allowed to print ends up pausing for
|
|
* the right duration, whereas all the other CPUs pause for twice as long:
|
|
* once in oops_enter(), once in oops_exit().
|
|
*/
|
|
void oops_enter(void)
|
|
{
|
|
tracing_off();
|
|
/* can't trust the integrity of the kernel anymore: */
|
|
debug_locks_off();
|
|
do_oops_enter_exit();
|
|
}
|
|
|
|
/*
|
|
* 64-bit random ID for oopses:
|
|
*/
|
|
static u64 oops_id;
|
|
|
|
static int init_oops_id(void)
|
|
{
|
|
if (!oops_id)
|
|
get_random_bytes(&oops_id, sizeof(oops_id));
|
|
else
|
|
oops_id++;
|
|
|
|
return 0;
|
|
}
|
|
late_initcall(init_oops_id);
|
|
|
|
void print_oops_end_marker(void)
|
|
{
|
|
init_oops_id();
|
|
pr_warn("---[ end trace %016llx ]---\n", (unsigned long long)oops_id);
|
|
}
|
|
|
|
/*
|
|
* Called when the architecture exits its oops handler, after printing
|
|
* everything.
|
|
*/
|
|
void oops_exit(void)
|
|
{
|
|
do_oops_enter_exit();
|
|
print_oops_end_marker();
|
|
kmsg_dump(KMSG_DUMP_OOPS);
|
|
}
|
|
|
|
struct warn_args {
|
|
const char *fmt;
|
|
va_list args;
|
|
};
|
|
|
|
void __warn(const char *file, int line, void *caller, unsigned taint,
|
|
struct pt_regs *regs, struct warn_args *args)
|
|
{
|
|
disable_trace_on_warning();
|
|
|
|
pr_warn("------------[ cut here ]------------\n");
|
|
|
|
if (file)
|
|
pr_warn("WARNING: CPU: %d PID: %d at %s:%d %pS\n",
|
|
raw_smp_processor_id(), current->pid, file, line,
|
|
caller);
|
|
else
|
|
pr_warn("WARNING: CPU: %d PID: %d at %pS\n",
|
|
raw_smp_processor_id(), current->pid, caller);
|
|
|
|
if (args)
|
|
vprintk(args->fmt, args->args);
|
|
|
|
if (panic_on_warn) {
|
|
/*
|
|
* This thread may hit another WARN() in the panic path.
|
|
* Resetting this prevents additional WARN() from panicking the
|
|
* system on this thread. Other threads are blocked by the
|
|
* panic_mutex in panic().
|
|
*/
|
|
panic_on_warn = 0;
|
|
panic("panic_on_warn set ...\n");
|
|
}
|
|
|
|
print_modules();
|
|
|
|
if (regs)
|
|
show_regs(regs);
|
|
else
|
|
dump_stack();
|
|
|
|
print_oops_end_marker();
|
|
|
|
/* Just a warning, don't kill lockdep. */
|
|
add_taint(taint, LOCKDEP_STILL_OK);
|
|
}
|
|
|
|
#ifdef WANT_WARN_ON_SLOWPATH
|
|
void warn_slowpath_fmt(const char *file, int line, const char *fmt, ...)
|
|
{
|
|
struct warn_args args;
|
|
|
|
args.fmt = fmt;
|
|
va_start(args.args, fmt);
|
|
__warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL,
|
|
&args);
|
|
va_end(args.args);
|
|
}
|
|
EXPORT_SYMBOL(warn_slowpath_fmt);
|
|
|
|
void warn_slowpath_fmt_taint(const char *file, int line,
|
|
unsigned taint, const char *fmt, ...)
|
|
{
|
|
struct warn_args args;
|
|
|
|
args.fmt = fmt;
|
|
va_start(args.args, fmt);
|
|
__warn(file, line, __builtin_return_address(0), taint, NULL, &args);
|
|
va_end(args.args);
|
|
}
|
|
EXPORT_SYMBOL(warn_slowpath_fmt_taint);
|
|
|
|
void warn_slowpath_null(const char *file, int line)
|
|
{
|
|
__warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, NULL);
|
|
}
|
|
EXPORT_SYMBOL(warn_slowpath_null);
|
|
#endif
|
|
|
|
#ifdef CONFIG_CC_STACKPROTECTOR
|
|
|
|
/*
|
|
* Called when gcc's -fstack-protector feature is used, and
|
|
* gcc detects corruption of the on-stack canary value
|
|
*/
|
|
__visible void __stack_chk_fail(void)
|
|
{
|
|
panic("stack-protector: Kernel stack is corrupted in: %p\n",
|
|
__builtin_return_address(0));
|
|
}
|
|
EXPORT_SYMBOL(__stack_chk_fail);
|
|
|
|
#endif
|
|
|
|
core_param(panic, panic_timeout, int, 0644);
|
|
core_param(pause_on_oops, pause_on_oops, int, 0644);
|
|
core_param(panic_on_warn, panic_on_warn, int, 0644);
|
|
core_param(crash_kexec_post_notifiers, crash_kexec_post_notifiers, bool, 0644);
|
|
|
|
static int __init oops_setup(char *s)
|
|
{
|
|
if (!s)
|
|
return -EINVAL;
|
|
if (!strcmp(s, "panic"))
|
|
panic_on_oops = 1;
|
|
return 0;
|
|
}
|
|
early_param("oops", oops_setup);
|