Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3ecafda9 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'akpm' (patches from Andrew)

Merge misc fixes from Andrew Morton:
 "16 fixes"

* emailed patches from Andrew Morton <akpm@linux-foundation.org>:
  coredump: fix race condition between mmget_not_zero()/get_task_mm() and core dumping
  mm/kmemleak.c: fix unused-function warning
  init: initialize jump labels before command line option parsing
  kernel/watchdog_hld.c: hard lockup message should end with a newline
  kcov: improve CONFIG_ARCH_HAS_KCOV help text
  mm: fix inactive list balancing between NUMA nodes and cgroups
  mm/hotplug: treat CMA pages as unmovable
  proc: fixup proc-pid-vm test
  proc: fix map_files test on F29
  mm/vmstat.c: fix /proc/vmstat format for CONFIG_DEBUG_TLBFLUSH=y CONFIG_SMP=n
  mm/memory_hotplug: do not unlock after failing to take the device_hotplug_lock
  mm: swapoff: shmem_unuse() stop eviction without igrab()
  mm: swapoff: take notice of completion sooner
  mm: swapoff: remove too limiting SWAP_UNUSE_MAX_TRIES
  mm: swapoff: shmem_find_swap_entries() filter out other types
  slab: store tagged freelist for off-slab slabmgmt
parents b222e9af 04f5866e
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -506,7 +506,7 @@ static ssize_t probe_store(struct device *dev, struct device_attribute *attr,


	ret = lock_device_hotplug_sysfs();
	ret = lock_device_hotplug_sysfs();
	if (ret)
	if (ret)
		goto out;
		return ret;


	nid = memory_add_physaddr_to_nid(phys_addr);
	nid = memory_add_physaddr_to_nid(phys_addr);
	ret = __add_memory(nid, phys_addr,
	ret = __add_memory(nid, phys_addr,
+3 −0
Original line number Original line Diff line number Diff line
@@ -993,6 +993,8 @@ void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile)
		 * will only be one mm, so no big deal.
		 * will only be one mm, so no big deal.
		 */
		 */
		down_write(&mm->mmap_sem);
		down_write(&mm->mmap_sem);
		if (!mmget_still_valid(mm))
			goto skip_mm;
		mutex_lock(&ufile->umap_lock);
		mutex_lock(&ufile->umap_lock);
		list_for_each_entry_safe (priv, next_priv, &ufile->umaps,
		list_for_each_entry_safe (priv, next_priv, &ufile->umaps,
					  list) {
					  list) {
@@ -1007,6 +1009,7 @@ void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile)
			vma->vm_flags &= ~(VM_SHARED | VM_MAYSHARE);
			vma->vm_flags &= ~(VM_SHARED | VM_MAYSHARE);
		}
		}
		mutex_unlock(&ufile->umap_lock);
		mutex_unlock(&ufile->umap_lock);
	skip_mm:
		up_write(&mm->mmap_sem);
		up_write(&mm->mmap_sem);
		mmput(mm);
		mmput(mm);
	}
	}
+18 −0
Original line number Original line Diff line number Diff line
@@ -1143,6 +1143,24 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf,
					count = -EINTR;
					count = -EINTR;
					goto out_mm;
					goto out_mm;
				}
				}
				/*
				 * Avoid to modify vma->vm_flags
				 * without locked ops while the
				 * coredump reads the vm_flags.
				 */
				if (!mmget_still_valid(mm)) {
					/*
					 * Silently return "count"
					 * like if get_task_mm()
					 * failed. FIXME: should this
					 * function have returned
					 * -ESRCH if get_task_mm()
					 * failed like if
					 * get_proc_task() fails?
					 */
					up_write(&mm->mmap_sem);
					goto out_mm;
				}
				for (vma = mm->mmap; vma; vma = vma->vm_next) {
				for (vma = mm->mmap; vma; vma = vma->vm_next) {
					vma->vm_flags &= ~VM_SOFTDIRTY;
					vma->vm_flags &= ~VM_SOFTDIRTY;
					vma_set_page_prot(vma);
					vma_set_page_prot(vma);
+9 −0
Original line number Original line Diff line number Diff line
@@ -629,6 +629,8 @@ static void userfaultfd_event_wait_completion(struct userfaultfd_ctx *ctx,


		/* the various vma->vm_userfaultfd_ctx still points to it */
		/* the various vma->vm_userfaultfd_ctx still points to it */
		down_write(&mm->mmap_sem);
		down_write(&mm->mmap_sem);
		/* no task can run (and in turn coredump) yet */
		VM_WARN_ON(!mmget_still_valid(mm));
		for (vma = mm->mmap; vma; vma = vma->vm_next)
		for (vma = mm->mmap; vma; vma = vma->vm_next)
			if (vma->vm_userfaultfd_ctx.ctx == release_new_ctx) {
			if (vma->vm_userfaultfd_ctx.ctx == release_new_ctx) {
				vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX;
				vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX;
@@ -883,6 +885,8 @@ static int userfaultfd_release(struct inode *inode, struct file *file)
	 * taking the mmap_sem for writing.
	 * taking the mmap_sem for writing.
	 */
	 */
	down_write(&mm->mmap_sem);
	down_write(&mm->mmap_sem);
	if (!mmget_still_valid(mm))
		goto skip_mm;
	prev = NULL;
	prev = NULL;
	for (vma = mm->mmap; vma; vma = vma->vm_next) {
	for (vma = mm->mmap; vma; vma = vma->vm_next) {
		cond_resched();
		cond_resched();
@@ -905,6 +909,7 @@ static int userfaultfd_release(struct inode *inode, struct file *file)
		vma->vm_flags = new_flags;
		vma->vm_flags = new_flags;
		vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX;
		vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX;
	}
	}
skip_mm:
	up_write(&mm->mmap_sem);
	up_write(&mm->mmap_sem);
	mmput(mm);
	mmput(mm);
wakeup:
wakeup:
@@ -1333,6 +1338,8 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
		goto out;
		goto out;


	down_write(&mm->mmap_sem);
	down_write(&mm->mmap_sem);
	if (!mmget_still_valid(mm))
		goto out_unlock;
	vma = find_vma_prev(mm, start, &prev);
	vma = find_vma_prev(mm, start, &prev);
	if (!vma)
	if (!vma)
		goto out_unlock;
		goto out_unlock;
@@ -1520,6 +1527,8 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx,
		goto out;
		goto out;


	down_write(&mm->mmap_sem);
	down_write(&mm->mmap_sem);
	if (!mmget_still_valid(mm))
		goto out_unlock;
	vma = find_vma_prev(mm, start, &prev);
	vma = find_vma_prev(mm, start, &prev);
	if (!vma)
	if (!vma)
		goto out_unlock;
		goto out_unlock;
+21 −0
Original line number Original line Diff line number Diff line
@@ -49,6 +49,27 @@ static inline void mmdrop(struct mm_struct *mm)
		__mmdrop(mm);
		__mmdrop(mm);
}
}


/*
 * This has to be called after a get_task_mm()/mmget_not_zero()
 * followed by taking the mmap_sem for writing before modifying the
 * vmas or anything the coredump pretends not to change from under it.
 *
 * NOTE: find_extend_vma() called from GUP context is the only place
 * that can modify the "mm" (notably the vm_start/end) under mmap_sem
 * for reading and outside the context of the process, so it is also
 * the only case that holds the mmap_sem for reading that must call
 * this function. Generally if the mmap_sem is hold for reading
 * there's no need of this check after get_task_mm()/mmget_not_zero().
 *
 * This function can be obsoleted and the check can be removed, after
 * the coredump code will hold the mmap_sem for writing before
 * invoking the ->core_dump methods.
 */
static inline bool mmget_still_valid(struct mm_struct *mm)
{
	return likely(!mm->core_state);
}

/**
/**
 * mmget() - Pin the address space associated with a &struct mm_struct.
 * mmget() - Pin the address space associated with a &struct mm_struct.
 * @mm: The address space to pin.
 * @mm: The address space to pin.
Loading