Commit b5d903c2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'akpm' (patches from Andrew)

Merge more updates from Andrew Morton:

 - MM remainders

 - various misc things

 - kcov updates

* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (27 commits)
  lib/test_printf.c: call wait_for_random_bytes() before plain %p tests
  hexagon: drop the unused variable zero_page_mask
  hexagon: fix printk format warning in setup.c
  mm: fix oom_kill event handling
  treewide: use PHYS_ADDR_MAX to avoid type casting ULLONG_MAX
  mm: use octal not symbolic permissions
  ipc: use new return type vm_fault_t
  sysvipc/sem: mitigate semnum index against spectre v1
  fault-injection: reorder config entries
  arm: port KCOV to arm
  sched/core / kcov: avoid kcov_area during task switch
  kcov: prefault the kcov_area
  kcov: ensure irq code sees a valid area
  kernel/relay.c: change return type to vm_fault_t
  exofs: avoid VLA in structures
  coredump: fix spam with zero VMA process
  fat: use fat_fs_error() instead of BUG_ON() in __fat_get_block()
  proc: skip branch in /proc/*/* lookup
  mremap: remove LATENCY_LIMIT from mremap to reduce the number of TLB shootdowns
  mm/memblock: add missing include <linux/bootmem.h>
  ...
parents 7a932516 ee410f15
......@@ -549,27 +549,26 @@ static int exofs_devs_2_odi(struct exofs_dt_device_info *dt_dev,
static int __alloc_dev_table(struct exofs_sb_info *sbi, unsigned numdevs,
struct exofs_dev **peds)
{
struct __alloc_ore_devs_and_exofs_devs {
/* Twice bigger table: See exofs_init_comps() and comment at
* exofs_read_lookup_dev_table()
*/
struct ore_dev *oreds[numdevs * 2 - 1];
struct exofs_dev eds[numdevs];
} *aoded;
/* Twice bigger table: See exofs_init_comps() and comment at
* exofs_read_lookup_dev_table()
*/
const size_t numores = numdevs * 2 - 1;
struct exofs_dev *eds;
unsigned i;
aoded = kzalloc(sizeof(*aoded), GFP_KERNEL);
if (unlikely(!aoded)) {
sbi->oc.ods = kzalloc(numores * sizeof(struct ore_dev *) +
numdevs * sizeof(struct exofs_dev), GFP_KERNEL);
if (unlikely(!sbi->oc.ods)) {
EXOFS_ERR("ERROR: failed allocating Device array[%d]\n",
numdevs);
return -ENOMEM;
}
sbi->oc.ods = aoded->oreds;
*peds = eds = aoded->eds;
/* Start of allocated struct exofs_dev entries */
*peds = eds = (void *)sbi->oc.ods[numores];
/* Initialize pointers into struct exofs_dev */
for (i = 0; i < numdevs; ++i)
aoded->oreds[i] = &eds[i].ored;
sbi->oc.ods[i] = &eds[i].ored;
return 0;
}
......
......@@ -158,8 +158,14 @@ static inline int __fat_get_block(struct inode *inode, sector_t iblock,
err = fat_bmap(inode, iblock, &phys, &mapped_blocks, create, false);
if (err)
return err;
if (!phys) {
fat_fs_error(sb,
"invalid FAT chain (i_pos %lld, last_block %llu)",
MSDOS_I(inode)->i_pos,
(unsigned long long)last_block);
return -EIO;
}
BUG_ON(!phys);
BUG_ON(*max_blocks != mapped_blocks);
set_buffer_new(bh_result);
map_bh(bh_result, sb, phys);
......
......@@ -2439,14 +2439,11 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
for (p = ents; p < last; p++) {
if (p->len != dentry->d_name.len)
continue;
if (!memcmp(dentry->d_name.name, p->name, p->len))
if (!memcmp(dentry->d_name.name, p->name, p->len)) {
res = proc_pident_instantiate(dentry, task, p);
break;
}
}
if (p >= last)
goto out;
res = proc_pident_instantiate(dentry, task, p);
out:
put_task_struct(task);
out_no_task:
return res;
......
......@@ -22,13 +22,27 @@ enum kcov_mode {
KCOV_MODE_TRACE_CMP = 3,
};
#define KCOV_IN_CTXSW (1 << 30)
void kcov_task_init(struct task_struct *t);
void kcov_task_exit(struct task_struct *t);
#define kcov_prepare_switch(t) \
do { \
(t)->kcov_mode |= KCOV_IN_CTXSW; \
} while (0)
#define kcov_finish_switch(t) \
do { \
(t)->kcov_mode &= ~KCOV_IN_CTXSW; \
} while (0)
#else
static inline void kcov_task_init(struct task_struct *t) {}
static inline void kcov_task_exit(struct task_struct *t) {}
static inline void kcov_prepare_switch(struct task_struct *t) {}
static inline void kcov_finish_switch(struct task_struct *t) {}
#endif /* CONFIG_KCOV */
#endif /* _LINUX_KCOV_H */
......@@ -53,6 +53,7 @@ enum memcg_memory_event {
MEMCG_HIGH,
MEMCG_MAX,
MEMCG_OOM,
MEMCG_OOM_KILL,
MEMCG_SWAP_MAX,
MEMCG_SWAP_FAIL,
MEMCG_NR_MEMORY_EVENTS,
......@@ -720,11 +721,8 @@ static inline void count_memcg_event_mm(struct mm_struct *mm,
rcu_read_lock();
memcg = mem_cgroup_from_task(rcu_dereference(mm->owner));
if (likely(memcg)) {
if (likely(memcg))
count_memcg_events(memcg, idx, 1);
if (idx == OOM_KILL)
cgroup_file_notify(&memcg->events_file);
}
rcu_read_unlock();
}
......@@ -735,6 +733,21 @@ static inline void memcg_memory_event(struct mem_cgroup *memcg,
cgroup_file_notify(&memcg->events_file);
}
static inline void memcg_memory_event_mm(struct mm_struct *mm,
enum memcg_memory_event event)
{
struct mem_cgroup *memcg;
if (mem_cgroup_disabled())
return;
rcu_read_lock();
memcg = mem_cgroup_from_task(rcu_dereference(mm->owner));
if (likely(memcg))
memcg_memory_event(memcg, event);
rcu_read_unlock();
}
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
void mem_cgroup_split_huge_fixup(struct page *head);
#endif
......@@ -756,6 +769,11 @@ static inline void memcg_memory_event(struct mem_cgroup *memcg,
{
}
static inline void memcg_memory_event_mm(struct mm_struct *mm,
enum memcg_memory_event event)
{
}
static inline enum mem_cgroup_protection mem_cgroup_protected(
struct mem_cgroup *root, struct mem_cgroup *memcg)
{
......
......@@ -1130,7 +1130,7 @@ struct task_struct {
#ifdef CONFIG_KCOV
/* Coverage collection mode enabled for this task (0 if disabled): */
enum kcov_mode kcov_mode;
unsigned int kcov_mode;
/* Size of the kcov_area: */
unsigned int kcov_size;
......
......@@ -600,6 +600,7 @@ struct memcg_cache_params {
struct memcg_cache_array __rcu *memcg_caches;
struct list_head __root_caches_node;
struct list_head children;
bool dying;
};
struct {
struct mem_cgroup *memcg;
......
......@@ -85,6 +85,7 @@
#include <linux/nsproxy.h>
#include <linux/ipc_namespace.h>
#include <linux/sched/wake_q.h>
#include <linux/nospec.h>
#include <linux/uaccess.h>
#include "util.h"
......@@ -368,6 +369,7 @@ static inline int sem_lock(struct sem_array *sma, struct sembuf *sops,
int nsops)
{
struct sem *sem;
int idx;
if (nsops != 1) {
/* Complex operation - acquire a full lock */
......@@ -385,7 +387,8 @@ static inline int sem_lock(struct sem_array *sma, struct sembuf *sops,
*
* Both facts are tracked by use_global_mode.
*/
sem = &sma->sems[sops->sem_num];
idx = array_index_nospec(sops->sem_num, sma->sem_nsems);
sem = &sma->sems[idx];
/*
* Initial check for use_global_lock. Just an optimization,
......@@ -638,7 +641,8 @@ static int perform_atomic_semop_slow(struct sem_array *sma, struct sem_queue *q)
un = q->undo;
for (sop = sops; sop < sops + nsops; sop++) {
curr = &sma->sems[sop->sem_num];
int idx = array_index_nospec(sop->sem_num, sma->sem_nsems);
curr = &sma->sems[idx];
sem_op = sop->sem_op;
result = curr->semval;
......@@ -718,7 +722,9 @@ static int perform_atomic_semop(struct sem_array *sma, struct sem_queue *q)
* until the operations can go through.
*/
for (sop = sops; sop < sops + nsops; sop++) {
curr = &sma->sems[sop->sem_num];
int idx = array_index_nospec(sop->sem_num, sma->sem_nsems);
curr = &sma->sems[idx];
sem_op = sop->sem_op;
result = curr->semval;
......@@ -1356,6 +1362,7 @@ static int semctl_setval(struct ipc_namespace *ns, int semid, int semnum,
return -EIDRM;
}
semnum = array_index_nospec(semnum, sma->sem_nsems);
curr = &sma->sems[semnum];
ipc_assert_locked_object(&sma->sem_perm);
......@@ -1509,6 +1516,8 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
err = -EIDRM;
goto out_unlock;
}
semnum = array_index_nospec(semnum, nsems);
curr = &sma->sems[semnum];
switch (cmd) {
......@@ -2081,7 +2090,8 @@ static long do_semtimedop(int semid, struct sembuf __user *tsops,
*/
if (nsops == 1) {
struct sem *curr;
curr = &sma->sems[sops->sem_num];
int idx = array_index_nospec(sops->sem_num, sma->sem_nsems);
curr = &sma->sems[idx];
if (alter) {
if (sma->complex_count) {
......
......@@ -408,7 +408,7 @@ void exit_shm(struct task_struct *task)
up_write(&shm_ids(ns).rwsem);
}
static int shm_fault(struct vm_fault *vmf)
static vm_fault_t shm_fault(struct vm_fault *vmf)
{
struct file *file = vmf->vma->vm_file;
struct shm_file_data *sfd = shm_file_data(file);
......
......@@ -440,6 +440,14 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
continue;
}
charge = 0;
/*
* Don't duplicate many vmas if we've been oom-killed (for
* example)
*/
if (fatal_signal_pending(current)) {
retval = -EINTR;
goto out;
}
if (mpnt->vm_flags & VM_ACCOUNT) {
unsigned long len = vma_pages(mpnt);
......
......@@ -58,7 +58,7 @@ struct kcov {
static bool check_kcov_mode(enum kcov_mode needed_mode, struct task_struct *t)
{
enum kcov_mode mode;
unsigned int mode;
/*
* We are interested in code coverage as a function of a syscall inputs,
......@@ -241,7 +241,8 @@ static void kcov_put(struct kcov *kcov)
void kcov_task_init(struct task_struct *t)
{
t->kcov_mode = KCOV_MODE_DISABLED;
WRITE_ONCE(t->kcov_mode, KCOV_MODE_DISABLED);
barrier();
t->kcov_size = 0;
t->kcov_area = NULL;
t->kcov = NULL;
......@@ -323,6 +324,21 @@ static int kcov_close(struct inode *inode, struct file *filep)
return 0;
}
/*
* Fault in a lazily-faulted vmalloc area before it can be used by
* __santizer_cov_trace_pc(), to avoid recursion issues if any code on the
* vmalloc fault handling path is instrumented.
*/
static void kcov_fault_in_area(struct kcov *kcov)
{
unsigned long stride = PAGE_SIZE / sizeof(unsigned long);
unsigned long *area = kcov->area;
unsigned long offset;
for (offset = 0; offset < kcov->size; offset += stride)
READ_ONCE(area[offset]);
}
static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd,
unsigned long arg)
{
......@@ -371,6 +387,7 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd,
#endif
else
return -EINVAL;
kcov_fault_in_area(kcov);
/* Cache in task struct for performance. */
t->kcov_size = kcov->size;
t->kcov_area = kcov->area;
......
......@@ -829,6 +829,8 @@ static int kimage_load_normal_segment(struct kimage *image,
else
buf += mchunk;
mbytes -= mchunk;
cond_resched();
}
out:
return result;
......@@ -893,6 +895,8 @@ static int kimage_load_crash_segment(struct kimage *image,
else
buf += mchunk;
mbytes -= mchunk;
cond_resched();
}
out:
return result;
......
......@@ -39,7 +39,7 @@ static void relay_file_mmap_close(struct vm_area_struct *vma)
/*
* fault() vm_op implementation for relay file mapping.
*/
static int relay_buf_fault(struct vm_fault *vmf)
static vm_fault_t relay_buf_fault(struct vm_fault *vmf)
{
struct page *page;
struct rchan_buf *buf = vmf->vma->vm_private_data;
......
......@@ -10,6 +10,8 @@
#include <linux/kthread.h>
#include <linux/nospec.h>
#include <linux/kcov.h>
#include <asm/switch_to.h>
#include <asm/tlb.h>
......@@ -2633,6 +2635,7 @@ static inline void
prepare_task_switch(struct rq *rq, struct task_struct *prev,
struct task_struct *next)
{
kcov_prepare_switch(prev);
sched_info_switch(rq, prev, next);
perf_event_task_sched_out(prev, next);
rseq_preempt(prev);
......@@ -2702,6 +2705,7 @@ static struct rq *finish_task_switch(struct task_struct *prev)
finish_task(prev);
finish_lock_switch(rq);
finish_arch_post_lock_switch();
kcov_finish_switch(current);
fire_sched_in_preempt_notifiers(current);
/*
......
......@@ -1506,6 +1506,10 @@ config NETDEV_NOTIFIER_ERROR_INJECT
If unsure, say N.
config FUNCTION_ERROR_INJECTION
def_bool y
depends on HAVE_FUNCTION_ERROR_INJECTION && KPROBES
config FAULT_INJECTION
bool "Fault-injection framework"
depends on DEBUG_KERNEL
......@@ -1513,10 +1517,6 @@ config FAULT_INJECTION
Provide fault-injection framework.
For more details, see Documentation/fault-injection/.
config FUNCTION_ERROR_INJECTION
def_bool y
depends on HAVE_FUNCTION_ERROR_INJECTION && KPROBES
config FAILSLAB
bool "Fault-injection capability for kmalloc"
depends on FAULT_INJECTION
......@@ -1547,16 +1547,6 @@ config FAIL_IO_TIMEOUT
Only works with drivers that use the generic timeout handling,
for others it wont do anything.
config FAIL_MMC_REQUEST
bool "Fault-injection capability for MMC IO"
depends on FAULT_INJECTION_DEBUG_FS && MMC
help
Provide fault-injection capability for MMC IO.
This will make the mmc core return data errors. This is
useful to test the error handling in the mmc block device
and to test how the mmc host driver handles retries from
the block device.
config FAIL_FUTEX
bool "Fault-injection capability for futexes"
select DEBUG_FS
......@@ -1564,6 +1554,12 @@ config FAIL_FUTEX
help
Provide fault-injection capability for futexes.
config FAULT_INJECTION_DEBUG_FS
bool "Debugfs entries for fault-injection capabilities"
depends on FAULT_INJECTION && SYSFS && DEBUG_FS
help
Enable configuration of fault-injection capabilities via debugfs.
config FAIL_FUNCTION
bool "Fault-injection capability for functions"
depends on FAULT_INJECTION_DEBUG_FS && FUNCTION_ERROR_INJECTION
......@@ -1574,11 +1570,15 @@ config FAIL_FUNCTION
an error value and have to handle it. This is useful to test the
error handling in various subsystems.
config FAULT_INJECTION_DEBUG_FS
bool "Debugfs entries for fault-injection capabilities"
depends on FAULT_INJECTION && SYSFS && DEBUG_FS
config FAIL_MMC_REQUEST
bool "Fault-injection capability for MMC IO"
depends on FAULT_INJECTION_DEBUG_FS && MMC
help
Enable configuration of fault-injection capabilities via debugfs.
Provide fault-injection capability for MMC IO.
This will make the mmc core return data errors. This is
useful to test the error handling in the mmc block device
and to test how the mmc host driver handles retries from
the block device.
config FAULT_INJECTION_STACKTRACE_FILTER
bool "stacktrace filter for fault-injection capabilities"
......
......@@ -260,6 +260,13 @@ plain(void)
{
int err;
/*
* Make sure crng is ready. Otherwise we get "(ptrval)" instead
* of a hashed address when printing '%p' in plain_hash() and
* plain_format().
*/
wait_for_random_bytes();
err = plain_hash();
if (err) {
pr_warn("plain 'p' does not appear to be hashed\n");
......
......@@ -307,12 +307,10 @@ static int __init init_cleancache(void)
struct dentry *root = debugfs_create_dir("cleancache", NULL);
if (root == NULL)
return -ENXIO;
debugfs_create_u64("succ_gets", S_IRUGO, root, &cleancache_succ_gets);
debugfs_create_u64("failed_gets", S_IRUGO,
root, &cleancache_failed_gets);
debugfs_create_u64("puts", S_IRUGO, root, &cleancache_puts);
debugfs_create_u64("invalidates", S_IRUGO,
root, &cleancache_invalidates);
debugfs_create_u64("succ_gets", 0444, root, &cleancache_succ_gets);
debugfs_create_u64("failed_gets", 0444, root, &cleancache_failed_gets);
debugfs_create_u64("puts", 0444, root, &cleancache_puts);
debugfs_create_u64("invalidates", 0444, root, &cleancache_invalidates);
#endif
return 0;
}
......
......@@ -172,23 +172,18 @@ static void cma_debugfs_add_one(struct cma *cma, int idx)
tmp = debugfs_create_dir(name, cma_debugfs_root);
debugfs_create_file("alloc", S_IWUSR, tmp, cma,
&cma_alloc_fops);
debugfs_create_file("free", S_IWUSR, tmp, cma,
&cma_free_fops);
debugfs_create_file("base_pfn", S_IRUGO, tmp,
&cma->base_pfn, &cma_debugfs_fops);
debugfs_create_file("count", S_IRUGO, tmp,
&cma->count, &cma_debugfs_fops);
debugfs_create_file("order_per_bit", S_IRUGO, tmp,
&cma->order_per_bit, &cma_debugfs_fops);
debugfs_create_file("used", S_IRUGO, tmp, cma, &cma_used_fops);
debugfs_create_file("maxchunk", S_IRUGO, tmp, cma, &cma_maxchunk_fops);
debugfs_create_file("alloc", 0200, tmp, cma, &cma_alloc_fops);
debugfs_create_file("free", 0200, tmp, cma, &cma_free_fops);
debugfs_create_file("base_pfn", 0444, tmp,
&cma->base_pfn, &cma_debugfs_fops);
debugfs_create_file("count", 0444, tmp, &cma->count, &cma_debugfs_fops);
debugfs_create_file("order_per_bit", 0444, tmp,
&cma->order_per_bit, &cma_debugfs_fops);
debugfs_create_file("used", 0444, tmp, cma, &cma_used_fops);
debugfs_create_file("maxchunk", 0444, tmp, cma, &cma_maxchunk_fops);
u32s = DIV_ROUND_UP(cma_bitmap_maxno(cma), BITS_PER_BYTE * sizeof(u32));
debugfs_create_u32_array("bitmap", S_IRUGO, tmp, (u32*)cma->bitmap, u32s);
debugfs_create_u32_array("bitmap", 0444, tmp, (u32 *)cma->bitmap, u32s);
}
static int __init cma_debugfs_init(void)
......
......@@ -1899,7 +1899,7 @@ static ssize_t sysfs_compact_node(struct device *dev,
return count;
}
static DEVICE_ATTR(compact, S_IWUSR, NULL, sysfs_compact_node);
static DEVICE_ATTR(compact, 0200, NULL, sysfs_compact_node);
int compaction_register_node(struct node *node)
{
......
......@@ -105,7 +105,7 @@ show_pools(struct device *dev, struct device_attribute *attr, char *buf)
return PAGE_SIZE - size;
}
static DEVICE_ATTR(pools, S_IRUGO, show_pools, NULL);
static DEVICE_ATTR(pools, 0444, show_pools, NULL);
/**
* dma_pool_create - Creates a pool of consistent memory blocks, for dma.
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment