[tip:locking/urgent 1/1] kernel/futex/core.c:1870:21: sparse: sparse: cast removes address space '__percpu' of expression

kernel test robot <[email protected]>
Newsgroups dev.linux.lists.oe-kbuild-all,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
tree:   https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git locking/urgent
head:   4f664e37fe72ab21426d2d74fcbcf7399e8fc52c
commit: 4f664e37fe72ab21426d2d74fcbcf7399e8fc52c [1/1] futex: Fix race on the initial mm->futex.phash.ref allocation
config: riscv-randconfig-r134-20260816 (https://download.01.org/0day-ci/archive/20260816/[email protected]/config)
compiler: clang version 24.0.0git (https://github.com/llvm/llvm-project 844a18e753e822736c9805ab779144b647a2c186)
sparse: v0.6.5-rc1
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260816/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

sparse warnings: (new ones prefixed by >>)
   WARNING: invalid argument to '-march': '_zacas_zabha'
   kernel/futex/core.c:536:38: sparse: sparse: cast removes address space '__user' of expression
   kernel/futex/core.c:536:51: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected unsigned int [noderef] [usertype] __user *naddr @@     got void * @@
   kernel/futex/core.c:536:51: sparse:     expected unsigned int [noderef] [usertype] __user *naddr
   kernel/futex/core.c:536:51: sparse:     got void *
   kernel/futex/core.c:552:38: sparse: sparse: cast removes address space '__user' of expression
   kernel/futex/core.c:552:51: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected unsigned int [noderef] [usertype] __user *naddr @@     got void * @@
   kernel/futex/core.c:552:51: sparse:     expected unsigned int [noderef] [usertype] __user *naddr
   kernel/futex/core.c:552:51: sparse:     got void *
>> kernel/futex/core.c:1870:21: sparse: sparse: cast removes address space '__percpu' of expression

vim +/__percpu +1870 kernel/futex/core.c

  1836	
  1837	static int futex_hash_allocate(unsigned int hash_slots, unsigned int flags)
  1838	{
  1839		struct mm_struct *mm = current->mm;
  1840		struct futex_private_hash *fph;
  1841		bool custom = flags & FH_CUSTOM;
  1842		int i;
  1843	
  1844		if (hash_slots && (hash_slots == 1 || !is_power_of_2(hash_slots)))
  1845			return -EINVAL;
  1846	
  1847		/*
  1848		 * Once we've disabled the global hash there is no way back.
  1849		 */
  1850		scoped_guard(rcu) {
  1851			fph = rcu_dereference(mm->futex.phash.hash);
  1852			if (fph && !fph->hash_mask) {
  1853				if (custom)
  1854					return -EBUSY;
  1855				return 0;
  1856			}
  1857		}
  1858	
  1859		if (!mm->futex.phash.ref) {
  1860			unsigned int __percpu *ref = alloc_percpu(unsigned int);
  1861	
  1862			if (!ref)
  1863				return -ENOMEM;
  1864	
  1865			/*
  1866			 * Tasks sharing the mm can run this concurrently, so take the
  1867			 * initial reference before publishing the counter.
  1868			 */
  1869			this_cpu_inc(*ref); /* 0 -> 1 */
> 1870			if (cmpxchg(&mm->futex.phash.ref, NULL, ref))
  1871				free_percpu(ref);
  1872		}
  1873	
  1874		fph = kvzalloc(struct_size(fph, queues, hash_slots),
  1875			       GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
  1876		if (!fph)
  1877			return -ENOMEM;
  1878	
  1879		fph->hash_mask = hash_slots ? hash_slots - 1 : 0;
  1880		fph->custom = custom;
  1881		fph->mm = mm;
  1882	
  1883		for (i = 0; i < hash_slots; i++)
  1884			futex_hash_bucket_init(&fph->queues[i]);
  1885	
  1886		if (custom) {
  1887			/*
  1888			 * Only let prctl() wait / retry; don't unduly delay clone().
  1889			 */
  1890	again:
  1891			wait_var_event(mm, futex_pivot_pending(mm));
  1892		}
  1893	
  1894		scoped_guard(mutex, &mm->futex.phash.lock) {
  1895			struct futex_private_hash *free __free(kvfree) = NULL;
  1896			struct futex_private_hash *cur, *new;
  1897	
  1898			cur = rcu_dereference_protected(mm->futex.phash.hash,
  1899							lockdep_is_held(&mm->futex.phash.lock));
  1900			new = mm->futex.phash.hash_new;
  1901			mm->futex.phash.hash_new = NULL;
  1902	
  1903			if (fph) {
  1904				if (cur && !cur->hash_mask) {
  1905					/*
  1906					 * If two threads simultaneously request the global
  1907					 * hash then the first one performs the switch,
  1908					 * the second one returns here.
  1909					 */
  1910					free = fph;
  1911					mm->futex.phash.hash_new = new;
  1912					return -EBUSY;
  1913				}
  1914				if (cur && !new) {
  1915					/*
  1916					 * If we have an existing hash, but do not yet have
  1917					 * allocated a replacement hash, drop the initial
  1918					 * reference on the existing hash.
  1919					 */
  1920					futex_ref_drop(cur);
  1921				}
  1922	
  1923				if (new) {
  1924					/*
  1925					 * Two updates raced; throw out the lesser one.
  1926					 */
  1927					if (futex_hash_less(new, fph)) {
  1928						free = new;
  1929						new = fph;
  1930					} else {
  1931						free = fph;
  1932					}
  1933				} else {
  1934					new = fph;
  1935				}
  1936				fph = NULL;
  1937			}
  1938	
  1939			if (new) {
  1940				/*
  1941				 * Will set mm->futex.phash.new_hash on failure;
  1942				 * futex_private_hash_get() will try again.
  1943				 */
  1944				if (!__futex_pivot_hash(mm, new) && custom)
  1945					goto again;
  1946			}
  1947		}
  1948		return 0;
  1949	}
  1950	

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.