Merge branch 'akpm' (patches from Andrew)
Merge more updates from Andrew Morton: - most of the rest of MM (memcg, hugetlb, vmscan, proc, compaction, mempolicy, oom-kill, hugetlbfs, migration, thp, cma, util, memory-hotplug, cleanups, uaccess, migration, gup, pagemap), - various other subsystems (alpha, misc, sparse, bitmap, lib, bitops, checkpatch, autofs, minix, nilfs, ufs, fat, signals, kmod, coredump, exec, kdump, rapidio, panic, kcov, kgdb, ipc). * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (164 commits) mm/gup: remove task_struct pointer for all gup code mm: clean up the last pieces of page fault accountings mm/xtensa: use general page fault accounting mm/x86: use general page fault accounting mm/sparc64: use general page fault accounting mm/sparc32: use general page fault accounting mm/sh: use general page fault accounting mm/s390: use general page fault accounting mm/riscv: use general page fault accounting mm/powerpc: use general page fault accounting mm/parisc: use general page fault accounting mm/openrisc: use general page fault accounting mm/nios2: use general page fault accounting mm/nds32: use general page fault accounting mm/mips: use general page fault accounting mm/microblaze: use general page fault accounting mm/m68k: use general page fault accounting mm/ia64: use general page fault accounting mm/hexagon: use general page fault accounting mm/csky: use general page fault accounting ...
This commit is contained in:
@@ -36,7 +36,7 @@ KCOV_INSTRUMENT_stacktrace.o := n
|
||||
KCOV_INSTRUMENT_kcov.o := n
|
||||
KASAN_SANITIZE_kcov.o := n
|
||||
KCSAN_SANITIZE_kcov.o := n
|
||||
CFLAGS_kcov.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector)
|
||||
CFLAGS_kcov.o := $(call cc-option, -fno-conserve-stack) -fno-stack-protector
|
||||
|
||||
# cond_syscall is currently not LTO compatible
|
||||
CFLAGS_sys_ni.o = $(DISABLE_LTO)
|
||||
|
@@ -11,6 +11,8 @@
|
||||
#include <asm/page.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
#include <crypto/sha.h>
|
||||
|
||||
/* vmcoreinfo stuff */
|
||||
unsigned char *vmcoreinfo_data;
|
||||
size_t vmcoreinfo_size;
|
||||
@@ -376,6 +378,53 @@ phys_addr_t __weak paddr_vmcoreinfo_note(void)
|
||||
}
|
||||
EXPORT_SYMBOL(paddr_vmcoreinfo_note);
|
||||
|
||||
#define NOTES_SIZE (&__stop_notes - &__start_notes)
|
||||
#define BUILD_ID_MAX SHA1_DIGEST_SIZE
|
||||
#define NT_GNU_BUILD_ID 3
|
||||
|
||||
struct elf_note_section {
|
||||
struct elf_note n_hdr;
|
||||
u8 n_data[];
|
||||
};
|
||||
|
||||
/*
|
||||
* Add build ID from .notes section as generated by the GNU ld(1)
|
||||
* or LLVM lld(1) --build-id option.
|
||||
*/
|
||||
static void add_build_id_vmcoreinfo(void)
|
||||
{
|
||||
char build_id[BUILD_ID_MAX * 2 + 1];
|
||||
int n_remain = NOTES_SIZE;
|
||||
|
||||
while (n_remain >= sizeof(struct elf_note)) {
|
||||
const struct elf_note_section *note_sec =
|
||||
&__start_notes + NOTES_SIZE - n_remain;
|
||||
const u32 n_namesz = note_sec->n_hdr.n_namesz;
|
||||
|
||||
if (note_sec->n_hdr.n_type == NT_GNU_BUILD_ID &&
|
||||
n_namesz != 0 &&
|
||||
!strcmp((char *)¬e_sec->n_data[0], "GNU")) {
|
||||
if (note_sec->n_hdr.n_descsz <= BUILD_ID_MAX) {
|
||||
const u32 n_descsz = note_sec->n_hdr.n_descsz;
|
||||
const u8 *s = ¬e_sec->n_data[n_namesz];
|
||||
|
||||
s = PTR_ALIGN(s, 4);
|
||||
bin2hex(build_id, s, n_descsz);
|
||||
build_id[2 * n_descsz] = '\0';
|
||||
VMCOREINFO_BUILD_ID(build_id);
|
||||
return;
|
||||
}
|
||||
pr_warn("Build ID is too large to include in vmcoreinfo: %u > %u\n",
|
||||
note_sec->n_hdr.n_descsz,
|
||||
BUILD_ID_MAX);
|
||||
return;
|
||||
}
|
||||
n_remain -= sizeof(struct elf_note) +
|
||||
ALIGN(note_sec->n_hdr.n_namesz, 4) +
|
||||
ALIGN(note_sec->n_hdr.n_descsz, 4);
|
||||
}
|
||||
}
|
||||
|
||||
static int __init crash_save_vmcoreinfo_init(void)
|
||||
{
|
||||
vmcoreinfo_data = (unsigned char *)get_zeroed_page(GFP_KERNEL);
|
||||
@@ -394,6 +443,7 @@ static int __init crash_save_vmcoreinfo_init(void)
|
||||
}
|
||||
|
||||
VMCOREINFO_OSRELEASE(init_uts_ns.name.release);
|
||||
add_build_id_vmcoreinfo();
|
||||
VMCOREINFO_PAGESIZE(PAGE_SIZE);
|
||||
|
||||
VMCOREINFO_SYMBOL(init_uts_ns);
|
||||
|
@@ -217,10 +217,9 @@ get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user,
|
||||
if (add_mark)
|
||||
perf_callchain_store_context(&ctx, PERF_CONTEXT_USER);
|
||||
|
||||
fs = get_fs();
|
||||
set_fs(USER_DS);
|
||||
fs = force_uaccess_begin();
|
||||
perf_callchain_user(&ctx, regs);
|
||||
set_fs(fs);
|
||||
force_uaccess_end(fs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -6453,10 +6453,9 @@ perf_output_sample_ustack(struct perf_output_handle *handle, u64 dump_size,
|
||||
|
||||
/* Data. */
|
||||
sp = perf_user_stack_pointer(regs);
|
||||
fs = get_fs();
|
||||
set_fs(USER_DS);
|
||||
fs = force_uaccess_begin();
|
||||
rem = __output_copy_user(handle, (void *) sp, dump_size);
|
||||
set_fs(fs);
|
||||
force_uaccess_end(fs);
|
||||
dyn_size = dump_size - rem;
|
||||
|
||||
perf_output_skip(handle, rem);
|
||||
|
@@ -184,7 +184,7 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr,
|
||||
if (new_page) {
|
||||
get_page(new_page);
|
||||
page_add_new_anon_rmap(new_page, vma, addr, false);
|
||||
lru_cache_add_active_or_unevictable(new_page, vma);
|
||||
lru_cache_add_inactive_or_unevictable(new_page, vma);
|
||||
} else
|
||||
/* no new page, just dec_mm_counter for old_page */
|
||||
dec_mm_counter(mm, MM_ANONPAGES);
|
||||
@@ -376,7 +376,7 @@ __update_ref_ctr(struct mm_struct *mm, unsigned long vaddr, short d)
|
||||
if (!vaddr || !d)
|
||||
return -EINVAL;
|
||||
|
||||
ret = get_user_pages_remote(NULL, mm, vaddr, 1,
|
||||
ret = get_user_pages_remote(mm, vaddr, 1,
|
||||
FOLL_WRITE, &page, &vma, NULL);
|
||||
if (unlikely(ret <= 0)) {
|
||||
/*
|
||||
@@ -477,7 +477,7 @@ retry:
|
||||
if (is_register)
|
||||
gup_flags |= FOLL_SPLIT_PMD;
|
||||
/* Read the page with vaddr into memory */
|
||||
ret = get_user_pages_remote(NULL, mm, vaddr, 1, gup_flags,
|
||||
ret = get_user_pages_remote(mm, vaddr, 1, gup_flags,
|
||||
&old_page, &vma, NULL);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
@@ -2029,7 +2029,7 @@ static int is_trap_at_addr(struct mm_struct *mm, unsigned long vaddr)
|
||||
* but we treat this as a 'remote' access since it is
|
||||
* essentially a kernel access to the memory.
|
||||
*/
|
||||
result = get_user_pages_remote(NULL, mm, vaddr, 1, FOLL_FORCE, &page,
|
||||
result = get_user_pages_remote(mm, vaddr, 1, FOLL_FORCE, &page,
|
||||
NULL, NULL);
|
||||
if (result < 0)
|
||||
return result;
|
||||
|
@@ -732,7 +732,7 @@ void __noreturn do_exit(long code)
|
||||
* mm_release()->clear_child_tid() from writing to a user-controlled
|
||||
* kernel address.
|
||||
*/
|
||||
set_fs(USER_DS);
|
||||
force_uaccess_begin();
|
||||
|
||||
if (unlikely(in_atomic())) {
|
||||
pr_info("note: %s[%d] exited with preempt_count %d\n",
|
||||
@@ -1626,6 +1626,22 @@ long kernel_wait4(pid_t upid, int __user *stat_addr, int options,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int kernel_wait(pid_t pid, int *stat)
|
||||
{
|
||||
struct wait_opts wo = {
|
||||
.wo_type = PIDTYPE_PID,
|
||||
.wo_pid = find_get_pid(pid),
|
||||
.wo_flags = WEXITED,
|
||||
};
|
||||
int ret;
|
||||
|
||||
ret = do_wait(&wo);
|
||||
if (ret > 0 && wo.wo_stat)
|
||||
*stat = wo.wo_stat;
|
||||
put_pid(wo.wo_pid);
|
||||
return ret;
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE4(wait4, pid_t, upid, int __user *, stat_addr,
|
||||
int, options, struct rusage __user *, ru)
|
||||
{
|
||||
|
@@ -678,7 +678,7 @@ static int fault_in_user_writeable(u32 __user *uaddr)
|
||||
int ret;
|
||||
|
||||
mmap_read_lock(mm);
|
||||
ret = fixup_user_fault(current, mm, (unsigned long)uaddr,
|
||||
ret = fixup_user_fault(mm, (unsigned long)uaddr,
|
||||
FAULT_FLAG_WRITE, NULL);
|
||||
mmap_read_unlock(mm);
|
||||
|
||||
|
@@ -96,7 +96,7 @@ struct kcov_percpu_data {
|
||||
int saved_sequence;
|
||||
};
|
||||
|
||||
DEFINE_PER_CPU(struct kcov_percpu_data, kcov_percpu_data);
|
||||
static DEFINE_PER_CPU(struct kcov_percpu_data, kcov_percpu_data);
|
||||
|
||||
/* Must be called with kcov_remote_lock locked. */
|
||||
static struct kcov_remote *kcov_remote_find(u64 handle)
|
||||
@@ -775,7 +775,7 @@ static inline bool kcov_mode_enabled(unsigned int mode)
|
||||
return (mode & ~KCOV_IN_CTXSW) != KCOV_MODE_DISABLED;
|
||||
}
|
||||
|
||||
void kcov_remote_softirq_start(struct task_struct *t)
|
||||
static void kcov_remote_softirq_start(struct task_struct *t)
|
||||
{
|
||||
struct kcov_percpu_data *data = this_cpu_ptr(&kcov_percpu_data);
|
||||
unsigned int mode;
|
||||
@@ -792,7 +792,7 @@ void kcov_remote_softirq_start(struct task_struct *t)
|
||||
}
|
||||
}
|
||||
|
||||
void kcov_remote_softirq_stop(struct task_struct *t)
|
||||
static void kcov_remote_softirq_stop(struct task_struct *t)
|
||||
{
|
||||
struct kcov_percpu_data *data = this_cpu_ptr(&kcov_percpu_data);
|
||||
|
||||
|
@@ -36,9 +36,8 @@
|
||||
*
|
||||
* If you need less than 50 threads would mean we're dealing with systems
|
||||
* smaller than 3200 pages. This assumes you are capable of having ~13M memory,
|
||||
* and this would only be an be an upper limit, after which the OOM killer
|
||||
* would take effect. Systems like these are very unlikely if modules are
|
||||
* enabled.
|
||||
* and this would only be an upper limit, after which the OOM killer would take
|
||||
* effect. Systems like these are very unlikely if modules are enabled.
|
||||
*/
|
||||
#define MAX_KMOD_CONCURRENT 50
|
||||
static atomic_t kmod_concurrent_max = ATOMIC_INIT(MAX_KMOD_CONCURRENT);
|
||||
|
@@ -1258,8 +1258,7 @@ void kthread_use_mm(struct mm_struct *mm)
|
||||
if (active_mm != mm)
|
||||
mmdrop(active_mm);
|
||||
|
||||
to_kthread(tsk)->oldfs = get_fs();
|
||||
set_fs(USER_DS);
|
||||
to_kthread(tsk)->oldfs = force_uaccess_begin();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kthread_use_mm);
|
||||
|
||||
@@ -1274,7 +1273,7 @@ void kthread_unuse_mm(struct mm_struct *mm)
|
||||
WARN_ON_ONCE(!(tsk->flags & PF_KTHREAD));
|
||||
WARN_ON_ONCE(!tsk->mm);
|
||||
|
||||
set_fs(to_kthread(tsk)->oldfs);
|
||||
force_uaccess_end(to_kthread(tsk)->oldfs);
|
||||
|
||||
task_lock(tsk);
|
||||
sync_mm_rss(mm);
|
||||
|
@@ -505,7 +505,7 @@ static void do_oops_enter_exit(void)
|
||||
* Return true if the calling CPU is allowed to print oops-related info.
|
||||
* This is a bit racy..
|
||||
*/
|
||||
int oops_may_print(void)
|
||||
bool oops_may_print(void)
|
||||
{
|
||||
return pause_on_oops_flag == 0;
|
||||
}
|
||||
@@ -551,7 +551,7 @@ static int init_oops_id(void)
|
||||
}
|
||||
late_initcall(init_oops_id);
|
||||
|
||||
void print_oops_end_marker(void)
|
||||
static void print_oops_end_marker(void)
|
||||
{
|
||||
init_oops_id();
|
||||
pr_warn("---[ end trace %016llx ]---\n", (unsigned long long)oops_id);
|
||||
|
@@ -233,10 +233,9 @@ unsigned int stack_trace_save_user(unsigned long *store, unsigned int size)
|
||||
if (current->flags & PF_KTHREAD)
|
||||
return 0;
|
||||
|
||||
fs = get_fs();
|
||||
set_fs(USER_DS);
|
||||
fs = force_uaccess_begin();
|
||||
arch_stack_walk_user(consume_entry, &c, task_pt_regs(current));
|
||||
set_fs(fs);
|
||||
force_uaccess_end(fs);
|
||||
|
||||
return c.len;
|
||||
}
|
||||
|
@@ -2851,6 +2851,15 @@ static struct ctl_table vm_table[] = {
|
||||
.mode = 0200,
|
||||
.proc_handler = sysctl_compaction_handler,
|
||||
},
|
||||
{
|
||||
.procname = "compaction_proactiveness",
|
||||
.data = &sysctl_compaction_proactiveness,
|
||||
.maxlen = sizeof(sysctl_compaction_proactiveness),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
.extra1 = SYSCTL_ZERO,
|
||||
.extra2 = &one_hundred,
|
||||
},
|
||||
{
|
||||
.procname = "extfrag_threshold",
|
||||
.data = &sysctl_extfrag_threshold,
|
||||
|
29
kernel/umh.c
29
kernel/umh.c
@@ -119,37 +119,16 @@ static void call_usermodehelper_exec_sync(struct subprocess_info *sub_info)
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
/* If SIGCLD is ignored kernel_wait4 won't populate the status. */
|
||||
/* If SIGCLD is ignored do_wait won't populate the status. */
|
||||
kernel_sigaction(SIGCHLD, SIG_DFL);
|
||||
pid = kernel_thread(call_usermodehelper_exec_async, sub_info, SIGCHLD);
|
||||
if (pid < 0) {
|
||||
if (pid < 0)
|
||||
sub_info->retval = pid;
|
||||
} else {
|
||||
int ret = -ECHILD;
|
||||
/*
|
||||
* Normally it is bogus to call wait4() from in-kernel because
|
||||
* wait4() wants to write the exit code to a userspace address.
|
||||
* But call_usermodehelper_exec_sync() always runs as kernel
|
||||
* thread (workqueue) and put_user() to a kernel address works
|
||||
* OK for kernel threads, due to their having an mm_segment_t
|
||||
* which spans the entire address space.
|
||||
*
|
||||
* Thus the __user pointer cast is valid here.
|
||||
*/
|
||||
kernel_wait4(pid, (int __user *)&ret, 0, NULL);
|
||||
|
||||
/*
|
||||
* If ret is 0, either call_usermodehelper_exec_async failed and
|
||||
* the real error code is already in sub_info->retval or
|
||||
* sub_info->retval is 0 anyway, so don't mess with it then.
|
||||
*/
|
||||
if (ret)
|
||||
sub_info->retval = ret;
|
||||
}
|
||||
else
|
||||
kernel_wait(pid, &sub_info->retval);
|
||||
|
||||
/* Restore default kernel sig handler */
|
||||
kernel_sigaction(SIGCHLD, SIG_IGN);
|
||||
|
||||
umh_complete(sub_info);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user