// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  Fast Userspace Mutexes (which I call "Futexes!").
 *  (C) Rusty Russell, IBM 2002
 *
 *  Generalized futexes, futex requeueing, misc fixes by Ingo Molnar
 *  (C) Copyright 2003 Red Hat Inc, All Rights Reserved
 *
 *  Removed page pinning, fix privately mapped COW pages and other cleanups
 *  (C) Copyright 2003, 2004 Jamie Lokier
 *
 *  Robust futex support started by Ingo Molnar
 *  (C) Copyright 2006 Red Hat Inc, All Rights Reserved
 *  Thanks to Thomas Gleixner for suggestions, analysis and fixes.
 *
 *  PI-futex support started by Ingo Molnar and Thomas Gleixner
 *  Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
 *  Copyright (C) 2006 Timesys Corp., Thomas Gleixner <tglx@timesys.com>
 *
 *  PRIVATE futexes by Eric Dumazet
 *  Copyright (C) 2007 Eric Dumazet <dada1@cosmosbay.com>
 *
 *  Requeue-PI support by Darren Hart <dvhltc@us.ibm.com>
 *  Copyright (C) IBM Corporation, 2009
 *  Thanks to Thomas Gleixner for conceptual design and careful reviews.
 *
 *  Thanks to Ben LaHaise for yelling "hashed waitqueues" loudly
 *  enough at me, Linus for the original (flawed) idea, Matthew
 *  Kirkwood for proof-of-concept implementation.
 *
 *  "The futexes are also cursed."
 *  "But they come in a choice of three flavours!"
 */
#include <linux/compat.h>
#include <linux/debugfs.h>
#include <linux/fault-inject.h>
#include <linux/gfp.h>
#include <linux/jhash.h>
#include <linux/memblock.h>
#include <linux/mempolicy.h>
#include <linux/mmap_lock.h>
#include <linux/pagemap.h>
#include <linux/plist.h>
#include <linux/prctl.h>
#include <linux/rseq.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/kmemleak.h>
#include <linux/wait_bit.h>

#include <vdso/futex.h>

#include <asm/runtime-const.h>

#include "futex.h"
#include "../locking/rtmutex_common.h"

static u32 __futex_mask __ro_after_init;
static u32 __futex_shift __ro_after_init;
static struct futex_hash_bucket **__futex_queues __ro_after_init;

static __always_inline struct futex_hash_bucket **futex_queues(void)
{
	return runtime_const_ptr(__futex_queues);
}

struct futex_private_hash {
	int		state;
	unsigned int	hash_mask;
	struct rcu_head	rcu;
	void		*mm;
	bool		custom;
	struct futex_hash_bucket queues[];
};

/*
 * Fault injections for futexes.
 */
#ifdef CONFIG_FAIL_FUTEX

static struct {
	struct fault_attr attr;

	bool ignore_private;
} fail_futex = {
	.attr = FAULT_ATTR_INITIALIZER,
	.ignore_private = false,
};

static int __init setup_fail_futex(char *str)
{
	return setup_fault_attr(&fail_futex.attr, str);
}
__setup("fail_futex=", setup_fail_futex);

bool should_fail_futex(bool fshared)
{
	if (fail_futex.ignore_private && !fshared)
		return false;

	return should_fail(&fail_futex.attr, 1);
}

#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS

static int __init fail_futex_debugfs(void)
{
	umode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
	struct dentry *dir;

	dir = fault_create_debugfs_attr("fail_futex", NULL,
					&fail_futex.attr);
	if (IS_ERR(dir))
		return PTR_ERR(dir);

	debugfs_create_bool("ignore-private", mode, dir,
			    &fail_futex.ignore_private);
	return 0;
}

late_initcall(fail_futex_debugfs);

#endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */

#endif /* CONFIG_FAIL_FUTEX */

static struct futex_hash_bucket *
__futex_hash(union futex_key *key, struct futex_private_hash *fph, struct futex_private_hash **fph_p);

#ifdef CONFIG_FUTEX_PRIVATE_HASH
static bool futex_ref_get(struct futex_private_hash *fph);
static bool futex_ref_put(struct futex_private_hash *fph);
static bool futex_ref_is_dead(struct futex_private_hash *fph);

enum { FR_PERCPU = 0, FR_ATOMIC };

static bool futex_private_hash_get(struct futex_private_hash *fph)
{
	return futex_ref_get(fph);
}

void futex_private_hash_put(struct futex_private_hash *fph)
{
	struct mm_struct *mm;

	if (!fph)
		return;

	mm = fph->mm;
	if (futex_ref_put(fph))
		wake_up_var(mm);
}

static struct futex_hash_bucket *
__futex_hash_private(union futex_key *key, struct futex_private_hash *fph)
{
	u32 hash;

	hash = jhash2((void *)&key->private.address, sizeof(key->private.address) / 4,
		      key->both.offset);

	return &fph->queues[hash & fph->hash_mask];
}

static void futex_rehash_private(struct futex_private_hash *old,
				 struct futex_private_hash *new)
{
	struct futex_hash_bucket *hb_old, *hb_new;
	unsigned int slots = old->hash_mask + 1;
	unsigned int i;

	for (i = 0; i < slots; i++) {
		struct futex_q *this, *tmp;

		hb_old = &old->queues[i];

		spin_lock(&hb_old->lock);
		plist_for_each_entry_safe(this, tmp, &hb_old->chain, list) {
			plist_del(&this->list, &hb_old->chain);
			futex_hb_waiters_dec(hb_old);

			WARN_ON_ONCE(this->lock_ptr != &hb_old->lock);

			hb_new = __futex_hash(&this->key, new, NULL);
			futex_hb_waiters_inc(hb_new);
			/*
			 * The new pointer isn't published yet but an already
			 * moved user can be unqueued due to timeout or signal.
			 */
			spin_lock_nested(&hb_new->lock, SINGLE_DEPTH_NESTING);
			plist_add(&this->list, &hb_new->chain);
			this->lock_ptr = &hb_new->lock;
			spin_unlock(&hb_new->lock);
		}
		spin_unlock(&hb_old->lock);
	}
}

static bool __futex_pivot_hash(struct mm_struct *mm, struct futex_private_hash *new)
{
	struct futex_mm_phash *mmph = &mm->futex.phash;
	struct futex_private_hash *fph;

	WARN_ON_ONCE(mmph->hash_new);

	fph = rcu_dereference_protected(mmph->hash, lockdep_is_held(&mmph->lock));
	if (fph) {
		if (!futex_ref_is_dead(fph)) {
			mmph->hash_new = new;
			return false;
		}

		futex_rehash_private(fph, new);
	}
	new->state = FR_PERCPU;
	scoped_guard(rcu) {
		mmph->batches = get_state_synchronize_rcu();
		rcu_assign_pointer(mmph->hash, new);
	}
	kvfree_rcu(fph, rcu);
	return true;
}

static void futex_pivot_hash(struct mm_struct *mm)
{
	scoped_guard(mutex, &mm->futex.phash.lock) {
		struct futex_private_hash *fph;

		fph = mm->futex.phash.hash_new;
		if (fph) {
			mm->futex.phash.hash_new = NULL;
			__futex_pivot_hash(mm, fph);
		}
	}
}

struct futex_private_hash *futex_private_hash(struct mm_struct *mm)
{
	/*
	 * Ideally we don't loop. If there is a replacement in progress
	 * then a new private hash is already prepared and a reference can't be
	 * obtained once the last user dropped it's.
	 * In that case we block on mm_struct::futex_hash_lock and either have
	 * to perform the replacement or wait while someone else is doing the
	 * job. Eitherway, on the second iteration we acquire a reference on the
	 * new private hash or loop again because a new replacement has been
	 * requested.
	 */
again:
	scoped_guard(rcu) {
		struct futex_private_hash *fph;

		fph = rcu_dereference(mm->futex.phash.hash);
		if (!fph)
			return NULL;

		if (futex_private_hash_get(fph))
			return fph;
	}
	futex_pivot_hash(mm);
	goto again;
}

struct futex_bucket_ref futex_hash(union futex_key *key)
{
again:
	scoped_guard(rcu) {
		struct futex_private_hash *fph = NULL;
		struct futex_hash_bucket *hb;

		hb = __futex_hash(key, NULL, &fph);

		if (!fph || futex_private_hash_get(fph))
			return (struct futex_bucket_ref){ .hb = hb, .fph = fph };
	}
	futex_pivot_hash(key->private.mm);
	goto again;
}

#else /* !CONFIG_FUTEX_PRIVATE_HASH */

struct futex_bucket_ref futex_hash(union futex_key *key)
{
	return (struct futex_bucket_ref){ .hb = __futex_hash(key, NULL, NULL), .fph = NULL };
}

#endif /* CONFIG_FUTEX_PRIVATE_HASH */

#ifdef CONFIG_FUTEX_MPOL

static int __futex_key_to_node(struct mm_struct *mm, unsigned long addr)
{
	struct vm_area_struct *vma = vma_lookup(mm, addr);
	struct mempolicy *mpol;
	int node = FUTEX_NO_NODE;

	if (!vma)
		return FUTEX_NO_NODE;

	mpol = READ_ONCE(vma->vm_policy);
	if (!mpol)
		return FUTEX_NO_NODE;

	switch (mpol->mode) {
	case MPOL_PREFERRED:
		node = first_node(mpol->nodes);
		break;
	case MPOL_PREFERRED_MANY:
	case MPOL_BIND:
		if (mpol->home_node != NUMA_NO_NODE)
			node = mpol->home_node;
		break;
	default:
		break;
	}

	return node;
}

static int futex_key_to_node_opt(struct mm_struct *mm, unsigned long addr)
{
	int seq, node;

	guard(rcu)();

	if (!mmap_lock_speculate_try_begin(mm, &seq))
		return -EBUSY;

	node = __futex_key_to_node(mm, addr);

	if (mmap_lock_speculate_retry(mm, seq))
		return -EAGAIN;

	return node;
}

static int futex_mpol(struct mm_struct *mm, unsigned long addr)
{
	int node;

	node = futex_key_to_node_opt(mm, addr);
	if (node >= FUTEX_NO_NODE)
		return node;

	guard(mmap_read_lock)(mm);
	return __futex_key_to_node(mm, addr);
}

#else /* !CONFIG_FUTEX_MPOL */

static int futex_mpol(struct mm_struct *mm, unsigned long addr)
{
	return FUTEX_NO_NODE;
}

#endif /* CONFIG_FUTEX_MPOL */

/**
 * __futex_hash - Return the hash bucket
 * @key:	Pointer to the futex key for which the hash is calculated
 * @fph:	Pointer to private hash if known
 * @fph_p:	Pointer to a private hash pointer; output for the private hash
 *              used when set.
 *
 * We hash on the keys returned from get_futex_key (see below) and return the
 * corresponding hash bucket.
 * If the FUTEX is PROCESS_PRIVATE then a per-process hash bucket (from the
 * private hash) is returned if existing. Otherwise a hash bucket from the
 * global hash is returned.
 */
static struct futex_hash_bucket *
__futex_hash(union futex_key *key, struct futex_private_hash *fph, struct futex_private_hash **fph_p)
{
	int node = key->both.node;
	u32 hash;

#ifdef CONFIG_FUTEX_PRIVATE_HASH
	if (node == FUTEX_NO_NODE && futex_key_is_private(key)) {
		if (!fph)
			fph = rcu_dereference(key->private.mm->futex.phash.hash);
		if (fph && fph->hash_mask) {
			if (fph_p)
				*fph_p = fph;
			return __futex_hash_private(key, fph);
		}
	}
#endif

	hash = jhash2((u32 *)key, offsetof(typeof(*key), both.offset) / sizeof(u32),
		      key->both.offset);

	if (node == FUTEX_NO_NODE) {
		/*
		 * In case of !FLAGS_NUMA, use some unused hash bits to pick a
		 * node -- this ensures regular futexes are interleaved across
		 * the nodes and avoids having to allocate multiple
		 * hash-tables.
		 *
		 * NOTE: this isn't perfectly uniform, but it is fast and
		 * handles sparse node masks.
		 */
		node = runtime_const_shift_right_32(hash, __futex_shift) % nr_node_ids;
		if (!node_possible(node)) {
			node = find_next_bit_wrap(node_possible_map.bits, nr_node_ids, node);
		}
	}

	return &futex_queues()[node][runtime_const_mask_32(hash, __futex_mask)];
}

/**
 * futex_setup_timer - set up the sleeping hrtimer.
 * @time:	ptr to the given timeout value
 * @timeout:	the hrtimer_sleeper structure to be set up
 * @flags:	futex flags
 * @range_ns:	optional range in ns
 *
 * Return: Initialized hrtimer_sleeper structure or NULL if no timeout
 *	   value given
 */
struct hrtimer_sleeper *futex_setup_timer(ktime_t *time, struct hrtimer_sleeper *timeout,
					  int flags, u64 range_ns)
{
	if (!time)
		return NULL;

	hrtimer_setup_sleeper_on_stack(timeout,
				       (flags & FLAGS_CLOCKRT) ? CLOCK_REALTIME : CLOCK_MONOTONIC,
				       HRTIMER_MODE_ABS);
	/*
	 * If range_ns is 0, calling hrtimer_set_expires_range_ns() is
	 * effectively the same as calling hrtimer_set_expires().
	 */
	hrtimer_set_expires_range_ns(&timeout->timer, *time, range_ns);

	return timeout;
}

/*
 * Generate a machine wide unique identifier for this inode.
 *
 * This relies on u64 not wrapping in the life-time of the machine; which with
 * 1ns resolution means almost 585 years.
 *
 * This further relies on the fact that a well formed program will not unmap
 * the file while it has a (shared) futex waiting on it. This mapping will have
 * a file reference which pins the mount and inode.
 *
 * If for some reason an inode gets evicted and read back in again, it will get
 * a new sequence number and will _NOT_ match, even though it is the exact same
 * file.
 *
 * It is important that futex_match() will never have a false-positive, esp.
 * for PI futexes that can mess up the state. The above argues that false-negatives
 * are only possible for malformed programs.
 */
static u64 get_inode_sequence_number(struct inode *inode)
{
	static atomic64_t i_seq;
	u64 old;

	/* Does the inode already have a sequence number? */
	old = atomic64_read(&inode->i_sequence);
	if (likely(old))
		return old;

	for (;;) {
		u64 new = atomic64_inc_return(&i_seq);
		if (WARN_ON_ONCE(!new))
			continue;

		old = 0;
		if (!atomic64_try_cmpxchg_relaxed(&inode->i_sequence, &old, new))
			return old;
		return new;
	}
}

/**
 * get_futex_key() - Get parameters which are the keys for a futex
 * @uaddr:	virtual address of the futex
 * @flags:	FLAGS_*
 * @key:	address where result is stored.
 * @rw:		mapping needs to be read/write (values: FUTEX_READ,
 *              FUTEX_WRITE)
 *
 * Return: a negative error code or 0
 *
 * The key words are stored in @key on success.
 *
 * For shared mappings (when @fshared), the key is:
 *
 *   ( inode->i_sequence, page offset within mapping, offset_within_page )
 *
 * [ also see get_inode_sequence_number() ]
 *
 * For private mappings (or when !@fshared), the key is:
 *
 *   ( current->mm, address, 0 )
 *
 * This allows (cross process, where applicable) identification of the futex
 * without keeping the page pinned for the duration of the FUTEX_WAIT.
 *
 * lock_page() might sleep, the caller should not hold a spinlock.
 */
int get_futex_key(u32 __user *uaddr, unsigned int flags, union futex_key *key,
		  enum futex_access rw)
{
	unsigned long address = (unsigned long)uaddr;
	struct mm_struct *mm = current->mm;
	struct page *page;
	struct folio *folio;
	struct address_space *mapping;
	int node, err, size, ro = 0;
	bool node_updated = false;
	bool fshared;

	fshared = flags & FLAGS_SHARED;
	size = futex_size(flags);
	if (flags & FLAGS_NUMA)
		size *= 2;

	/*
	 * The futex address must be "naturally" aligned.
	 */
	key->both.offset = address % PAGE_SIZE;
	if (unlikely((address & (size-1)) != 0))
		return -EINVAL;
	address -= key->both.offset;

	if (unlikely(!access_ok(uaddr, size)))
		return -EFAULT;

	if (unlikely(should_fail_futex(fshared)))
		return -EFAULT;

	node = FUTEX_NO_NODE;

	if (flags & FLAGS_NUMA) {
		u32 __user *naddr = (void *)uaddr + size / 2;

		if (get_user_inline(node, naddr))
			return -EFAULT;

		if ((node != FUTEX_NO_NODE) &&
		    ((unsigned int)node >= MAX_NUMNODES || !node_possible(node)))
			return -EINVAL;
	}

	if (node == FUTEX_NO_NODE && (flags & FLAGS_MPOL)) {
		node = futex_mpol(mm, address);
		node_updated = true;
	}

	if (flags & FLAGS_NUMA) {
		u32 __user *naddr = (void *)uaddr + size / 2;

		if (node == FUTEX_NO_NODE) {
			node = numa_node_id();
			node_updated = true;
		}
		if (node_updated && put_user_inline(node, naddr))
			return -EFAULT;
	}

	key->both.node = node;

	/*
	 * PROCESS_PRIVATE futexes are fast.
	 * As the mm cannot disappear under us and the 'key' only needs
	 * virtual address, we dont even have to find the underlying vma.
	 * Note : We do have to check 'uaddr' is a valid user address,
	 *        but access_ok() should be faster than find_vma()
	 */
	if (!fshared) {
		/*
		 * On no-MMU, shared futexes are treated as private, therefore
		 * we must not include the current process in the key. Since
		 * there is only one address space, the address is a unique key
		 * on its own.
		 */
		if (IS_ENABLED(CONFIG_MMU))
			key->private.mm = mm;
		else
			key->private.mm = NULL;

		key->private.address = address;
		return 0;
	}

again:
	/* Ignore any VERIFY_READ mapping (futex common case) */
	if (unlikely(should_fail_futex(true)))
		return -EFAULT;

	err = get_user_pages_fast(address, 1, FOLL_WRITE, &page);
	/*
	 * If write access is not required (eg. FUTEX_WAIT), try
	 * and get read-only access.
	 */
	if (err == -EFAULT && rw == FUTEX_READ) {
		err = get_user_pages_fast(address, 1, 0, &page);
		ro = 1;
	}
	if (err < 0)
		return err;
	else
		err = 0;

	/*
	 * The treatment of mapping from this point on is critical. The folio
	 * lock protects many things but in this context the folio lock
	 * stabilizes mapping, prevents inode freeing in the shared
	 * file-backed region case and guards against movement to swap cache.
	 *
	 * Strictly speaking the folio lock is not needed in all cases being
	 * considered here and folio lock forces unnecessarily serialization.
	 * From this point on, mapping will be re-verified if necessary and
	 * folio lock will be acquired only if it is unavoidable
	 *
	 * Mapping checks require the folio so it is looked up now. For
	 * anonymous pages, it does not matter if the folio is split
	 * in the future as the key is based on the address. For
	 * filesystem-backed pages, the precise page is required as the
	 * index of the page determines the key.
	 */
	folio = page_folio(page);
	mapping = READ_ONCE(folio->mapping);

	/*
	 * If folio->mapping is NULL, then it cannot be an anonymous
	 * page; but it might be the ZERO_PAGE or in the gate area or
	 * in a special mapping (all cases which we are happy to fail);
	 * or it may have been a good file page when get_user_pages_fast
	 * found it, but truncated or holepunched or subjected to
	 * invalidate_complete_page2 before we got the folio lock (also
	 * cases which we are happy to fail).  And we hold a reference,
	 * so refcount care in invalidate_inode_page's remove_mapping
	 * prevents drop_caches from setting mapping to NULL beneath us.
	 *
	 * The case we do have to guard against is when memory pressure made
	 * shmem_writepage move it from filecache to swapcache beneath us:
	 * an unlikely race, but we do need to retry for folio->mapping.
	 */
	if (unlikely(!mapping)) {
		int shmem_swizzled;

		/*
		 * Folio lock is required to identify which special case above
		 * applies. If this is really a shmem page then the folio lock
		 * will prevent unexpected transitions.
		 */
		folio_lock(folio);
		shmem_swizzled = folio_test_swapcache(folio) || folio->mapping;
		folio_unlock(folio);
		folio_put(folio);

		if (shmem_swizzled)
			goto again;

		return -EFAULT;
	}

	/*
	 * Private mappings are handled in a simple way.
	 *
	 * If the futex key is stored in anonymous memory, then the associated
	 * object is the mm which is implicitly pinned by the calling process.
	 *
	 * NOTE: When userspace waits on a MAP_SHARED mapping, even if
	 * it's a read-only handle, it's expected that futexes attach to
	 * the object not the particular process.
	 */
	if (folio_test_anon(folio)) {
		/*
		 * A RO anonymous page will never change and thus doesn't make
		 * sense for futex operations.
		 */
		if (unlikely(should_fail_futex(true)) || ro) {
			err = -EFAULT;
			goto out;
		}

		key->both.offset |= FUT_OFF_MMSHARED; /* ref taken on mm */
		key->private.mm = mm;
		key->private.address = address;

	} else {
		struct inode *inode;

		/*
		 * The associated futex object in this case is the inode and
		 * the folio->mapping must be traversed. Ordinarily this should
		 * be stabilised under folio lock but it's not strictly
		 * necessary in this case as we just want to pin the inode, not
		 * update i_pages or anything like that.
		 *
		 * The RCU read lock is taken as the inode is finally freed
		 * under RCU. If the mapping still matches expectations then the
		 * mapping->host can be safely accessed as being a valid inode.
		 */
		rcu_read_lock();

		if (READ_ONCE(folio->mapping) != mapping) {
			rcu_read_unlock();
			folio_put(folio);

			goto again;
		}

		inode = READ_ONCE(mapping->host);
		if (!inode) {
			rcu_read_unlock();
			folio_put(folio);

			goto again;
		}

		key->both.offset |= FUT_OFF_INODE; /* inode-based key */
		key->shared.i_seq = get_inode_sequence_number(inode);
		key->shared.pgoff = page_pgoff(folio, page);
		rcu_read_unlock();
	}

out:
	folio_put(folio);
	return err;
}

/**
 * fault_in_user_writeable() - Fault in user address and verify RW access
 * @uaddr:	pointer to faulting user space address
 *
 * Slow path to fixup the fault we just took in the atomic write
 * access to @uaddr.
 *
 * We have no generic implementation of a non-destructive write to the
 * user address. We know that we faulted in the atomic pagefault
 * disabled section so we can as well avoid the #PF overhead by
 * calling get_user_pages() right away.
 */
int fault_in_user_writeable(u32 __user *uaddr)
{
	struct mm_struct *mm = current->mm;
	int ret;

	mmap_read_lock(mm);
	ret = fixup_user_fault(mm, (unsigned long)uaddr,
			       FAULT_FLAG_WRITE, NULL);
	mmap_read_unlock(mm);

	return ret < 0 ? ret : 0;
}

/**
 * futex_top_waiter() - Return the highest priority waiter on a futex
 * @hb:		the hash bucket the futex_q's reside in
 * @key:	the futex key (to distinguish it from other futex futex_q's)
 *
 * Must be called with the hb lock held.
 */
struct futex_q *futex_top_waiter(struct futex_hash_bucket *hb, union futex_key *key)
{
	struct futex_q *this;

	plist_for_each_entry(this, &hb->chain, list) {
		if (futex_match(&this->key, key))
			return this;
	}
	return NULL;
}

/**
 * wait_for_owner_exiting - Block until the owner has exited
 * @ret: owner's current futex lock status
 * @exiting:	Pointer to the exiting task
 *
 * Caller must hold a refcount on @exiting.
 */
void wait_for_owner_exiting(int ret, struct task_struct *exiting)
{
	if (ret != -EBUSY) {
		WARN_ON_ONCE(exiting);
		return;
	}

	if (WARN_ON_ONCE(ret == -EBUSY && !exiting))
		return;

	mutex_lock(&exiting->futex.exit_mutex);
	/*
	 * No point in doing state checking here. If the waiter got here
	 * while the task was in exec()->exec_futex_release() then it can
	 * have any FUTEX_STATE_* value when the waiter has acquired the
	 * mutex. OK, if running, EXITING or DEAD if it reached exit()
	 * already. Highly unlikely and not a problem. Just one more round
	 * through the futex maze.
	 */
	mutex_unlock(&exiting->futex.exit_mutex);

	put_task_struct(exiting);
}

/**
 * __futex_unqueue() - Remove the futex_q from its futex_hash_bucket
 * @q:	The futex_q to unqueue
 *
 * The q->lock_ptr must not be NULL and must be held by the caller.
 */
void __futex_unqueue(struct futex_q *q)
{
	struct futex_hash_bucket *hb;

	if (WARN_ON_SMP(!q->lock_ptr) || WARN_ON(plist_node_empty(&q->list)))
		return;
	lockdep_assert_held(q->lock_ptr);

	hb = container_of(q->lock_ptr, struct futex_hash_bucket, lock);
	plist_del(&q->list, &hb->chain);
	futex_hb_waiters_dec(hb);
}

/* The key must be already stored in q->key. */
void futex_q_lock(struct futex_q *q, struct futex_hash_bucket *hb)
{
	/*
	 * Increment the counter before taking the lock so that
	 * a potential waker won't miss a to-be-slept task that is
	 * waiting for the spinlock. This is safe as all futex_q_lock()
	 * users end up calling futex_queue(). Similarly, for housekeeping,
	 * decrement the counter at futex_q_unlock() when some error has
	 * occurred and we don't end up adding the task to the list.
	 */
	futex_hb_waiters_inc(hb); /* implies smp_mb(); (A) */

	q->lock_ptr = &hb->lock;

	spin_lock(&hb->lock);
	__acquire(q->lock_ptr);
}

void futex_q_unlock(struct futex_hash_bucket *hb)
{
	futex_hb_waiters_dec(hb);
	spin_unlock(&hb->lock);
}

void __futex_queue(struct futex_q *q, struct futex_hash_bucket *hb,
		   struct task_struct *task)
{
	int prio;

	/*
	 * The priority used to register this element is
	 * - either the real thread-priority for the real-time threads
	 * (i.e. threads with a priority lower than MAX_RT_PRIO)
	 * - or MAX_RT_PRIO for non-RT threads.
	 * Thus, all RT-threads are woken first in priority order, and
	 * the others are woken last, in FIFO order.
	 */
	prio = min(current->normal_prio, MAX_RT_PRIO);

	plist_node_init(&q->list, prio);
	plist_add(&q->list, &hb->chain);
	q->task = task;
}

/**
 * futex_unqueue() - Remove the futex_q from its futex_hash_bucket
 * @q:	The futex_q to unqueue
 *
 * The q->lock_ptr must not be held by the caller. A call to futex_unqueue() must
 * be paired with exactly one earlier call to futex_queue().
 *
 * Return:
 *  - 1 - if the futex_q was still queued (and we removed unqueued it);
 *  - 0 - if the futex_q was already removed by the waking thread
 */
int futex_unqueue(struct futex_q *q)
{
	spinlock_t *lock_ptr;
	int ret = 0;

	/* RCU so lock_ptr is not going away during locking. */
	guard(rcu)();
	/* In the common case we don't take the spinlock, which is nice. */
retry:
	/*
	 * q->lock_ptr can change between this read and the following spin_lock.
	 * Use READ_ONCE to forbid the compiler from reloading q->lock_ptr and
	 * optimizing lock_ptr out of the logic below.
	 */
	lock_ptr = READ_ONCE(q->lock_ptr);
	if (lock_ptr != NULL) {
		spin_lock(lock_ptr);
		/*
		 * q->lock_ptr can change between reading it and
		 * spin_lock(), causing us to take the wrong lock.  This
		 * corrects the race condition.
		 *
		 * Reasoning goes like this: if we have the wrong lock,
		 * q->lock_ptr must have changed (maybe several times)
		 * between reading it and the spin_lock().  It can
		 * change again after the spin_lock() but only if it was
		 * already changed before the spin_lock().  It cannot,
		 * however, change back to the original value.  Therefore
		 * we can detect whether we acquired the correct lock.
		 */
		if (unlikely(lock_ptr != q->lock_ptr)) {
			spin_unlock(lock_ptr);
			goto retry;
		}
		__futex_unqueue(q);

		BUG_ON(q->pi_state);

		spin_unlock(lock_ptr);
		ret = 1;
	}

	return ret;
}

void futex_q_lockptr_lock(struct futex_q *q)
{
	spinlock_t *lock_ptr;

	/*
	 * See futex_unqueue() why lock_ptr can change.
	 */
	guard(rcu)();
retry:
	lock_ptr = READ_ONCE(q->lock_ptr);
	spin_lock(lock_ptr);

	if (unlikely(lock_ptr != q->lock_ptr)) {
		spin_unlock(lock_ptr);
		goto retry;
	}
}

/*
 * PI futexes can not be requeued and must remove themselves from the hash
 * bucket. The hash bucket lock (i.e. lock_ptr) is held.
 */
void futex_unqueue_pi(struct futex_q *q)
{
	/*
	 * If the lock was not acquired (due to timeout or signal) then the
	 * rt_waiter is removed before futex_q is. If this is observed by
	 * an unlocker after dropping the rtmutex wait lock and before
	 * acquiring the hash bucket lock, then the unlocker dequeues the
	 * futex_q from the hash bucket list to guarantee consistent state
	 * vs. userspace. Therefore the dequeue here must be conditional.
	 */
	if (!plist_node_empty(&q->list))
		__futex_unqueue(q);

	BUG_ON(!q->pi_state);
	put_pi_state(q->pi_state);
	q->pi_state = NULL;
}

/* Constants for the pending_op argument of handle_futex_death */
#define HANDLE_DEATH_PENDING	true
#define HANDLE_DEATH_LIST	false

/*
 * Process a futex-list entry, check whether it's owned by the
 * dying task, and do notification if so:
 */
static int handle_futex_death(u32 __user *uaddr, struct task_struct *curr,
			      unsigned int mod, bool pending_op)
{
	bool pi = !!(mod & FUTEX_ROBUST_MOD_PI);
	u32 uval, nval, mval;
	pid_t owner;
	int err;

	/* Futex address must be 32bit aligned */
	if ((((unsigned long)uaddr) % sizeof(*uaddr)) != 0)
		return -1;

retry:
	if (get_user(uval, uaddr))
		return -1;

	/*
	 * Special case for regular (non PI) futexes. Ordinarily, we do
	 * not perform any processing here unless the current thread was
	 * the owner of the futex (by the TID check below).
	 *
	 * However, the unlock path has three race scenarios:
	 *
	 * 1. The unlock path releases the user space futex value and
	 *    before it can execute the futex() syscall to wake up
	 *    waiters it is killed.
	 *
	 * 2. A woken up waiter is killed before it can acquire the
	 *    futex in user space.
	 *
	 * 3. A woken up waiter is killed in user space after another
	 *    thread has acquired the futex, but before it can set
	 *    FUTEX_WAITERS.
	 *
	 * Note that, if userspace uses the FUTEX_ROBUST_UNLOCK flag, we
	 * will not see case 1 here.
	 *
	 * In the second and third case, the wake up notification could
	 * be generated from any of:
	 *
	 *    i.   An ordinary futex wakeup after unlock (with or
	 *         without FUTEX_ROBUST_UNLOCK)
	 *    ii.  A robust wakeup from another thread's death
	 *    iii. A previous round through this special case
	 *
	 * As a result, the futex world will be in one of four states:
	 *
	 *    A. The futex word is 0 (unlocked)
	 *    B. The futex word is owned by another thread
	 *       (FUTEX_WAITERS is not set)
	 *    C. The futex word is owned by another thread
	 *       (FUTEX_WAITERS set)
	 *    D. The futex's owner died and OWNER_DIED is set
	 *       (the owner part of the word is 0)
	 *
	 * The key issue is that the kernel usually (at least from
	 * sources ii. and iii. or when so requested by userspace from
	 * source i.) only ever wakes *one* waiter at a time. If this
	 * waiter dies before acquiring the futex (or setting the
	 * FUTEX_WAITERS bit), the kernel *must* still wake the next
	 * waiter down the line to uphold the futex invariants and
	 * avoid lost wakeups. Note we do not need to handle state C,
	 * as it does not matter to us whether *we* successfully set
	 * the bit or a third thread did so in the meantime.
	 *
	 * Therefore, in these cases we must issue an additional
	 * futex_wake(). Note however that we *must not* set OWNER_DIED
	 * here. Our thread is *not* the owner of the futex.
	 *
	 * Thus to summarize, the conditions for needing the additional
	 * futex_wake() are:
	 *
	 *	1) @pending_op == true (the thread has not finished the
	 *	   mutex operation)
	 *	2) The futex word is in one of the states A, B or D
	 *	3) Regular futex: @pi == false
	 *
	 * Note in particular that in all of the states A-D the owner
	 * portion of the futex word differs from our thread's TID
	 * (unless the actual owner has the same TID in another PID
	 * namespace, but we cannot currently distinguish that
	 * scenario), so this can be a special-case wakeup in the bail
	 * path of the ordinary TID check.
	 */
	owner = uval & FUTEX_TID_MASK;

	if (owner != task_pid_vnr(curr)) {
		if (pending_op && !pi && (!owner || !(uval & FUTEX_WAITERS))) {
			futex_wake(uaddr, FLAGS_SIZE_32 | FLAGS_SHARED, NULL, 1,
				   FUTEX_BITSET_MATCH_ANY);
		}
		return 0;
	}

	/*
	 * Ok, this dying thread is truly holding a futex
	 * of interest. Set the OWNER_DIED bit atomically
	 * via cmpxchg, and if the value had FUTEX_WAITERS
	 * set, wake up a waiter (if any). (We have to do a
	 * futex_wake() even if OWNER_DIED is already set -
	 * to handle the rare but possible case of recursive
	 * thread-death.) The rest of the cleanup is done in
	 * userspace.
	 */
	mval = (uval & FUTEX_WAITERS) | FUTEX_OWNER_DIED;

	/*
	 * We are not holding a lock here, but we want to have
	 * the pagefault_disable/enable() protection because
	 * we want to handle the fault gracefully. If the
	 * access fails we try to fault in the futex with R/W
	 * verification via get_user_pages. get_user() above
	 * does not guarantee R/W access. If that fails we
	 * give up and leave the futex locked.
	 */
	if ((err = futex_cmpxchg_value_locked(&nval, uaddr, uval, mval))) {
		switch (err) {
		case -EFAULT:
			if (fault_in_user_writeable(uaddr))
				return -1;
			goto retry;

		case -EAGAIN:
			cond_resched();
			goto retry;

		default:
			WARN_ON_ONCE(1);
			return err;
		}
	}

	if (nval != uval)
		goto retry;

	/*
	 * Wake robust non-PI futexes here. The wakeup of
	 * PI futexes happens in exit_pi_state():
	 */
	if (!pi && (uval & FUTEX_WAITERS)) {
		futex_wake(uaddr, FLAGS_SIZE_32 | FLAGS_SHARED, NULL, 1,
			   FUTEX_BITSET_MATCH_ANY);
	}

	return 0;
}

/*
 * Fetch a robust-list pointer. Bit 0 signals PI futexes:
 */
static inline int fetch_robust_entry(struct robust_list __user **entry,
				     struct robust_list __user * __user *head,
				     unsigned int *mod)
{
	unsigned long uentry;

	if (get_user(uentry, (unsigned long __user *)head))
		return -EFAULT;

	*entry = (void __user *)(uentry & ~FUTEX_ROBUST_MOD_MASK);
	*mod = uentry & FUTEX_ROBUST_MOD_MASK;

	return 0;
}

/*
 * Walk curr->futex.robust_list (very carefully, it's a userspace list!)
 * and mark any locks found there dead, and notify any waiters.
 *
 * We silently return on any sign of list-walking problem.
 */
static void exit_robust_list(struct task_struct *curr)
{
	struct robust_list_head __user *head = curr->futex.robust_list;
	unsigned int limit = ROBUST_LIST_LIMIT, cur_mod, next_mod, pend_mod;
	struct robust_list __user *entry, *next_entry, *pending;
	unsigned long futex_offset;
	int rc;

	/*
	 * Fetch the list head (which was registered earlier, via
	 * sys_set_robust_list()):
	 */
	if (fetch_robust_entry(&entry, &head->list.next, &cur_mod))
		return;
	/*
	 * Fetch the relative futex offset:
	 */
	if (get_user(futex_offset, &head->futex_offset))
		return;
	/*
	 * Fetch any possibly pending lock-add first, and handle it
	 * if it exists:
	 */
	if (fetch_robust_entry(&pending, &head->list_op_pending, &pend_mod))
		return;

	next_entry = NULL;	/* avoid warning with gcc */
	while (entry != &head->list) {
		/*
		 * Fetch the next entry in the list before calling
		 * handle_futex_death:
		 */
		rc = fetch_robust_entry(&next_entry, &entry->next, &next_mod);
		/*
		 * A pending lock might already be on the list, so
		 * don't process it twice:
		 */
		if (entry != pending) {
			if (handle_futex_death((void __user *)entry + futex_offset,
						curr, cur_mod, HANDLE_DEATH_LIST))
				return;
		}
		if (rc)
			return;
		entry = next_entry;
		cur_mod = next_mod;
		/*
		 * Avoid excessively long or circular lists:
		 */
		if (!--limit)
			break;

		cond_resched();
	}

	if (pending) {
		handle_futex_death((void __user *)pending + futex_offset,
				   curr, pend_mod, HANDLE_DEATH_PENDING);
	}
}

static bool robust_list_clear_pending(unsigned long __user *pop)
{
	struct robust_list_head __user *head = current->futex.robust_list;

	if (!put_user(0UL, pop))
		return true;

	/*
	 * Just give up. The robust list head is usually part of TLS, so the
	 * chance that this gets resolved is close to zero.
	 *
	 * If @pop_addr is the robust_list_head::list_op_pending pointer then
	 * clear the robust list head pointer to prevent further damage when the
	 * task exits.  Better a few stale futexes than corrupted memory. But
	 * that's mostly an academic exercise.
	 */
	if (pop == (unsigned long __user *)&head->list_op_pending)
		current->futex.robust_list = NULL;
	return false;
}

#ifdef CONFIG_COMPAT
static void __user *futex_uaddr(struct robust_list __user *entry,
				compat_long_t futex_offset)
{
	compat_uptr_t base = ptr_to_compat(entry);
	void __user *uaddr = compat_ptr(base + futex_offset);

	return uaddr;
}

/*
 * Fetch a robust-list pointer. Bit 0 signals PI futexes:
 */
static inline int
compat_fetch_robust_entry(compat_uptr_t *uentry, struct robust_list __user **entry,
		   compat_uptr_t __user *head, unsigned int *pflags)
{
	if (get_user(*uentry, head))
		return -EFAULT;

	*entry = compat_ptr((*uentry) & ~FUTEX_ROBUST_MOD_MASK);
	*pflags = (unsigned int)(*uentry) & FUTEX_ROBUST_MOD_MASK;

	return 0;
}

/*
 * Walk curr->futex.robust_list (very carefully, it's a userspace list!)
 * and mark any locks found there dead, and notify any waiters.
 *
 * We silently return on any sign of list-walking problem.
 */
static void compat_exit_robust_list(struct task_struct *curr)
{
	struct compat_robust_list_head __user *head = current->futex.compat_robust_list;
	unsigned int limit = ROBUST_LIST_LIMIT, cur_mod, next_mod, pend_mod;
	struct robust_list __user *entry, *next_entry, *pending;
	compat_uptr_t uentry, next_uentry, upending;
	compat_long_t futex_offset;
	int rc;

	/*
	 * Fetch the list head (which was registered earlier, via
	 * sys_set_robust_list()):
	 */
	if (compat_fetch_robust_entry(&uentry, &entry, &head->list.next, &cur_mod))
		return;
	/*
	 * Fetch the relative futex offset:
	 */
	if (get_user(futex_offset, &head->futex_offset))
		return;
	/*
	 * Fetch any possibly pending lock-add first, and handle it
	 * if it exists:
	 */
	if (compat_fetch_robust_entry(&upending, &pending, &head->list_op_pending, &pend_mod))
		return;

	next_entry = NULL;	/* avoid warning with gcc */
	while (entry != (struct robust_list __user *) &head->list) {
		/*
		 * Fetch the next entry in the list before calling
		 * handle_futex_death:
		 */
		rc = compat_fetch_robust_entry(&next_uentry, &next_entry,
			(compat_uptr_t __user *)&entry->next, &next_mod);
		/*
		 * A pending lock might already be on the list, so
		 * dont process it twice:
		 */
		if (entry != pending) {
			void __user *uaddr = futex_uaddr(entry, futex_offset);

			if (handle_futex_death(uaddr, curr, cur_mod, HANDLE_DEATH_LIST))
				return;
		}
		if (rc)
			return;
		uentry = next_uentry;
		entry = next_entry;
		cur_mod = next_mod;
		/*
		 * Avoid excessively long or circular lists:
		 */
		if (!--limit)
			break;

		cond_resched();
	}
	if (pending) {
		void __user *uaddr = futex_uaddr(pending, futex_offset);

		handle_futex_death(uaddr, curr, pend_mod, HANDLE_DEATH_PENDING);
	}
}

static bool compat_robust_list_clear_pending(u32 __user *pop)
{
	struct compat_robust_list_head __user *head = current->futex.compat_robust_list;

	if (!put_user(0U, pop))
		return true;

	/* See comment in robust_list_clear_pending(). */
	if (pop == &head->list_op_pending)
		current->futex.compat_robust_list = NULL;
	return false;
}
#else
static bool compat_robust_list_clear_pending(u32 __user *pop_addr) { return false; }
#endif

#ifdef CONFIG_FUTEX_PI

/*
 * This task is holding PI mutexes at exit time => bad.
 * Kernel cleans up PI-state, but userspace is likely hosed.
 * (Robust-futex cleanup is separate and might save the day for userspace.)
 */
static void exit_pi_state_list(struct task_struct *curr)
{
	struct list_head *next, *head = &curr->futex.pi_state_list;
	struct futex_pi_state *pi_state;
	union futex_key key = FUTEX_KEY_INIT;

	/*
	 * The mutex mm_struct::futex_hash_lock might be acquired.
	 */
	might_sleep();
	/*
	 * Ensure the hash remains stable (no resize) during the while loop
	 * below. The hb pointer is acquired under the pi_lock so we can't block
	 * on the mutex.
	 */
	WARN_ON(curr != current);
	guard(private_hash)(current->mm);
	/*
	 * We are a ZOMBIE and nobody can enqueue itself on
	 * pi_state_list anymore, but we have to be careful
	 * versus waiters unqueueing themselves:
	 */
	raw_spin_lock_irq(&curr->pi_lock);
	while (!list_empty(head)) {
		next = head->next;
		pi_state = list_entry(next, struct futex_pi_state, list);
		key = pi_state->key;
		if (1) {
			CLASS(hbr, hbr)(&key);
			auto hb = hbr.hb;

			/*
			 * We can race against put_pi_state() removing itself from the
			 * list (a waiter going away). put_pi_state() will first
			 * decrement the reference count and then modify the list, so
			 * its possible to see the list entry but fail this reference
			 * acquire.
			 *
			 * In that case; drop the locks to let put_pi_state() make
			 * progress and retry the loop.
			 */
			if (!refcount_inc_not_zero(&pi_state->refcount)) {
				raw_spin_unlock_irq(&curr->pi_lock);
				cpu_relax();
				raw_spin_lock_irq(&curr->pi_lock);
				continue;
			}
			raw_spin_unlock_irq(&curr->pi_lock);

			spin_lock(&hb->lock);
			raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock);
			raw_spin_lock(&curr->pi_lock);
			/*
			 * We dropped the pi-lock, so re-check whether this
			 * task still owns the PI-state:
			 */
			if (head->next != next) {
				/* retain curr->pi_lock for the loop invariant */
				raw_spin_unlock(&pi_state->pi_mutex.wait_lock);
				spin_unlock(&hb->lock);
				put_pi_state(pi_state);
				continue;
			}

			WARN_ON(pi_state->owner != curr);
			WARN_ON(list_empty(&pi_state->list));
			list_del_init(&pi_state->list);
			pi_state->owner = NULL;

			raw_spin_unlock(&curr->pi_lock);
			raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock);
			spin_unlock(&hb->lock);
		}

		rt_mutex_futex_unlock(&pi_state->pi_mutex);
		put_pi_state(pi_state);

		raw_spin_lock_irq(&curr->pi_lock);
	}
	raw_spin_unlock_irq(&curr->pi_lock);
}
#else
static inline void exit_pi_state_list(struct task_struct *curr) { }
#endif

bool futex_robust_list_clear_pending(void __user *pop, unsigned int flags)
{
	bool size32bit = !!(flags & FLAGS_ROBUST_LIST32);

	if (!IS_ENABLED(CONFIG_64BIT) && !size32bit)
		return false;

	if (IS_ENABLED(CONFIG_64BIT) && size32bit)
		return compat_robust_list_clear_pending(pop);

	return robust_list_clear_pending(pop);
}

#ifdef CONFIG_FUTEX_ROBUST_UNLOCK
void __futex_fixup_robust_unlock(struct pt_regs *regs, struct futex_unlock_cs_range *csr)
{
	/*
	 * arch_futex_robust_unlock_get_pop() returns the list pending op pointer from
	 * @regs if the try_cmpxchg() succeeded.
	 */
	void __user *pop = arch_futex_robust_unlock_get_pop(regs);

	if (!pop)
		return;

	futex_robust_list_clear_pending(pop, csr->pop_size32 ? FLAGS_ROBUST_LIST32 : 0);
}
#endif /* CONFIG_FUTEX_ROBUST_UNLOCK */

static void futex_cleanup(struct task_struct *tsk)
{
	if (unlikely(tsk->futex.robust_list)) {
		exit_robust_list(tsk);
		tsk->futex.robust_list = NULL;
	}

#ifdef CONFIG_COMPAT
	if (unlikely(tsk->futex.compat_robust_list)) {
		compat_exit_robust_list(tsk);
		tsk->futex.compat_robust_list = NULL;
	}
#endif

	if (unlikely(!list_empty(&tsk->futex.pi_state_list)))
		exit_pi_state_list(tsk);
}

/**
 * futex_exit_recursive - Set the tasks futex state to FUTEX_STATE_DEAD
 * @tsk:	task to set the state on
 *
 * Set the futex exit state of the task lockless. The futex waiter code
 * observes that state when a task is exiting and loops until the task has
 * actually finished the futex cleanup. The worst case for this is that the
 * waiter runs through the wait loop until the state becomes visible.
 *
 * This is called from the recursive fault handling path in make_task_dead().
 *
 * This is best effort. Either the futex exit code has run already or
 * not. If the OWNER_DIED bit has been set on the futex then the waiter can
 * take it over. If not, the problem is pushed back to user space. If the
 * futex exit code did not run yet, then an already queued waiter might
 * block forever, but there is nothing which can be done about that.
 */
void futex_exit_recursive(struct task_struct *tsk)
{
	/* If the state is FUTEX_STATE_EXITING then futex_exit_mutex is held */
	if (tsk->futex.state == FUTEX_STATE_EXITING) {
		__assume_ctx_lock(&tsk->futex.exit_mutex);
		mutex_unlock(&tsk->futex.exit_mutex);
	}
	tsk->futex.state = FUTEX_STATE_DEAD;
}

static void futex_cleanup_begin(struct task_struct *tsk)
	__acquires(&tsk->futex.exit_mutex)
{
	/*
	 * Prevent various race issues against a concurrent incoming waiter
	 * including live locks by forcing the waiter to block on
	 * tsk->futex.exit_mutex when it observes FUTEX_STATE_EXITING in
	 * attach_to_pi_owner().
	 */
	mutex_lock(&tsk->futex.exit_mutex);

	/*
	 * Switch the state to FUTEX_STATE_EXITING under tsk->pi_lock.
	 *
	 * This ensures that all subsequent checks of tsk->futex_state in
	 * attach_to_pi_owner() must observe FUTEX_STATE_EXITING with
	 * tsk->pi_lock held.
	 *
	 * It guarantees also that a pi_state which was queued right before
	 * the state change under tsk->pi_lock by a concurrent waiter must
	 * be observed in exit_pi_state_list().
	 */
	raw_spin_lock_irq(&tsk->pi_lock);
	tsk->futex.state = FUTEX_STATE_EXITING;
	raw_spin_unlock_irq(&tsk->pi_lock);
}

static void futex_cleanup_end(struct task_struct *tsk)
	__releases(&tsk->futex.exit_mutex)
{
	scoped_guard(raw_spinlock_irq, &tsk->pi_lock)
		tsk->futex.state = FUTEX_STATE_DEAD;

	/*
	 * Drop the exit protection. This unblocks waiters which observed
	 * FUTEX_STATE_EXITING to reevaluate the state.
	 */
	mutex_unlock(&tsk->futex.exit_mutex);
}

/*
 * Invoked from mm_exit_exec_release() to cleanup the robust lists and pi state
 * of the outgoing task.
 *
 * exec() makes it interesting for futexes because the TID of the task stays the
 * same, but from a futex perspective the task has to be treated like an exiting
 * task. This is especially important for the sanity check for private futexes
 * in attach_to_pi_owner() which compares the owner's mm with the waiter's mm.
 *
 * That check would give the wrong answer if futex_cleanup_end() would
 * set the state to FUTEX_STATE_OK as long as the task still has the old
 * mm.
 *
 * After the task has switched to the new mm it sets it to
 * FUTEX_STATE_OK again in futex_exec_done().
 */
void futex_exit_exec_release(struct task_struct *tsk)
{
	futex_cleanup_begin(tsk);
	futex_cleanup(tsk);
	futex_cleanup_end(tsk);
}

/*
 * exec() has switched to the new mm. Futex operations are safe again.
 */
void futex_exec_done(struct task_struct *tsk)
{
	/*
	 * This store does not have to take tsk::futex::exit_mutex because the
	 * phase where waiters block on it during state FUTEX_STATE_EXITING has
	 * been finished when futex_cleanup_end() set the state to
	 * FUTEX_STATE_DEAD.
	 *
	 * This transitions back from FUTEX_STATE_DEAD to FUTEX_STATE_OK. The
	 * ordering guarantee required here is that the previous store to
	 * tsk::mm in the calling code cannot be reordered against this store.
	 */
	guard(raw_spinlock_irq)(&tsk->pi_lock);
	tsk->futex.state = FUTEX_STATE_OK;
}

static void futex_hash_bucket_init(struct futex_hash_bucket *fhb)
{
	atomic_set(&fhb->waiters, 0);
	plist_head_init(&fhb->chain);
	spin_lock_init(&fhb->lock);
}

#define FH_CUSTOM	0x01

#ifdef CONFIG_FUTEX_PRIVATE_HASH

/*
 * futex-ref
 *
 * Heavily inspired by percpu-rwsem/percpu-refcount; not reusing any of that
 * code because it just doesn't fit right.
 *
 * Dual counter, per-cpu / atomic approach like percpu-refcount, except it
 * re-initializes the state automatically, such that the fph swizzle is also a
 * transition back to per-cpu.
 */

static void futex_ref_rcu(struct rcu_head *head);

static void __futex_ref_atomic_begin(struct futex_private_hash *fph)
{
	struct mm_struct *mm = fph->mm;

	/*
	 * The counter we're about to switch to must have fully switched;
	 * otherwise it would be impossible for it to have reported success
	 * from futex_ref_is_dead().
	 */
	WARN_ON_ONCE(atomic_long_read(&mm->futex.phash.atomic) != 0);

	/*
	 * Set the atomic to the bias value such that futex_ref_{get,put}()
	 * will never observe 0. Will be fixed up in __futex_ref_atomic_end()
	 * when folding in the percpu count.
	 */
	atomic_long_set(&mm->futex.phash.atomic, LONG_MAX);
	smp_store_release(&fph->state, FR_ATOMIC);

	call_rcu_hurry(&mm->futex.phash.rcu, futex_ref_rcu);
}

static void __futex_ref_atomic_end(struct futex_private_hash *fph)
{
	struct mm_struct *mm = fph->mm;
	unsigned int count = 0;
	long ret;
	int cpu;

	/*
	 * Per __futex_ref_atomic_begin() the state of the fph must be ATOMIC
	 * and per this RCU callback, everybody must now observe this state and
	 * use the atomic variable.
	 */
	WARN_ON_ONCE(fph->state != FR_ATOMIC);

	/*
	 * Therefore the per-cpu counter is now stable, sum and reset.
	 */
	for_each_possible_cpu(cpu) {
		unsigned int *ptr = per_cpu_ptr(mm->futex.phash.ref, cpu);
		count += *ptr;
		*ptr = 0;
	}

	/*
	 * Re-init for the next cycle.
	 */
	this_cpu_inc(*mm->futex.phash.ref); /* 0 -> 1 */

	/*
	 * Add actual count, subtract bias and initial refcount.
	 *
	 * The moment this atomic operation happens, futex_ref_is_dead() can
	 * become true.
	 */
	ret = atomic_long_add_return(count - LONG_MAX - 1, &mm->futex.phash.atomic);
	if (!ret)
		wake_up_var(mm);

	WARN_ON_ONCE(ret < 0);
	mmput_async(mm);
}

static void futex_ref_rcu(struct rcu_head *head)
{
	struct mm_struct *mm = container_of(head, struct mm_struct, futex.phash.rcu);
	struct futex_private_hash *fph = rcu_dereference_raw(mm->futex.phash.hash);

	if (fph->state == FR_PERCPU) {
		/*
		 * Per this extra grace-period, everybody must now observe
		 * fph as the current fph and no previously observed fph's
		 * are in-flight.
		 *
		 * Notably, nobody will now rely on the atomic
		 * futex_ref_is_dead() state anymore so we can begin the
		 * migration of the per-cpu counter into the atomic.
		 */
		__futex_ref_atomic_begin(fph);
		return;
	}

	__futex_ref_atomic_end(fph);
}

/*
 * Drop the initial refcount and transition to atomics.
 */
static void futex_ref_drop(struct futex_private_hash *fph)
{
	struct mm_struct *mm = fph->mm;

	/*
	 * Can only transition the current fph;
	 */
	WARN_ON_ONCE(rcu_dereference_raw(mm->futex.phash.hash) != fph);
	/*
	 * We enqueue at least one RCU callback. Ensure mm stays if the task
	 * exits before the transition is completed.
	 */
	mmget(mm);

	/*
	 * In order to avoid the following scenario:
	 *
	 * futex_hash()			__futex_pivot_hash()
	 *   guard(rcu);		  guard(mm->futex.phash.lock);
	 *   fph = mm->futex.phash.hash;
	 *				  rcu_assign_pointer(&mm->futex.phash.hash, new);
	 *				futex_hash_allocate()
	 *				  futex_ref_drop()
	 *				    fph->state = FR_ATOMIC;
	 *				    atomic_set(, BIAS);
	 *
	 *   futex_private_hash_get(fph); // OOPS
	 *
	 * Where an old fph (which is FR_ATOMIC) and should fail on
	 * inc_not_zero, will succeed because a new transition is started and
	 * the atomic is bias'ed away from 0.
	 *
	 * There must be at least one full grace-period between publishing a
	 * new fph and trying to replace it.
	 */
	if (poll_state_synchronize_rcu(mm->futex.phash.batches)) {
		/*
		 * There was a grace-period, we can begin now.
		 */
		__futex_ref_atomic_begin(fph);
		return;
	}

	call_rcu_hurry(&mm->futex.phash.rcu, futex_ref_rcu);
}

static bool futex_ref_get(struct futex_private_hash *fph)
{
	struct mm_struct *mm = fph->mm;

	guard(preempt)();

	if (READ_ONCE(fph->state) == FR_PERCPU) {
		__this_cpu_inc(*mm->futex.phash.ref);
		return true;
	}

	return atomic_long_inc_not_zero(&mm->futex.phash.atomic);
}

static bool futex_ref_put(struct futex_private_hash *fph)
{
	struct mm_struct *mm = fph->mm;

	guard(preempt)();

	if (READ_ONCE(fph->state) == FR_PERCPU) {
		__this_cpu_dec(*mm->futex.phash.ref);
		return false;
	}

	return atomic_long_dec_and_test(&mm->futex.phash.atomic);
}

static bool futex_ref_is_dead(struct futex_private_hash *fph)
{
	struct mm_struct *mm = fph->mm;

	guard(rcu)();

	if (smp_load_acquire(&fph->state) == FR_PERCPU)
		return false;

	return atomic_long_read(&mm->futex.phash.atomic) == 0;
}

static void futex_hash_init_mm(struct futex_mm_data *fd)
{
	memset(&fd->phash, 0, sizeof(fd->phash));
	mutex_init(&fd->phash.lock);
	fd->phash.batches = get_state_synchronize_rcu();
}

void futex_hash_free(struct mm_struct *mm)
{
	struct futex_private_hash *fph;

	free_percpu(mm->futex.phash.ref);
	kvfree(mm->futex.phash.hash_new);
	fph = rcu_dereference_raw(mm->futex.phash.hash);
	kvfree(fph);
}

static bool futex_pivot_pending(struct mm_struct *mm)
{
	struct futex_mm_phash *mmph = &mm->futex.phash;
	struct futex_private_hash *fph;

	guard(mutex)(&mmph->lock);

	if (!mmph->hash_new)
		return true;

	fph = rcu_dereference_raw(mmph->hash);
	return futex_ref_is_dead(fph);
}

static bool futex_hash_less(struct futex_private_hash *a,
			    struct futex_private_hash *b)
{
	/* user provided always wins */
	if (!a->custom && b->custom)
		return true;
	if (a->custom && !b->custom)
		return false;

	/* zero-sized hash wins */
	if (!b->hash_mask)
		return true;
	if (!a->hash_mask)
		return false;

	/* keep the biggest */
	if (a->hash_mask < b->hash_mask)
		return true;
	if (a->hash_mask > b->hash_mask)
		return false;

	return false; /* equal */
}

static int futex_hash_allocate(unsigned int hash_slots, unsigned int flags)
{
	struct mm_struct *mm = current->mm;
	struct futex_private_hash *fph;
	bool custom = flags & FH_CUSTOM;
	int i;

	if (hash_slots && (hash_slots == 1 || !is_power_of_2(hash_slots)))
		return -EINVAL;

	/*
	 * Once we've disabled the global hash there is no way back.
	 */
	scoped_guard(rcu) {
		fph = rcu_dereference(mm->futex.phash.hash);
		if (fph && !fph->hash_mask) {
			if (custom)
				return -EBUSY;
			return 0;
		}
	}

	if (!mm->futex.phash.ref) {
		unsigned int __percpu *ref = alloc_percpu(unsigned int);

		if (!ref)
			return -ENOMEM;

		/*
		 * Tasks sharing the mm can run this concurrently, so take the
		 * initial reference before publishing the counter.
		 */
		this_cpu_inc(*ref); /* 0 -> 1 */
		if (cmpxchg(&mm->futex.phash.ref, NULL, ref))
			free_percpu(ref);
	}

	fph = kvzalloc_flex(*fph, queues, hash_slots,
			    GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
	if (!fph)
		return -ENOMEM;

	fph->hash_mask = hash_slots ? hash_slots - 1 : 0;
	fph->custom = custom;
	fph->mm = mm;

	for (i = 0; i < hash_slots; i++)
		futex_hash_bucket_init(&fph->queues[i]);

	if (custom) {
		struct wait_bit_queue_entry __wbq_entry;
		struct wait_queue_head *__wq_head;

		/*
		 * Only let prctl() wait / retry; don't unduly delay clone().
		 */
again:
		__wq_head = __var_waitqueue(mm);
		init_wait_var_entry(&__wbq_entry, mm, 0);
		__wbq_entry.wq_entry.func = woken_wake_bit_function;
		add_wait_queue(__wq_head, &__wbq_entry.wq_entry);

		/*
		 * add_wait_queue()		futex_ref_put()
		 * MB (this)			MB (implied)
		 * futex_pivot_pending()	wake_up_var()
		 *                                waitqueue_active()
		 *
		 * Notably, it must not be possible to see
		 * !futex_pivot_pending() && !waitqueue_active().
		 */
		smp_mb();

		while (!futex_pivot_pending(mm) &&
		       wait_woken(&__wbq_entry.wq_entry, TASK_UNINTERRUPTIBLE,
				  MAX_SCHEDULE_TIMEOUT))
			/* empty */;

		remove_wait_queue(__wq_head, &__wbq_entry.wq_entry);
	}

	scoped_guard(mutex, &mm->futex.phash.lock) {
		struct futex_private_hash *free __free(kvfree) = NULL;
		struct futex_private_hash *cur, *new;

		cur = rcu_dereference_protected(mm->futex.phash.hash,
						lockdep_is_held(&mm->futex.phash.lock));
		new = mm->futex.phash.hash_new;
		mm->futex.phash.hash_new = NULL;

		if (fph) {
			if (cur && !cur->hash_mask) {
				/*
				 * If two threads simultaneously request the global
				 * hash then the first one performs the switch,
				 * the second one returns here.
				 */
				free = fph;
				mm->futex.phash.hash_new = new;
				return -EBUSY;
			}
			if (cur && !new) {
				/*
				 * If we have an existing hash, but do not yet have
				 * allocated a replacement hash, drop the initial
				 * reference on the existing hash.
				 */
				futex_ref_drop(cur);
			}

			if (new) {
				/*
				 * Two updates raced; throw out the lesser one.
				 */
				if (futex_hash_less(new, fph)) {
					free = new;
					new = fph;
				} else {
					free = fph;
				}
			} else {
				new = fph;
			}
			fph = NULL;
		}

		if (new) {
			/*
			 * Will set mm->futex.phash.new_hash on failure;
			 * futex_private_hash_get() will try again.
			 */
			if (!__futex_pivot_hash(mm, new) && custom)
				goto again;
		}
	}
	return 0;
}

int futex_hash_allocate_default(void)
{
	unsigned int threads, buckets, current_buckets = 0;
	struct futex_private_hash *fph;

	if (!current->mm)
		return 0;

	scoped_guard(rcu) {
		threads = min_t(unsigned int, get_nr_threads(current), num_online_cpus());

		fph = rcu_dereference(current->mm->futex.phash.hash);
		if (fph) {
			if (fph->custom)
				return 0;

			current_buckets = fph->hash_mask + 1;
		}
	}

	/*
	 * The default allocation will remain within
	 *   16 <= threads * 4 <= global hash size
	 */
	buckets = roundup_pow_of_two(4 * threads);
	buckets = clamp(buckets, 16, __futex_mask + 1);

	if (current_buckets >= buckets)
		return 0;

	return futex_hash_allocate(buckets, 0);
}

static int futex_hash_get_slots(void)
{
	struct futex_private_hash *fph;

	guard(rcu)();
	fph = rcu_dereference(current->mm->futex.phash.hash);
	if (fph && fph->hash_mask)
		return fph->hash_mask + 1;
	return 0;
}
#else  /* CONFIG_FUTEX_PRIVATE_HASH */
static inline int futex_hash_allocate(unsigned int hslots, unsigned int flags) { return -EINVAL; }
static inline int futex_hash_get_slots(void) { return 0; }
static inline void futex_hash_init_mm(struct futex_mm_data *fd) { }
#endif /* !CONFIG_FUTEX_PRIVATE_HASH */

#ifdef CONFIG_FUTEX_ROBUST_UNLOCK
static void futex_invalidate_cs_ranges(struct futex_mm_data *fd)
{
	/*
	 * Invalidate start_ip so that the quick check fails for ip >= start_ip
	 * if VDSO is not mapped or the second slot is not available for compat
	 * tasks as they use VDSO32 which does not provide the 64-bit pointer
	 * variant.
	 */
	for (int i = 0; i < FUTEX_ROBUST_MAX_CS_RANGES; i++)
		fd->unlock.cs_ranges[i].start_ip = ~0UL;
}

void futex_reset_cs_ranges(struct futex_mm_data *fd)
{
	memset(fd->unlock.cs_ranges, 0, sizeof(fd->unlock.cs_ranges));
	futex_invalidate_cs_ranges(fd);
}

static void futex_robust_unlock_init_mm(struct futex_mm_data *fd)
{
	/* mm_dup() preserves the range, mm_alloc() clears it */
	if (!fd->unlock.cs_ranges[0].start_ip)
		futex_invalidate_cs_ranges(fd);
}
#else  /* CONFIG_FUTEX_ROBUST_UNLOCK */
static inline void futex_robust_unlock_init_mm(struct futex_mm_data *fd) { }
#endif /* !CONFIG_FUTEX_ROBUST_UNLOCK */

#if defined(CONFIG_FUTEX_PRIVATE_HASH) || defined(CONFIG_FUTEX_ROBUST_UNLOCK)
void futex_mm_init(struct mm_struct *mm)
{
	futex_hash_init_mm(&mm->futex);
	futex_robust_unlock_init_mm(&mm->futex);
}
#endif

int futex_hash_prctl(unsigned long arg2, unsigned long arg3, unsigned long arg4)
{
	unsigned int flags = FH_CUSTOM;
	int ret;

	switch (arg2) {
	case PR_FUTEX_HASH_SET_SLOTS:
		if (arg4)
			return -EINVAL;
		ret = futex_hash_allocate(arg3, flags);
		break;

	case PR_FUTEX_HASH_GET_SLOTS:
		ret = futex_hash_get_slots();
		break;

	default:
		ret = -EINVAL;
		break;
	}
	return ret;
}

static int __init futex_init(void)
{
	unsigned long hashsize, i;
	unsigned int order, n;
	unsigned long size;

#ifdef CONFIG_BASE_SMALL
	hashsize = 16;
#else
	hashsize = 256 * num_possible_cpus();
	hashsize /= num_possible_nodes();
	hashsize = max(4, hashsize);
	hashsize = roundup_pow_of_two(hashsize);
#endif
	__futex_mask = hashsize - 1;
	__futex_shift = ilog2(hashsize);
	size = sizeof(struct futex_hash_bucket) * hashsize;
	order = get_order(size);

	__futex_queues = kzalloc_objs(*__futex_queues, nr_node_ids);
	kmemleak_not_leak(__futex_queues);

	runtime_const_init(shift, __futex_shift);
	runtime_const_init(mask,  __futex_mask);
	runtime_const_init(ptr,   __futex_queues);

	barrier();

	BUG_ON(!futex_queues());

	for_each_node(n) {
		struct futex_hash_bucket *table;

		if (order > MAX_PAGE_ORDER)
			table = vmalloc_huge_node(size, GFP_KERNEL, n);
		else
			table = alloc_pages_exact_nid(n, size, GFP_KERNEL);

		BUG_ON(!table);

		for (i = 0; i < hashsize; i++)
			futex_hash_bucket_init(&table[i]);

		futex_queues()[n] = table;
	}

	pr_info("futex hash table entries: %lu (%lu bytes on %d NUMA nodes, total %lu KiB, %s).\n",
		hashsize, size, num_possible_nodes(), size * num_possible_nodes() / 1024,
		order > MAX_PAGE_ORDER ? "vmalloc" : "linear");
	return 0;
}
core_initcall(futex_init);
