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

Merge tag 'locking_urgent_for_v6.16_rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull locking fixes from Borislav Petkov:

 - Make sure the switch to the global hash is requested always under a
   lock so that two threads requesting that simultaneously cannot get to
   inconsistent state

 - Reject negative NUMA nodes earlier in the futex NUMA interface
   handling code

 - Selftests fixes

* tag 'locking_urgent_for_v6.16_rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  futex: Verify under the lock if hash can be replaced
  futex: Handle invalid node numbers supplied by user
  selftests/futex: Set the home_node in futex_numa_mpol
  selftests/futex: getopt() requires int as return value.
parents 73543bad 69a14d14
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -583,8 +583,8 @@ int get_futex_key(u32 __user *uaddr, unsigned int flags, union futex_key *key,
		if (futex_get_value(&node, naddr))
			return -EFAULT;

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

@@ -1629,6 +1629,16 @@ static int futex_hash_allocate(unsigned int hash_slots, unsigned int flags)
		mm->futex_phash_new = NULL;

		if (fph) {
			if (cur && (!cur->hash_mask || cur->immutable)) {
				/*
				 * 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_new = new;
				return -EBUSY;
			}
			if (cur && !new) {
				/*
				 * If we have an existing hash, but do not yet have
+7 −3
Original line number Diff line number Diff line
@@ -144,7 +144,7 @@ int main(int argc, char *argv[])
	struct futex32_numa *futex_numa;
	int mem_size, i;
	void *futex_ptr;
	char c;
	int c;

	while ((c = getopt(argc, argv, "chv:")) != -1) {
		switch (c) {
@@ -210,6 +210,10 @@ int main(int argc, char *argv[])
		ret = mbind(futex_ptr, mem_size, MPOL_BIND, &nodemask,
			    sizeof(nodemask) * 8, 0);
		if (ret == 0) {
			ret = numa_set_mempolicy_home_node(futex_ptr, mem_size, i, 0);
			if (ret != 0)
				ksft_exit_fail_msg("Failed to set home node: %m, %d\n", errno);

			ksft_print_msg("Node %d test\n", i);
			futex_numa->futex = 0;
			futex_numa->numa = FUTEX_NO_NODE;
@@ -220,7 +224,7 @@ int main(int argc, char *argv[])
			if (0)
				test_futex_mpol(futex_numa, 0);
			if (futex_numa->numa != i) {
				ksft_test_result_fail("Returned NUMA node is %d expected %d\n",
				ksft_exit_fail_msg("Returned NUMA node is %d expected %d\n",
						   futex_numa->numa, i);
			}
		}
+1 −1
Original line number Diff line number Diff line
@@ -130,7 +130,7 @@ int main(int argc, char *argv[])
	pthread_mutexattr_t mutex_attr_pi;
	int use_global_hash = 0;
	int ret;
	char c;
	int c;

	while ((c = getopt(argc, argv, "cghv:")) != -1) {
		switch (c) {