Merge branch 'akpm' (patches from Andrew)

Merge more updates from Andrew Morton:
 "Various misc subsystems, before getting into the post-linux-next
  material.

  41 patches.

  Subsystems affected by this patch series: procfs, misc, core-kernel,
  lib, checkpatch, init, pipe, minix, fat, cgroups, kexec, kdump,
  taskstats, panic, kcov, resource, and ubsan"

* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (41 commits)
  Revert "ubsan, kcsan: Don't combine sanitizer with kcov on clang"
  kernel/resource: fix kfree() of bootmem memory again
  kcov: properly handle subsequent mmap calls
  kcov: split ioctl handling into locked and unlocked parts
  panic: move panic_print before kmsg dumpers
  panic: add option to dump all CPUs backtraces in panic_print
  docs: sysctl/kernel: add missing bit to panic_print
  taskstats: remove unneeded dead assignment
  kasan: no need to unset panic_on_warn in end_report()
  ubsan: no need to unset panic_on_warn in ubsan_epilogue()
  panic: unset panic_on_warn inside panic()
  docs: kdump: add scp example to write out the dump file
  docs: kdump: update description about sysfs file system support
  arm64: mm: use IS_ENABLED(CONFIG_KEXEC_CORE) instead of #ifdef
  x86/setup: use IS_ENABLED(CONFIG_KEXEC_CORE) instead of #ifdef
  riscv: mm: init: use IS_ENABLED(CONFIG_KEXEC_CORE) instead of #ifdef
  kexec: make crashk_res, crashk_low_res and crash_notes symbols always visible
  cgroup: use irqsave in cgroup_rstat_flush_locked().
  fat: use pointer to simple type in put_user()
  minix: fix bug when opening a file with O_DIRECT
  ...
This commit is contained in:
Linus Torvalds 2022-03-24 14:14:07 -07:00
commit 52deda9551
34 changed files with 311 additions and 303 deletions

View File

@ -146,9 +146,9 @@ System kernel config options
CONFIG_SYSFS=y CONFIG_SYSFS=y
Note that "sysfs file system support" might not appear in the "Pseudo Note that "sysfs file system support" might not appear in the "Pseudo
filesystems" menu if "Configure standard kernel features (for small filesystems" menu if "Configure standard kernel features (expert users)"
systems)" is not enabled in "General Setup." In this case, check the is not enabled in "General Setup." In this case, check the .config file
.config file itself to ensure that sysfs is turned on, as follows:: itself to ensure that sysfs is turned on, as follows::
grep 'CONFIG_SYSFS' .config grep 'CONFIG_SYSFS' .config
@ -533,6 +533,10 @@ the following command::
cp /proc/vmcore <dump-file> cp /proc/vmcore <dump-file>
or use scp to write out the dump file between hosts on a network, e.g::
scp /proc/vmcore remote_username@remote_ip:<dump-file>
You can also use makedumpfile utility to write out the dump file You can also use makedumpfile utility to write out the dump file
with specified options to filter out unwanted contents, e.g:: with specified options to filter out unwanted contents, e.g::

View File

@ -3792,6 +3792,11 @@
bit 3: print locks info if CONFIG_LOCKDEP is on bit 3: print locks info if CONFIG_LOCKDEP is on
bit 4: print ftrace buffer bit 4: print ftrace buffer
bit 5: print all printk messages in buffer bit 5: print all printk messages in buffer
bit 6: print all CPUs backtrace (if available in the arch)
*Be aware* that this option may print a _lot_ of lines,
so there are risks of losing older messages in the log.
Use this option carefully, maybe worth to setup a
bigger log buffer with "log_buf_len" along with this.
panic_on_taint= Bitmask for conditionally calling panic() in add_taint() panic_on_taint= Bitmask for conditionally calling panic() in add_taint()
Format: <hex>[,nousertaint] Format: <hex>[,nousertaint]

View File

@ -763,6 +763,8 @@ bit 1 print system memory info
bit 2 print timer info bit 2 print timer info
bit 3 print locks info if ``CONFIG_LOCKDEP`` is on bit 3 print locks info if ``CONFIG_LOCKDEP`` is on
bit 4 print ftrace buffer bit 4 print ftrace buffer
bit 5 print all printk messages in buffer
bit 6 print all CPUs backtrace (if available in the arch)
===== ============================================ ===== ============================================
So for example to print tasks and memory info on panic, user can:: So for example to print tasks and memory info on panic, user can::

View File

@ -100,3 +100,5 @@ have already built it.
The optional make variable CF can be used to pass arguments to sparse. The The optional make variable CF can be used to pass arguments to sparse. The
build system passes -Wbitwise to sparse automatically. build system passes -Wbitwise to sparse automatically.
Note that sparse defines the __CHECKER__ preprocessor symbol.

View File

@ -90,7 +90,6 @@ phys_addr_t __ro_after_init arm64_dma_phys_limit;
phys_addr_t __ro_after_init arm64_dma_phys_limit = PHYS_MASK + 1; phys_addr_t __ro_after_init arm64_dma_phys_limit = PHYS_MASK + 1;
#endif #endif
#ifdef CONFIG_KEXEC_CORE
/* /*
* reserve_crashkernel() - reserves memory for crash kernel * reserve_crashkernel() - reserves memory for crash kernel
* *
@ -104,6 +103,9 @@ static void __init reserve_crashkernel(void)
unsigned long long crash_max = arm64_dma_phys_limit; unsigned long long crash_max = arm64_dma_phys_limit;
int ret; int ret;
if (!IS_ENABLED(CONFIG_KEXEC_CORE))
return;
ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(), ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
&crash_size, &crash_base); &crash_size, &crash_base);
/* no crashkernel= or invalid value specified */ /* no crashkernel= or invalid value specified */
@ -136,11 +138,6 @@ static void __init reserve_crashkernel(void)
crashk_res.start = crash_base; crashk_res.start = crash_base;
crashk_res.end = crash_base + crash_size - 1; crashk_res.end = crash_base + crash_size - 1;
} }
#else
static void __init reserve_crashkernel(void)
{
}
#endif /* CONFIG_KEXEC_CORE */
/* /*
* Return the maximum physical address for a zone accessible by the given bits * Return the maximum physical address for a zone accessible by the given bits

View File

@ -957,7 +957,6 @@ static inline void setup_vm_final(void)
} }
#endif /* CONFIG_MMU */ #endif /* CONFIG_MMU */
#ifdef CONFIG_KEXEC_CORE
/* /*
* reserve_crashkernel() - reserves memory for crash kernel * reserve_crashkernel() - reserves memory for crash kernel
* *
@ -974,6 +973,8 @@ static void __init reserve_crashkernel(void)
int ret = 0; int ret = 0;
if (!IS_ENABLED(CONFIG_KEXEC_CORE))
return;
/* /*
* Don't reserve a region for a crash kernel on a crash kernel * Don't reserve a region for a crash kernel on a crash kernel
* since it doesn't make much sense and we have limited memory * since it doesn't make much sense and we have limited memory
@ -1023,7 +1024,6 @@ static void __init reserve_crashkernel(void)
crashk_res.start = crash_base; crashk_res.start = crash_base;
crashk_res.end = crash_base + crash_size - 1; crashk_res.end = crash_base + crash_size - 1;
} }
#endif /* CONFIG_KEXEC_CORE */
void __init paging_init(void) void __init paging_init(void)
{ {
@ -1037,9 +1037,7 @@ void __init misc_mem_init(void)
arch_numa_init(); arch_numa_init();
sparse_init(); sparse_init();
zone_sizes_init(); zone_sizes_init();
#ifdef CONFIG_KEXEC_CORE
reserve_crashkernel(); reserve_crashkernel();
#endif
memblock_dump_all(); memblock_dump_all();
} }

View File

@ -411,8 +411,6 @@ static void __init memblock_x86_reserve_range_setup_data(void)
* --------- Crashkernel reservation ------------------------------ * --------- Crashkernel reservation ------------------------------
*/ */
#ifdef CONFIG_KEXEC_CORE
/* 16M alignment for crash kernel regions */ /* 16M alignment for crash kernel regions */
#define CRASH_ALIGN SZ_16M #define CRASH_ALIGN SZ_16M
@ -490,6 +488,9 @@ static void __init reserve_crashkernel(void)
bool high = false; bool high = false;
int ret; int ret;
if (!IS_ENABLED(CONFIG_KEXEC_CORE))
return;
total_mem = memblock_phys_mem_size(); total_mem = memblock_phys_mem_size();
/* crashkernel=XM */ /* crashkernel=XM */
@ -555,11 +556,6 @@ static void __init reserve_crashkernel(void)
crashk_res.end = crash_base + crash_size - 1; crashk_res.end = crash_base + crash_size - 1;
insert_resource(&iomem_resource, &crashk_res); insert_resource(&iomem_resource, &crashk_res);
} }
#else
static void __init reserve_crashkernel(void)
{
}
#endif
static struct resource standard_io_resources[] = { static struct resource standard_io_resources[] = {
{ .name = "dma1", .start = 0x00, .end = 0x1f, { .name = "dma1", .start = 0x00, .end = 0x1f,

View File

@ -722,7 +722,7 @@ static int func(struct dir_context *ctx, const char *name, int name_len, \
if (name_len >= sizeof(d1->d_name)) \ if (name_len >= sizeof(d1->d_name)) \
name_len = sizeof(d1->d_name) - 1; \ name_len = sizeof(d1->d_name) - 1; \
\ \
if (put_user(0, d2->d_name) || \ if (put_user(0, &d2->d_name[0]) || \
put_user(0, &d2->d_reclen) || \ put_user(0, &d2->d_reclen) || \
copy_to_user(d1->d_name, name, name_len) || \ copy_to_user(d1->d_name, name, name_len) || \
put_user(0, d1->d_name + name_len) || \ put_user(0, d1->d_name + name_len) || \

View File

@ -448,7 +448,8 @@ static const struct address_space_operations minix_aops = {
.writepage = minix_writepage, .writepage = minix_writepage,
.write_begin = minix_write_begin, .write_begin = minix_write_begin,
.write_end = generic_write_end, .write_end = generic_write_end,
.bmap = minix_bmap .bmap = minix_bmap,
.direct_IO = noop_direct_IO
}; };
static const struct inode_operations minix_symlink_inode_operations = { static const struct inode_operations minix_symlink_inode_operations = {

View File

@ -607,7 +607,7 @@ out:
static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{ {
struct pipe_inode_info *pipe = filp->private_data; struct pipe_inode_info *pipe = filp->private_data;
int count, head, tail, mask; unsigned int count, head, tail, mask;
switch (cmd) { switch (cmd) {
case FIONREAD: case FIONREAD:
@ -804,7 +804,7 @@ struct pipe_inode_info *alloc_pipe_info(void)
if (too_many_pipe_buffers_hard(user_bufs) && pipe_is_unprivileged_user()) if (too_many_pipe_buffers_hard(user_bufs) && pipe_is_unprivileged_user())
goto out_revert_acct; goto out_revert_acct;
pipe->bufs = kcalloc(pipe_bufs, sizeof(struct pipe_buffer), pipe->bufs = kvcalloc(pipe_bufs, sizeof(struct pipe_buffer),
GFP_KERNEL_ACCOUNT); GFP_KERNEL_ACCOUNT);
if (pipe->bufs) { if (pipe->bufs) {
@ -829,7 +829,7 @@ out_free_uid:
void free_pipe_info(struct pipe_inode_info *pipe) void free_pipe_info(struct pipe_inode_info *pipe)
{ {
int i; unsigned int i;
#ifdef CONFIG_WATCH_QUEUE #ifdef CONFIG_WATCH_QUEUE
if (pipe->watch_queue) if (pipe->watch_queue)
@ -849,7 +849,7 @@ void free_pipe_info(struct pipe_inode_info *pipe)
#endif #endif
if (pipe->tmp_page) if (pipe->tmp_page)
__free_page(pipe->tmp_page); __free_page(pipe->tmp_page);
kfree(pipe->bufs); kvfree(pipe->bufs);
kfree(pipe); kfree(pipe);
} }
@ -1264,8 +1264,7 @@ int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots)
if (nr_slots < n) if (nr_slots < n)
return -EBUSY; return -EBUSY;
bufs = kcalloc(nr_slots, sizeof(*bufs), bufs = kvcalloc(nr_slots, sizeof(*bufs), GFP_KERNEL_ACCOUNT);
GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
if (unlikely(!bufs)) if (unlikely(!bufs))
return -ENOMEM; return -ENOMEM;
@ -1292,7 +1291,7 @@ int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots)
head = n; head = n;
tail = 0; tail = 0;
kfree(pipe->bufs); kvfree(pipe->bufs);
pipe->bufs = bufs; pipe->bufs = bufs;
pipe->ring_size = nr_slots; pipe->ring_size = nr_slots;
if (pipe->max_usage > nr_slots) if (pipe->max_usage > nr_slots)

View File

@ -1764,25 +1764,25 @@ out:
static int do_proc_readlink(struct path *path, char __user *buffer, int buflen) static int do_proc_readlink(struct path *path, char __user *buffer, int buflen)
{ {
char *tmp = (char *)__get_free_page(GFP_KERNEL); char *tmp = kmalloc(PATH_MAX, GFP_KERNEL);
char *pathname; char *pathname;
int len; int len;
if (!tmp) if (!tmp)
return -ENOMEM; return -ENOMEM;
pathname = d_path(path, tmp, PAGE_SIZE); pathname = d_path(path, tmp, PATH_MAX);
len = PTR_ERR(pathname); len = PTR_ERR(pathname);
if (IS_ERR(pathname)) if (IS_ERR(pathname))
goto out; goto out;
len = tmp + PAGE_SIZE - 1 - pathname; len = tmp + PATH_MAX - 1 - pathname;
if (len > buflen) if (len > buflen)
len = buflen; len = buflen;
if (copy_to_user(buffer, pathname, len)) if (copy_to_user(buffer, pathname, len))
len = -EFAULT; len = -EFAULT;
out: out:
free_page((unsigned long)tmp); kfree(tmp);
return len; return len;
} }

View File

@ -62,7 +62,8 @@ core_param(novmcoredd, vmcoredd_disabled, bool, 0);
/* Device Dump Size */ /* Device Dump Size */
static size_t vmcoredd_orig_sz; static size_t vmcoredd_orig_sz;
static DECLARE_RWSEM(vmcore_cb_rwsem); static DEFINE_SPINLOCK(vmcore_cb_lock);
DEFINE_STATIC_SRCU(vmcore_cb_srcu);
/* List of registered vmcore callbacks. */ /* List of registered vmcore callbacks. */
static LIST_HEAD(vmcore_cb_list); static LIST_HEAD(vmcore_cb_list);
/* Whether the vmcore has been opened once. */ /* Whether the vmcore has been opened once. */
@ -70,8 +71,8 @@ static bool vmcore_opened;
void register_vmcore_cb(struct vmcore_cb *cb) void register_vmcore_cb(struct vmcore_cb *cb)
{ {
down_write(&vmcore_cb_rwsem);
INIT_LIST_HEAD(&cb->next); INIT_LIST_HEAD(&cb->next);
spin_lock(&vmcore_cb_lock);
list_add_tail(&cb->next, &vmcore_cb_list); list_add_tail(&cb->next, &vmcore_cb_list);
/* /*
* Registering a vmcore callback after the vmcore was opened is * Registering a vmcore callback after the vmcore was opened is
@ -79,14 +80,14 @@ void register_vmcore_cb(struct vmcore_cb *cb)
*/ */
if (vmcore_opened) if (vmcore_opened)
pr_warn_once("Unexpected vmcore callback registration\n"); pr_warn_once("Unexpected vmcore callback registration\n");
up_write(&vmcore_cb_rwsem); spin_unlock(&vmcore_cb_lock);
} }
EXPORT_SYMBOL_GPL(register_vmcore_cb); EXPORT_SYMBOL_GPL(register_vmcore_cb);
void unregister_vmcore_cb(struct vmcore_cb *cb) void unregister_vmcore_cb(struct vmcore_cb *cb)
{ {
down_write(&vmcore_cb_rwsem); spin_lock(&vmcore_cb_lock);
list_del(&cb->next); list_del_rcu(&cb->next);
/* /*
* Unregistering a vmcore callback after the vmcore was opened is * Unregistering a vmcore callback after the vmcore was opened is
* very unusual (e.g., forced driver removal), but we cannot stop * very unusual (e.g., forced driver removal), but we cannot stop
@ -94,7 +95,9 @@ void unregister_vmcore_cb(struct vmcore_cb *cb)
*/ */
if (vmcore_opened) if (vmcore_opened)
pr_warn_once("Unexpected vmcore callback unregistration\n"); pr_warn_once("Unexpected vmcore callback unregistration\n");
up_write(&vmcore_cb_rwsem); spin_unlock(&vmcore_cb_lock);
synchronize_srcu(&vmcore_cb_srcu);
} }
EXPORT_SYMBOL_GPL(unregister_vmcore_cb); EXPORT_SYMBOL_GPL(unregister_vmcore_cb);
@ -103,9 +106,8 @@ static bool pfn_is_ram(unsigned long pfn)
struct vmcore_cb *cb; struct vmcore_cb *cb;
bool ret = true; bool ret = true;
lockdep_assert_held_read(&vmcore_cb_rwsem); list_for_each_entry_srcu(cb, &vmcore_cb_list, next,
srcu_read_lock_held(&vmcore_cb_srcu)) {
list_for_each_entry(cb, &vmcore_cb_list, next) {
if (unlikely(!cb->pfn_is_ram)) if (unlikely(!cb->pfn_is_ram))
continue; continue;
ret = cb->pfn_is_ram(cb, pfn); ret = cb->pfn_is_ram(cb, pfn);
@ -118,9 +120,9 @@ static bool pfn_is_ram(unsigned long pfn)
static int open_vmcore(struct inode *inode, struct file *file) static int open_vmcore(struct inode *inode, struct file *file)
{ {
down_read(&vmcore_cb_rwsem); spin_lock(&vmcore_cb_lock);
vmcore_opened = true; vmcore_opened = true;
up_read(&vmcore_cb_rwsem); spin_unlock(&vmcore_cb_lock);
return 0; return 0;
} }
@ -133,6 +135,7 @@ ssize_t read_from_oldmem(char *buf, size_t count,
unsigned long pfn, offset; unsigned long pfn, offset;
size_t nr_bytes; size_t nr_bytes;
ssize_t read = 0, tmp; ssize_t read = 0, tmp;
int idx;
if (!count) if (!count)
return 0; return 0;
@ -140,7 +143,7 @@ ssize_t read_from_oldmem(char *buf, size_t count,
offset = (unsigned long)(*ppos % PAGE_SIZE); offset = (unsigned long)(*ppos % PAGE_SIZE);
pfn = (unsigned long)(*ppos / PAGE_SIZE); pfn = (unsigned long)(*ppos / PAGE_SIZE);
down_read(&vmcore_cb_rwsem); idx = srcu_read_lock(&vmcore_cb_srcu);
do { do {
if (count > (PAGE_SIZE - offset)) if (count > (PAGE_SIZE - offset))
nr_bytes = PAGE_SIZE - offset; nr_bytes = PAGE_SIZE - offset;
@ -165,7 +168,7 @@ ssize_t read_from_oldmem(char *buf, size_t count,
offset, userbuf); offset, userbuf);
} }
if (tmp < 0) { if (tmp < 0) {
up_read(&vmcore_cb_rwsem); srcu_read_unlock(&vmcore_cb_srcu, idx);
return tmp; return tmp;
} }
@ -176,8 +179,8 @@ ssize_t read_from_oldmem(char *buf, size_t count,
++pfn; ++pfn;
offset = 0; offset = 0;
} while (count); } while (count);
srcu_read_unlock(&vmcore_cb_srcu, idx);
up_read(&vmcore_cb_rwsem);
return read; return read;
} }
@ -477,7 +480,7 @@ static const struct vm_operations_struct vmcore_mmap_ops = {
/** /**
* vmcore_alloc_buf - allocate buffer in vmalloc memory * vmcore_alloc_buf - allocate buffer in vmalloc memory
* @sizez: size of buffer * @size: size of buffer
* *
* If CONFIG_MMU is defined, use vmalloc_user() to allow users to mmap * If CONFIG_MMU is defined, use vmalloc_user() to allow users to mmap
* the buffer to user-space by means of remap_vmalloc_range(). * the buffer to user-space by means of remap_vmalloc_range().
@ -568,18 +571,18 @@ static int vmcore_remap_oldmem_pfn(struct vm_area_struct *vma,
unsigned long from, unsigned long pfn, unsigned long from, unsigned long pfn,
unsigned long size, pgprot_t prot) unsigned long size, pgprot_t prot)
{ {
int ret; int ret, idx;
/* /*
* Check if oldmem_pfn_is_ram was registered to avoid * Check if a callback was registered to avoid looping over all
* looping over all pages without a reason. * pages without a reason.
*/ */
down_read(&vmcore_cb_rwsem); idx = srcu_read_lock(&vmcore_cb_srcu);
if (!list_empty(&vmcore_cb_list)) if (!list_empty(&vmcore_cb_list))
ret = remap_oldmem_pfn_checked(vma, from, pfn, size, prot); ret = remap_oldmem_pfn_checked(vma, from, pfn, size, prot);
else else
ret = remap_oldmem_pfn_range(vma, from, pfn, size, prot); ret = remap_oldmem_pfn_range(vma, from, pfn, size, prot);
up_read(&vmcore_cb_rwsem); srcu_read_unlock(&vmcore_cb_srcu, idx);
return ret; return ret;
} }

View File

@ -19,6 +19,9 @@
* *
* Example: * Example:
* *
* #include <linux/bitfield.h>
* #include <linux/bits.h>
*
* #define REG_FIELD_A GENMASK(6, 0) * #define REG_FIELD_A GENMASK(6, 0)
* #define REG_FIELD_B BIT(7) * #define REG_FIELD_B BIT(7)
* #define REG_FIELD_C GENMASK(15, 8) * #define REG_FIELD_C GENMASK(15, 8)

View File

@ -11,6 +11,7 @@
# define BTF_TYPE_TAG(value) /* nothing */ # define BTF_TYPE_TAG(value) /* nothing */
#endif #endif
/* sparse defines __CHECKER__; see Documentation/dev-tools/sparse.rst */
#ifdef __CHECKER__ #ifdef __CHECKER__
/* address spaces */ /* address spaces */
# define __kernel __attribute__((address_space(0))) # define __kernel __attribute__((address_space(0)))
@ -144,8 +145,6 @@ struct ftrace_likely_data {
*/ */
#define __naked __attribute__((__naked__)) notrace #define __naked __attribute__((__naked__)) notrace
#define __compiler_offsetof(a, b) __builtin_offsetof(a, b)
/* /*
* Prefer gnu_inline, so that extern inline functions do not emit an * Prefer gnu_inline, so that extern inline functions do not emit an
* externally visible function. This makes extern inline behave as per gnu89 * externally visible function. This makes extern inline behave as per gnu89

View File

@ -320,12 +320,19 @@ struct obs_kernel_param {
__aligned(__alignof__(struct obs_kernel_param)) \ __aligned(__alignof__(struct obs_kernel_param)) \
= { __setup_str_##unique_id, fn, early } = { __setup_str_##unique_id, fn, early }
/*
* NOTE: __setup functions return values:
* @fn returns 1 (or non-zero) if the option argument is "handled"
* and returns 0 if the option argument is "not handled".
*/
#define __setup(str, fn) \ #define __setup(str, fn) \
__setup_param(str, fn, fn, 0) __setup_param(str, fn, fn, 0)
/* /*
* NOTE: fn is as per module_param, not __setup! * NOTE: @fn is as per module_param, not __setup!
* Emits warning if fn returns non-zero. * I.e., @fn returns 0 for no error or non-zero for error
* (possibly @fn returns a -errno value, but it does not matter).
* Emits warning if @fn returns non-zero.
*/ */
#define early_param(str, fn) \ #define early_param(str, fn) \
__setup_param(str, fn, fn, 1) __setup_param(str, fn, fn, 1)

View File

@ -20,6 +20,12 @@
#include <uapi/linux/kexec.h> #include <uapi/linux/kexec.h>
/* Location of a reserved region to hold the crash kernel.
*/
extern struct resource crashk_res;
extern struct resource crashk_low_res;
extern note_buf_t __percpu *crash_notes;
#ifdef CONFIG_KEXEC_CORE #ifdef CONFIG_KEXEC_CORE
#include <linux/list.h> #include <linux/list.h>
#include <linux/compat.h> #include <linux/compat.h>
@ -350,12 +356,6 @@ extern int kexec_load_disabled;
#define KEXEC_FILE_FLAGS (KEXEC_FILE_UNLOAD | KEXEC_FILE_ON_CRASH | \ #define KEXEC_FILE_FLAGS (KEXEC_FILE_UNLOAD | KEXEC_FILE_ON_CRASH | \
KEXEC_FILE_NO_INITRAMFS) KEXEC_FILE_NO_INITRAMFS)
/* Location of a reserved region to hold the crash kernel.
*/
extern struct resource crashk_res;
extern struct resource crashk_low_res;
extern note_buf_t __percpu *crash_notes;
/* flag to track if kexec reboot is in progress */ /* flag to track if kexec reboot is in progress */
extern bool kexec_in_progress; extern bool kexec_in_progress;

View File

@ -18,7 +18,7 @@
* - the arch is not required to handle n==0 if implementing the fallback * - the arch is not required to handle n==0 if implementing the fallback
*/ */
#ifndef CONFIG_ARCH_HAS_ILOG2_U32 #ifndef CONFIG_ARCH_HAS_ILOG2_U32
static inline __attribute__((const)) static __always_inline __attribute__((const))
int __ilog2_u32(u32 n) int __ilog2_u32(u32 n)
{ {
return fls(n) - 1; return fls(n) - 1;
@ -26,7 +26,7 @@ int __ilog2_u32(u32 n)
#endif #endif
#ifndef CONFIG_ARCH_HAS_ILOG2_U64 #ifndef CONFIG_ARCH_HAS_ILOG2_U64
static inline __attribute__((const)) static __always_inline __attribute__((const))
int __ilog2_u64(u64 n) int __ilog2_u64(u64 n)
{ {
return fls64(n) - 1; return fls64(n) - 1;

View File

@ -13,11 +13,7 @@ enum {
}; };
#undef offsetof #undef offsetof
#ifdef __compiler_offsetof #define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)
#define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE, MEMBER)
#else
#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER)
#endif
/** /**
* sizeof_field() - Report the size of a struct field in bytes * sizeof_field() - Report the size of a struct field in bytes

View File

@ -19,12 +19,12 @@
* any application/library that wants linux/types.h. * any application/library that wants linux/types.h.
*/ */
/* sparse defines __CHECKER__; see Documentation/dev-tools/sparse.rst */
#ifdef __CHECKER__ #ifdef __CHECKER__
#define __bitwise__ __attribute__((bitwise)) #define __bitwise __attribute__((bitwise))
#else #else
#define __bitwise__ #define __bitwise
#endif #endif
#define __bitwise __bitwise__
typedef __u16 __bitwise __le16; typedef __u16 __bitwise __le16;
typedef __u16 __bitwise __be16; typedef __u16 __bitwise __be16;

View File

@ -1192,7 +1192,7 @@ static int __init initcall_blacklist(char *str)
} }
} while (str_entry); } while (str_entry);
return 0; return 1;
} }
static bool __init_or_module initcall_blacklisted(initcall_t fn) static bool __init_or_module initcall_blacklisted(initcall_t fn)
@ -1248,15 +1248,11 @@ trace_initcall_start_cb(void *data, initcall_t fn)
static __init_or_module void static __init_or_module void
trace_initcall_finish_cb(void *data, initcall_t fn, int ret) trace_initcall_finish_cb(void *data, initcall_t fn, int ret)
{ {
ktime_t *calltime = (ktime_t *)data; ktime_t rettime, *calltime = (ktime_t *)data;
ktime_t delta, rettime;
unsigned long long duration;
rettime = ktime_get(); rettime = ktime_get();
delta = ktime_sub(rettime, *calltime);
duration = (unsigned long long) ktime_to_ns(delta) >> 10;
printk(KERN_DEBUG "initcall %pS returned %d after %lld usecs\n", printk(KERN_DEBUG "initcall %pS returned %d after %lld usecs\n",
fn, ret, duration); fn, ret, (unsigned long long)ktime_us_delta(rettime, *calltime));
} }
static ktime_t initcall_calltime; static ktime_t initcall_calltime;
@ -1454,7 +1450,9 @@ static noinline void __init kernel_init_freeable(void);
bool rodata_enabled __ro_after_init = true; bool rodata_enabled __ro_after_init = true;
static int __init set_debug_rodata(char *str) static int __init set_debug_rodata(char *str)
{ {
return strtobool(str, &rodata_enabled); if (strtobool(str, &rodata_enabled))
pr_warn("Invalid option string for rodata: '%s'\n", str);
return 1;
} }
__setup("rodata=", set_debug_rodata); __setup("rodata=", set_debug_rodata);
#endif #endif

View File

@ -153,8 +153,17 @@ static void cgroup_rstat_flush_locked(struct cgroup *cgrp, bool may_sleep)
raw_spinlock_t *cpu_lock = per_cpu_ptr(&cgroup_rstat_cpu_lock, raw_spinlock_t *cpu_lock = per_cpu_ptr(&cgroup_rstat_cpu_lock,
cpu); cpu);
struct cgroup *pos = NULL; struct cgroup *pos = NULL;
unsigned long flags;
raw_spin_lock(cpu_lock); /*
* The _irqsave() is needed because cgroup_rstat_lock is
* spinlock_t which is a sleeping lock on PREEMPT_RT. Acquiring
* this lock with the _irq() suffix only disables interrupts on
* a non-PREEMPT_RT kernel. The raw_spinlock_t below disables
* interrupts on both configurations. The _irqsave() ensures
* that interrupts are always disabled and later restored.
*/
raw_spin_lock_irqsave(cpu_lock, flags);
while ((pos = cgroup_rstat_cpu_pop_updated(pos, cgrp, cpu))) { while ((pos = cgroup_rstat_cpu_pop_updated(pos, cgrp, cpu))) {
struct cgroup_subsys_state *css; struct cgroup_subsys_state *css;
@ -166,7 +175,7 @@ static void cgroup_rstat_flush_locked(struct cgroup *cgrp, bool may_sleep)
css->ss->css_rstat_flush(css, cpu); css->ss->css_rstat_flush(css, cpu);
rcu_read_unlock(); rcu_read_unlock();
} }
raw_spin_unlock(cpu_lock); raw_spin_unlock_irqrestore(cpu_lock, flags);
/* if @may_sleep, play nice and yield if necessary */ /* if @may_sleep, play nice and yield if necessary */
if (may_sleep && (need_resched() || if (may_sleep && (need_resched() ||

View File

@ -459,37 +459,28 @@ void kcov_task_exit(struct task_struct *t)
static int kcov_mmap(struct file *filep, struct vm_area_struct *vma) static int kcov_mmap(struct file *filep, struct vm_area_struct *vma)
{ {
int res = 0; int res = 0;
void *area;
struct kcov *kcov = vma->vm_file->private_data; struct kcov *kcov = vma->vm_file->private_data;
unsigned long size, off; unsigned long size, off;
struct page *page; struct page *page;
unsigned long flags; unsigned long flags;
area = vmalloc_user(vma->vm_end - vma->vm_start);
if (!area)
return -ENOMEM;
spin_lock_irqsave(&kcov->lock, flags); spin_lock_irqsave(&kcov->lock, flags);
size = kcov->size * sizeof(unsigned long); size = kcov->size * sizeof(unsigned long);
if (kcov->mode != KCOV_MODE_INIT || vma->vm_pgoff != 0 || if (kcov->area == NULL || vma->vm_pgoff != 0 ||
vma->vm_end - vma->vm_start != size) { vma->vm_end - vma->vm_start != size) {
res = -EINVAL; res = -EINVAL;
goto exit; goto exit;
} }
if (!kcov->area) {
kcov->area = area;
vma->vm_flags |= VM_DONTEXPAND;
spin_unlock_irqrestore(&kcov->lock, flags); spin_unlock_irqrestore(&kcov->lock, flags);
vma->vm_flags |= VM_DONTEXPAND;
for (off = 0; off < size; off += PAGE_SIZE) { for (off = 0; off < size; off += PAGE_SIZE) {
page = vmalloc_to_page(kcov->area + off); page = vmalloc_to_page(kcov->area + off);
if (vm_insert_page(vma, vma->vm_start + off, page)) if (vm_insert_page(vma, vma->vm_start + off, page))
WARN_ONCE(1, "vm_insert_page() failed"); WARN_ONCE(1, "vm_insert_page() failed");
} }
return 0; return 0;
}
exit: exit:
spin_unlock_irqrestore(&kcov->lock, flags); spin_unlock_irqrestore(&kcov->lock, flags);
vfree(area);
return res; return res;
} }
@ -564,31 +555,12 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
struct task_struct *t; struct task_struct *t;
unsigned long size, unused; unsigned long flags, unused;
int mode, i; int mode, i;
struct kcov_remote_arg *remote_arg; struct kcov_remote_arg *remote_arg;
struct kcov_remote *remote; struct kcov_remote *remote;
unsigned long flags;
switch (cmd) { switch (cmd) {
case KCOV_INIT_TRACE:
/*
* Enable kcov in trace mode and setup buffer size.
* Must happen before anything else.
*/
if (kcov->mode != KCOV_MODE_DISABLED)
return -EBUSY;
/*
* Size must be at least 2 to hold current position and one PC.
* Later we allocate size * sizeof(unsigned long) memory,
* that must not overflow.
*/
size = arg;
if (size < 2 || size > INT_MAX / sizeof(unsigned long))
return -EINVAL;
kcov->size = size;
kcov->mode = KCOV_MODE_INIT;
return 0;
case KCOV_ENABLE: case KCOV_ENABLE:
/* /*
* Enable coverage for the current task. * Enable coverage for the current task.
@ -692,9 +664,37 @@ static long kcov_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
struct kcov_remote_arg *remote_arg = NULL; struct kcov_remote_arg *remote_arg = NULL;
unsigned int remote_num_handles; unsigned int remote_num_handles;
unsigned long remote_arg_size; unsigned long remote_arg_size;
unsigned long flags; unsigned long size, flags;
void *area;
if (cmd == KCOV_REMOTE_ENABLE) { kcov = filep->private_data;
switch (cmd) {
case KCOV_INIT_TRACE:
/*
* Enable kcov in trace mode and setup buffer size.
* Must happen before anything else.
*
* First check the size argument - it must be at least 2
* to hold the current position and one PC.
*/
size = arg;
if (size < 2 || size > INT_MAX / sizeof(unsigned long))
return -EINVAL;
area = vmalloc_user(size * sizeof(unsigned long));
if (area == NULL)
return -ENOMEM;
spin_lock_irqsave(&kcov->lock, flags);
if (kcov->mode != KCOV_MODE_DISABLED) {
spin_unlock_irqrestore(&kcov->lock, flags);
vfree(area);
return -EBUSY;
}
kcov->area = area;
kcov->size = size;
kcov->mode = KCOV_MODE_INIT;
spin_unlock_irqrestore(&kcov->lock, flags);
return 0;
case KCOV_REMOTE_ENABLE:
if (get_user(remote_num_handles, (unsigned __user *)(arg + if (get_user(remote_num_handles, (unsigned __user *)(arg +
offsetof(struct kcov_remote_arg, num_handles)))) offsetof(struct kcov_remote_arg, num_handles))))
return -EFAULT; return -EFAULT;
@ -710,16 +710,18 @@ static long kcov_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
return -EINVAL; return -EINVAL;
} }
arg = (unsigned long)remote_arg; arg = (unsigned long)remote_arg;
} fallthrough;
default:
kcov = filep->private_data; /*
* All other commands can be normally executed under a spin lock, so we
* obtain and release it here in order to simplify kcov_ioctl_locked().
*/
spin_lock_irqsave(&kcov->lock, flags); spin_lock_irqsave(&kcov->lock, flags);
res = kcov_ioctl_locked(kcov, cmd, arg); res = kcov_ioctl_locked(kcov, cmd, arg);
spin_unlock_irqrestore(&kcov->lock, flags); spin_unlock_irqrestore(&kcov->lock, flags);
kfree(remote_arg); kfree(remote_arg);
return res; return res;
}
} }
static const struct file_operations kcov_fops = { static const struct file_operations kcov_fops = {

View File

@ -24,8 +24,7 @@
static struct kobj_attribute _name##_attr = __ATTR_RO(_name) static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
#define KERNEL_ATTR_RW(_name) \ #define KERNEL_ATTR_RW(_name) \
static struct kobj_attribute _name##_attr = \ static struct kobj_attribute _name##_attr = __ATTR_RW(_name)
__ATTR(_name, 0644, _name##_show, _name##_store)
/* current uevent sequence number */ /* current uevent sequence number */
static ssize_t uevent_seqnum_show(struct kobject *kobj, static ssize_t uevent_seqnum_show(struct kobject *kobj,

View File

@ -66,6 +66,7 @@ EXPORT_SYMBOL_GPL(panic_timeout);
#define PANIC_PRINT_LOCK_INFO 0x00000008 #define PANIC_PRINT_LOCK_INFO 0x00000008
#define PANIC_PRINT_FTRACE_INFO 0x00000010 #define PANIC_PRINT_FTRACE_INFO 0x00000010
#define PANIC_PRINT_ALL_PRINTK_MSG 0x00000020 #define PANIC_PRINT_ALL_PRINTK_MSG 0x00000020
#define PANIC_PRINT_ALL_CPU_BT 0x00000040
unsigned long panic_print; unsigned long panic_print;
ATOMIC_NOTIFIER_HEAD(panic_notifier_list); ATOMIC_NOTIFIER_HEAD(panic_notifier_list);
@ -147,10 +148,16 @@ void nmi_panic(struct pt_regs *regs, const char *msg)
} }
EXPORT_SYMBOL(nmi_panic); EXPORT_SYMBOL(nmi_panic);
static void panic_print_sys_info(void) static void panic_print_sys_info(bool console_flush)
{ {
if (console_flush) {
if (panic_print & PANIC_PRINT_ALL_PRINTK_MSG) if (panic_print & PANIC_PRINT_ALL_PRINTK_MSG)
console_flush_on_panic(CONSOLE_REPLAY_ALL); console_flush_on_panic(CONSOLE_REPLAY_ALL);
return;
}
if (panic_print & PANIC_PRINT_ALL_CPU_BT)
trigger_all_cpu_backtrace();
if (panic_print & PANIC_PRINT_TASK_INFO) if (panic_print & PANIC_PRINT_TASK_INFO)
show_state(); show_state();
@ -185,6 +192,16 @@ void panic(const char *fmt, ...)
int old_cpu, this_cpu; int old_cpu, this_cpu;
bool _crash_kexec_post_notifiers = crash_kexec_post_notifiers; bool _crash_kexec_post_notifiers = crash_kexec_post_notifiers;
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;
}
/* /*
* Disable local interrupts. This will prevent panic_smp_self_stop * Disable local interrupts. This will prevent panic_smp_self_stop
* from deadlocking the first cpu that invokes the panic, since * from deadlocking the first cpu that invokes the panic, since
@ -272,6 +289,8 @@ void panic(const char *fmt, ...)
*/ */
atomic_notifier_call_chain(&panic_notifier_list, 0, buf); atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
panic_print_sys_info(false);
kmsg_dump(KMSG_DUMP_PANIC); kmsg_dump(KMSG_DUMP_PANIC);
/* /*
@ -302,7 +321,7 @@ void panic(const char *fmt, ...)
debug_locks_off(); debug_locks_off();
console_flush_on_panic(CONSOLE_FLUSH_PENDING); console_flush_on_panic(CONSOLE_FLUSH_PENDING);
panic_print_sys_info(); panic_print_sys_info(true);
if (!panic_blink) if (!panic_blink)
panic_blink = no_blink; panic_blink = no_blink;
@ -576,16 +595,8 @@ void __warn(const char *file, int line, void *caller, unsigned taint,
if (regs) if (regs)
show_regs(regs); show_regs(regs);
if (panic_on_warn) { 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"); panic("panic_on_warn set ...\n");
}
if (!regs) if (!regs)
dump_stack(); dump_stack();

View File

@ -56,14 +56,6 @@ struct resource_constraint {
static DEFINE_RWLOCK(resource_lock); static DEFINE_RWLOCK(resource_lock);
/*
* For memory hotplug, there is no way to free resource entries allocated
* by boot mem after the system is up. So for reusing the resource entry
* we need to remember the resource.
*/
static struct resource *bootmem_resource_free;
static DEFINE_SPINLOCK(bootmem_resource_lock);
static struct resource *next_resource(struct resource *p) static struct resource *next_resource(struct resource *p)
{ {
if (p->child) if (p->child)
@ -160,36 +152,19 @@ __initcall(ioresources_init);
static void free_resource(struct resource *res) static void free_resource(struct resource *res)
{ {
if (!res) /**
return; * If the resource was allocated using memblock early during boot
* we'll leak it here: we can only return full pages back to the
if (!PageSlab(virt_to_head_page(res))) { * buddy and trying to be smart and reusing them eventually in
spin_lock(&bootmem_resource_lock); * alloc_resource() overcomplicates resource handling.
res->sibling = bootmem_resource_free; */
bootmem_resource_free = res; if (res && PageSlab(virt_to_head_page(res)))
spin_unlock(&bootmem_resource_lock);
} else {
kfree(res); kfree(res);
}
} }
static struct resource *alloc_resource(gfp_t flags) static struct resource *alloc_resource(gfp_t flags)
{ {
struct resource *res = NULL; return kzalloc(sizeof(struct resource), flags);
spin_lock(&bootmem_resource_lock);
if (bootmem_resource_free) {
res = bootmem_resource_free;
bootmem_resource_free = res->sibling;
}
spin_unlock(&bootmem_resource_lock);
if (res)
memset(res, 0, sizeof(struct resource));
else
res = kzalloc(sizeof(struct resource), flags);
return res;
} }
/* Return the conflict entry if you can't request it */ /* Return the conflict entry if you can't request it */

View File

@ -113,13 +113,14 @@ static void send_cpu_listeners(struct sk_buff *skb,
struct listener *s, *tmp; struct listener *s, *tmp;
struct sk_buff *skb_next, *skb_cur = skb; struct sk_buff *skb_next, *skb_cur = skb;
void *reply = genlmsg_data(genlhdr); void *reply = genlmsg_data(genlhdr);
int rc, delcount = 0; int delcount = 0;
genlmsg_end(skb, reply); genlmsg_end(skb, reply);
rc = 0;
down_read(&listeners->sem); down_read(&listeners->sem);
list_for_each_entry(s, &listeners->list, list) { list_for_each_entry(s, &listeners->list, list) {
int rc;
skb_next = NULL; skb_next = NULL;
if (!list_is_last(&s->list, &listeners->list)) { if (!list_is_last(&s->list, &listeners->list)) {
skb_next = skb_clone(skb_cur, GFP_KERNEL); skb_next = skb_clone(skb_cur, GFP_KERNEL);

View File

@ -208,20 +208,87 @@ config DEBUG_BUGVERBOSE
endmenu # "printk and dmesg options" endmenu # "printk and dmesg options"
config DEBUG_KERNEL
bool "Kernel debugging"
help
Say Y here if you are developing drivers or trying to debug and
identify kernel problems.
config DEBUG_MISC
bool "Miscellaneous debug code"
default DEBUG_KERNEL
depends on DEBUG_KERNEL
help
Say Y here if you need to enable miscellaneous debug code that should
be under a more specific debug option but isn't.
menu "Compile-time checks and compiler options" menu "Compile-time checks and compiler options"
config DEBUG_INFO config DEBUG_INFO
bool "Compile the kernel with debug info" bool
depends on DEBUG_KERNEL && !COMPILE_TEST
help help
If you say Y here the resulting kernel image will include A kernel debug info option other than "None" has been selected
debugging info resulting in a larger kernel image. in the "Debug information" choice below, indicating that debug
information will be generated for build targets.
choice
prompt "Debug information"
depends on DEBUG_KERNEL
help
Selecting something other than "None" results in a kernel image
that will include debugging info resulting in a larger kernel image.
This adds debug symbols to the kernel and modules (gcc -g), and This adds debug symbols to the kernel and modules (gcc -g), and
is needed if you intend to use kernel crashdump or binary object is needed if you intend to use kernel crashdump or binary object
tools like crash, kgdb, LKCD, gdb, etc on the kernel. tools like crash, kgdb, LKCD, gdb, etc on the kernel.
Say Y here only if you plan to debug the kernel.
If unsure, say N. Choose which version of DWARF debug info to emit. If unsure,
select "Toolchain default".
config DEBUG_INFO_NONE
bool "Disable debug information"
help
Do not build the kernel with debugging information, which will
result in a faster and smaller build.
config DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT
bool "Rely on the toolchain's implicit default DWARF version"
select DEBUG_INFO
help
The implicit default version of DWARF debug info produced by a
toolchain changes over time.
This can break consumers of the debug info that haven't upgraded to
support newer revisions, and prevent testing newer versions, but
those should be less common scenarios.
config DEBUG_INFO_DWARF4
bool "Generate DWARF Version 4 debuginfo"
select DEBUG_INFO
help
Generate DWARF v4 debug info. This requires gcc 4.5+ and gdb 7.0+.
If you have consumers of DWARF debug info that are not ready for
newer revisions of DWARF, you may wish to choose this or have your
config select this.
config DEBUG_INFO_DWARF5
bool "Generate DWARF Version 5 debuginfo"
select DEBUG_INFO
depends on !CC_IS_CLANG || (CC_IS_CLANG && (AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502)))
help
Generate DWARF v5 debug info. Requires binutils 2.35.2, gcc 5.0+ (gcc
5.0+ accepts the -gdwarf-5 flag but only had partial support for some
draft features until 7.0), and gdb 8.0+.
Changes to the structure of debug info in Version 5 allow for around
15-18% savings in resulting image and debug info section sizes as
compared to DWARF Version 4. DWARF Version 5 standardizes previous
extensions such as accelerators for symbol indexing and the format
for fission (.dwo/.dwp) files. Users may not want to select this
config if they rely on tooling that has not yet been updated to
support DWARF Version 5.
endchoice # "Debug information"
if DEBUG_INFO if DEBUG_INFO
@ -267,56 +334,12 @@ config DEBUG_INFO_SPLIT
to know about the .dwo files and include them. to know about the .dwo files and include them.
Incompatible with older versions of ccache. Incompatible with older versions of ccache.
choice
prompt "DWARF version"
help
Which version of DWARF debug info to emit.
config DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT
bool "Rely on the toolchain's implicit default DWARF version"
help
The implicit default version of DWARF debug info produced by a
toolchain changes over time.
This can break consumers of the debug info that haven't upgraded to
support newer revisions, and prevent testing newer versions, but
those should be less common scenarios.
If unsure, say Y.
config DEBUG_INFO_DWARF4
bool "Generate DWARF Version 4 debuginfo"
help
Generate DWARF v4 debug info. This requires gcc 4.5+ and gdb 7.0+.
If you have consumers of DWARF debug info that are not ready for
newer revisions of DWARF, you may wish to choose this or have your
config select this.
config DEBUG_INFO_DWARF5
bool "Generate DWARF Version 5 debuginfo"
depends on !CC_IS_CLANG || (CC_IS_CLANG && (AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502)))
depends on !DEBUG_INFO_BTF || PAHOLE_VERSION >= 121
help
Generate DWARF v5 debug info. Requires binutils 2.35.2, gcc 5.0+ (gcc
5.0+ accepts the -gdwarf-5 flag but only had partial support for some
draft features until 7.0), and gdb 8.0+.
Changes to the structure of debug info in Version 5 allow for around
15-18% savings in resulting image and debug info section sizes as
compared to DWARF Version 4. DWARF Version 5 standardizes previous
extensions such as accelerators for symbol indexing and the format
for fission (.dwo/.dwp) files. Users may not want to select this
config if they rely on tooling that has not yet been updated to
support DWARF Version 5.
endchoice # "DWARF version"
config DEBUG_INFO_BTF config DEBUG_INFO_BTF
bool "Generate BTF typeinfo" bool "Generate BTF typeinfo"
depends on !DEBUG_INFO_SPLIT && !DEBUG_INFO_REDUCED depends on !DEBUG_INFO_SPLIT && !DEBUG_INFO_REDUCED
depends on !GCC_PLUGIN_RANDSTRUCT || COMPILE_TEST depends on !GCC_PLUGIN_RANDSTRUCT || COMPILE_TEST
depends on BPF_SYSCALL depends on BPF_SYSCALL
depends on !DEBUG_INFO_DWARF5 || PAHOLE_VERSION >= 121
help help
Generate deduplicated BTF type information from DWARF debug info. Generate deduplicated BTF type information from DWARF debug info.
Turning this on expects presence of pahole tool, which will convert Turning this on expects presence of pahole tool, which will convert
@ -434,7 +457,8 @@ config SECTION_MISMATCH_WARN_ONLY
If unsure, say Y. If unsure, say Y.
config DEBUG_FORCE_FUNCTION_ALIGN_64B config DEBUG_FORCE_FUNCTION_ALIGN_64B
bool "Force all function address 64B aligned" if EXPERT bool "Force all function address 64B aligned"
depends on EXPERT && (X86_64 || ARM64 || PPC32 || PPC64 || ARC)
help help
There are cases that a commit from one domain changes the function There are cases that a commit from one domain changes the function
address alignment of other domains, and cause magic performance address alignment of other domains, and cause magic performance
@ -603,20 +627,6 @@ source "lib/Kconfig.kcsan"
endmenu endmenu
config DEBUG_KERNEL
bool "Kernel debugging"
help
Say Y here if you are developing drivers or trying to debug and
identify kernel problems.
config DEBUG_MISC
bool "Miscellaneous debug code"
default DEBUG_KERNEL
depends on DEBUG_KERNEL
help
Say Y here if you need to enable miscellaneous debug code that should
be under a more specific debug option but isn't.
menu "Networking Debugging" menu "Networking Debugging"
source "net/Kconfig.debug" source "net/Kconfig.debug"

View File

@ -10,21 +10,10 @@ config HAVE_KCSAN_COMPILER
For the list of compilers that support KCSAN, please see For the list of compilers that support KCSAN, please see
<file:Documentation/dev-tools/kcsan.rst>. <file:Documentation/dev-tools/kcsan.rst>.
config KCSAN_KCOV_BROKEN
def_bool KCOV && CC_HAS_SANCOV_TRACE_PC
depends on CC_IS_CLANG
depends on !$(cc-option,-Werror=unused-command-line-argument -fsanitize=thread -fsanitize-coverage=trace-pc)
help
Some versions of clang support either KCSAN and KCOV but not the
combination of the two.
See https://bugs.llvm.org/show_bug.cgi?id=45831 for the status
in newer releases.
menuconfig KCSAN menuconfig KCSAN
bool "KCSAN: dynamic data race detector" bool "KCSAN: dynamic data race detector"
depends on HAVE_ARCH_KCSAN && HAVE_KCSAN_COMPILER depends on HAVE_ARCH_KCSAN && HAVE_KCSAN_COMPILER
depends on DEBUG_KERNEL && !KASAN depends on DEBUG_KERNEL && !KASAN
depends on !KCSAN_KCOV_BROKEN
select STACKTRACE select STACKTRACE
help help
The Kernel Concurrency Sanitizer (KCSAN) is a dynamic The Kernel Concurrency Sanitizer (KCSAN) is a dynamic

View File

@ -27,16 +27,6 @@ config UBSAN_TRAP
the system. For some system builders this is an acceptable the system. For some system builders this is an acceptable
trade-off. trade-off.
config UBSAN_KCOV_BROKEN
def_bool KCOV && CC_HAS_SANCOV_TRACE_PC
depends on CC_IS_CLANG
depends on !$(cc-option,-Werror=unused-command-line-argument -fsanitize=bounds -fsanitize-coverage=trace-pc)
help
Some versions of clang support either UBSAN or KCOV but not the
combination of the two.
See https://bugs.llvm.org/show_bug.cgi?id=45831 for the status
in newer releases.
config CC_HAS_UBSAN_BOUNDS config CC_HAS_UBSAN_BOUNDS
def_bool $(cc-option,-fsanitize=bounds) def_bool $(cc-option,-fsanitize=bounds)
@ -46,7 +36,6 @@ config CC_HAS_UBSAN_ARRAY_BOUNDS
config UBSAN_BOUNDS config UBSAN_BOUNDS
bool "Perform array index bounds checking" bool "Perform array index bounds checking"
default UBSAN default UBSAN
depends on !UBSAN_KCOV_BROKEN
depends on CC_HAS_UBSAN_ARRAY_BOUNDS || CC_HAS_UBSAN_BOUNDS depends on CC_HAS_UBSAN_ARRAY_BOUNDS || CC_HAS_UBSAN_BOUNDS
help help
This option enables detection of directly indexed out of bounds This option enables detection of directly indexed out of bounds
@ -72,7 +61,6 @@ config UBSAN_ARRAY_BOUNDS
config UBSAN_LOCAL_BOUNDS config UBSAN_LOCAL_BOUNDS
bool "Perform array local bounds checking" bool "Perform array local bounds checking"
depends on UBSAN_TRAP depends on UBSAN_TRAP
depends on !UBSAN_KCOV_BROKEN
depends on $(cc-option,-fsanitize=local-bounds) depends on $(cc-option,-fsanitize=local-bounds)
help help
This option enables -fsanitize=local-bounds which traps when an This option enables -fsanitize=local-bounds which traps when an

View File

@ -492,6 +492,11 @@ EXPORT_SYMBOL(bitmap_print_to_pagebuf);
* @list: indicates whether the bitmap must be list * @list: indicates whether the bitmap must be list
* true: print in decimal list format * true: print in decimal list format
* false: print in hexadecimal bitmask format * false: print in hexadecimal bitmask format
* @buf: buffer into which string is placed
* @maskp: pointer to bitmap to convert
* @nmaskbits: size of bitmap, in bits
* @off: in the string from which we are copying, We copy to @buf
* @count: the maximum number of bytes to print
*/ */
static int bitmap_print_to_buf(bool list, char *buf, const unsigned long *maskp, static int bitmap_print_to_buf(bool list, char *buf, const unsigned long *maskp,
int nmaskbits, loff_t off, size_t count) int nmaskbits, loff_t off, size_t count)
@ -512,6 +517,11 @@ static int bitmap_print_to_buf(bool list, char *buf, const unsigned long *maskp,
/** /**
* bitmap_print_bitmask_to_buf - convert bitmap to hex bitmask format ASCII string * bitmap_print_bitmask_to_buf - convert bitmap to hex bitmask format ASCII string
* @buf: buffer into which string is placed
* @maskp: pointer to bitmap to convert
* @nmaskbits: size of bitmap, in bits
* @off: in the string from which we are copying, We copy to @buf
* @count: the maximum number of bytes to print
* *
* The bitmap_print_to_pagebuf() is used indirectly via its cpumap wrapper * The bitmap_print_to_pagebuf() is used indirectly via its cpumap wrapper
* cpumap_print_to_pagebuf() or directly by drivers to export hexadecimal * cpumap_print_to_pagebuf() or directly by drivers to export hexadecimal
@ -553,12 +563,6 @@ static int bitmap_print_to_buf(bool list, char *buf, const unsigned long *maskp,
* move to use bin_attribute. In result, we have to pass the corresponding * move to use bin_attribute. In result, we have to pass the corresponding
* parameters such as off, count from bin_attribute show entry to this API. * parameters such as off, count from bin_attribute show entry to this API.
* *
* @buf: buffer into which string is placed
* @maskp: pointer to bitmap to convert
* @nmaskbits: size of bitmap, in bits
* @off: in the string from which we are copying, We copy to @buf
* @count: the maximum number of bytes to print
*
* The role of cpumap_print_bitmask_to_buf() and cpumap_print_list_to_buf() * The role of cpumap_print_bitmask_to_buf() and cpumap_print_list_to_buf()
* is similar with cpumap_print_to_pagebuf(), the difference is that * is similar with cpumap_print_to_pagebuf(), the difference is that
* bitmap_print_to_pagebuf() mainly serves sysfs attribute with the assumption * bitmap_print_to_pagebuf() mainly serves sysfs attribute with the assumption
@ -597,6 +601,11 @@ EXPORT_SYMBOL(bitmap_print_bitmask_to_buf);
/** /**
* bitmap_print_list_to_buf - convert bitmap to decimal list format ASCII string * bitmap_print_list_to_buf - convert bitmap to decimal list format ASCII string
* @buf: buffer into which string is placed
* @maskp: pointer to bitmap to convert
* @nmaskbits: size of bitmap, in bits
* @off: in the string from which we are copying, We copy to @buf
* @count: the maximum number of bytes to print
* *
* Everything is same with the above bitmap_print_bitmask_to_buf() except * Everything is same with the above bitmap_print_bitmask_to_buf() except
* the print format. * the print format.
@ -807,7 +816,8 @@ EXPORT_SYMBOL(bitmap_parselist);
/** /**
* bitmap_parselist_user() * bitmap_parselist_user() - convert user buffer's list format ASCII
* string to bitmap
* *
* @ubuf: pointer to user buffer containing string. * @ubuf: pointer to user buffer containing string.
* @ulen: buffer size in bytes. If string is smaller than this * @ulen: buffer size in bytes. If string is smaller than this

View File

@ -154,16 +154,8 @@ static void ubsan_epilogue(void)
current->in_ubsan--; current->in_ubsan--;
if (panic_on_warn) { 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"); panic("panic_on_warn set ...\n");
}
} }
void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs) void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs)

View File

@ -117,16 +117,8 @@ static void end_report(unsigned long *flags, unsigned long addr)
pr_err("==================================================================\n"); pr_err("==================================================================\n");
add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE); add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
spin_unlock_irqrestore(&report_lock, *flags); spin_unlock_irqrestore(&report_lock, *flags);
if (panic_on_warn && !test_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags)) { if (panic_on_warn && !test_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags))
/*
* 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"); panic("panic_on_warn set ...\n");
}
if (kasan_arg_fault == KASAN_ARG_FAULT_PANIC) if (kasan_arg_fault == KASAN_ARG_FAULT_PANIC)
panic("kasan.fault=panic set ...\n"); panic("kasan.fault=panic set ...\n");
kasan_enable_current(); kasan_enable_current();

View File

@ -334,7 +334,7 @@ if ($user_codespellfile) {
} elsif (!(-f $codespellfile)) { } elsif (!(-f $codespellfile)) {
# If /usr/share/codespell/dictionary.txt is not present, try to find it # If /usr/share/codespell/dictionary.txt is not present, try to find it
# under codespell's install directory: <codespell_root>/data/dictionary.txt # under codespell's install directory: <codespell_root>/data/dictionary.txt
if (($codespell || $help) && which("codespell") ne "" && which("python") ne "") { if (($codespell || $help) && which("python3") ne "") {
my $python_codespell_dict = << "EOF"; my $python_codespell_dict = << "EOF";
import os.path as op import os.path as op
@ -344,7 +344,7 @@ codespell_file = op.join(codespell_dir, 'data', 'dictionary.txt')
print(codespell_file, end='') print(codespell_file, end='')
EOF EOF
my $codespell_dict = `python -c "$python_codespell_dict" 2> /dev/null`; my $codespell_dict = `python3 -c "$python_codespell_dict" 2> /dev/null`;
$codespellfile = $codespell_dict if (-f $codespell_dict); $codespellfile = $codespell_dict if (-f $codespell_dict);
} }
} }
@ -3926,7 +3926,7 @@ sub process {
if ($prevline =~ /^[\+ ]};?\s*$/ && if ($prevline =~ /^[\+ ]};?\s*$/ &&
$line =~ /^\+/ && $line =~ /^\+/ &&
!($line =~ /^\+\s*$/ || !($line =~ /^\+\s*$/ ||
$line =~ /^\+\s*EXPORT_SYMBOL/ || $line =~ /^\+\s*(?:EXPORT_SYMBOL|early_param)/ ||
$line =~ /^\+\s*MODULE_/i || $line =~ /^\+\s*MODULE_/i ||
$line =~ /^\+\s*\#\s*(?:end|elif|else)/ || $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
$line =~ /^\+[a-z_]*init/ || $line =~ /^\+[a-z_]*init/ ||
@ -5551,6 +5551,7 @@ sub process {
defined($stat) && defined($cond) && defined($stat) && defined($cond) &&
$line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
my ($s, $c) = ($stat, $cond); my ($s, $c) = ($stat, $cond);
my $fixed_assign_in_if = 0;
if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
if (ERROR("ASSIGN_IN_IF", if (ERROR("ASSIGN_IN_IF",
@ -5575,6 +5576,7 @@ sub process {
$newline .= ')'; $newline .= ')';
$newline .= " {" if (defined($brace)); $newline .= " {" if (defined($brace));
fix_insert_line($fixlinenr + 1, $newline); fix_insert_line($fixlinenr + 1, $newline);
$fixed_assign_in_if = 1;
} }
} }
} }
@ -5598,8 +5600,20 @@ sub process {
$stat_real = "[...]\n$stat_real"; $stat_real = "[...]\n$stat_real";
} }
ERROR("TRAILING_STATEMENTS", if (ERROR("TRAILING_STATEMENTS",
"trailing statements should be on next line\n" . $herecurr . $stat_real); "trailing statements should be on next line\n" . $herecurr . $stat_real) &&
!$fixed_assign_in_if &&
$cond_lines == 0 &&
$fix && $perl_version_ok &&
$fixed[$fixlinenr] =~ /^\+(\s*)((?:if|while|for)\s*$balanced_parens)\s*(.*)$/) {
my $indent = $1;
my $test = $2;
my $rest = rtrim($4);
if ($rest =~ /;$/) {
$fixed[$fixlinenr] = "\+$indent$test";
fix_insert_line($fixlinenr + 1, "$indent\t$rest");
}
}
} }
} }
@ -7418,6 +7432,13 @@ sub process {
WARN("MODULE_LICENSE", WARN("MODULE_LICENSE",
"unknown module license " . $extracted_string . "\n" . $herecurr); "unknown module license " . $extracted_string . "\n" . $herecurr);
} }
if (!$file && $extracted_string eq '"GPL v2"') {
if (WARN("MODULE_LICENSE",
"Prefer \"GPL\" over \"GPL v2\" - see commit bf7fbeeae6db (\"module: Cure the MODULE_LICENSE \"GPL\" vs. \"GPL v2\" bogosity\")\n" . $herecurr) &&
$fix) {
$fixed[$fixlinenr] =~ s/\bMODULE_LICENSE\s*\(\s*"GPL v2"\s*\)/MODULE_LICENSE("GPL")/;
}
}
} }
# check for sysctl duplicate constants # check for sysctl duplicate constants

View File

@ -43,11 +43,10 @@ typedef __u8 u8;
typedef __s8 s8; typedef __s8 s8;
#ifdef __CHECKER__ #ifdef __CHECKER__
#define __bitwise__ __attribute__((bitwise)) #define __bitwise __attribute__((bitwise))
#else #else
#define __bitwise__ #define __bitwise
#endif #endif
#define __bitwise __bitwise__
#define __force #define __force
#define __user #define __user