From patchwork Tue May 20 20:48:36 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andr=C3=A9_Almeida?= X-Patchwork-Id: 891405 Received: from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E6AAE2528FD; Tue, 20 May 2025 20:49:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.97.179.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747774162; cv=none; b=fPl6av85NzssSqc/J0Wp0zMoXMRmn6HZfjMvUpTvCsEkP/RK18byQhjh5NgRhklEl9dJoX64NawATsCe+Ady4846q6Ksu/u8f9ptzKmc+idTo1NolVBun8e+OUr2G5CR7j9q59CcFmj2KA/CM/JCEldH43/AN5uzfDtwiUQmKlA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747774162; c=relaxed/simple; bh=qwe1bJBCAnMaBv7MRTYCEzTpcsZbKb+3cNfJpCZ81FE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PZO95/OOIxThDFLpxcEtF3UwnY7QGa5nwTUe2OIy1BVMF/q8ZJZiO5eZ0B7rukfldSHONOLE3tnWV1lrAV/1TP9dT7Sv7xH8vKJGlElPsUHTe/j7HLk2YIBuLJVC8jiBBEFUxmtTDGlZFQaWM+1rLbu8FWWw4ba4QBjOY+V/msM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com; spf=pass smtp.mailfrom=igalia.com; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b=Z64110q5; arc=none smtp.client-ip=213.97.179.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=igalia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="Z64110q5" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Cc:To:In-Reply-To:References:Message-Id: Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date:From:Sender: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=soxJF2871E2kck9CgKzCBCd4PxV461xnRNXuEkzvOew=; b=Z64110q58MOONIUFSJj9RKmb4C hH0lX4SW68Hx445o3P8qMqTuU5ANlt6EAIKiI2aggeB3YRMSLYmx+nxiaEG9rumO5WiTDZGmRQH6q tnSpp79jn/kKmtDmSZfsAZBeI/+spGnBR3oeTDIwwn1IEzslA4AfKZ3KbL+7o6k0JPtQcVQU0wl9J vfrnTFjr+xynIPSi5YwjsQceE0U4Bs0xB8thVW9myDv7qFz9cTIOTbPfmefqB2riXJ7ROSRF+SF4o ccPgSDTnTNsDT43kostLRRiaDkAtUOK7MIHeCqyo9v8eHHplsAJZHNnhqqm1zb13zYklfXYaOZL3N BDY2X7mg==; Received: from [191.204.192.64] (helo=[192.168.15.100]) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1uHTtf-00AsVE-LN; Tue, 20 May 2025 22:49:11 +0200 From: =?utf-8?q?Andr=C3=A9_Almeida?= Date: Tue, 20 May 2025 17:48:36 -0300 Subject: [PATCH v4 3/7] futex: Use explicit sizes for compat_exit_robust_list Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250520-tonyk-robust_futex-v4-3-1123093e59de@igalia.com> References: <20250520-tonyk-robust_futex-v4-0-1123093e59de@igalia.com> In-Reply-To: <20250520-tonyk-robust_futex-v4-0-1123093e59de@igalia.com> To: Thomas Gleixner , Ingo Molnar , Peter Zijlstra , Darren Hart , Davidlohr Bueso , Shuah Khan , Arnd Bergmann , Sebastian Andrzej Siewior , Waiman Long Cc: linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-api@vger.kernel.org, =?utf-8?q?Andr=C3=A9_Almeida?= X-Mailer: b4 0.14.2 There are two functions for handling robust lists during the task exit: exit_robust_list() and compat_exit_robust_list(). The first one handles either 64bit or 32bit lists, depending if it's a 64bit or 32bit kernel. The compat_exit_robust_list() only exists in 64bit kernels that supports 32bit syscalls, and handles 32bit lists. For the new syscall set_robust_list2(), 64bit kernels need to be able to handle 32bit lists despite having or not support for 32bit syscalls, so make compat_exit_robust_list() exist regardless of compat_ config. Also, use explicitly sizing, otherwise in a 32bit kernel both exit_robust_list() and compat_exit_robust_list() would be the exactly same function, with none of them dealing with 64bit robust lists. Signed-off-by: André Almeida --- include/linux/compat.h | 12 +----------- include/linux/futex.h | 11 +++++++++++ include/linux/sched.h | 2 +- kernel/futex/core.c | 44 ++++++++++++++++++++++++++++---------------- kernel/futex/syscalls.c | 4 ++-- 5 files changed, 43 insertions(+), 30 deletions(-) diff --git a/include/linux/compat.h b/include/linux/compat.h index 56cebaff0c910fda853a0e2b3d6d0517e55f8b38..968a9135ff486cf9c8be2a18b80cd4c46e890236 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -385,16 +385,6 @@ struct compat_ifconf { compat_caddr_t ifcbuf; }; -struct compat_robust_list { - compat_uptr_t next; -}; - -struct compat_robust_list_head { - struct compat_robust_list list; - compat_long_t futex_offset; - compat_uptr_t list_op_pending; -}; - #ifdef CONFIG_COMPAT_OLD_SIGACTION struct compat_old_sigaction { compat_uptr_t sa_handler; @@ -672,7 +662,7 @@ asmlinkage long compat_sys_waitid(int, compat_pid_t, struct compat_siginfo __user *, int, struct compat_rusage __user *); asmlinkage long -compat_sys_set_robust_list(struct compat_robust_list_head __user *head, +compat_sys_set_robust_list(struct robust_list_head32 __user *head, compat_size_t len); asmlinkage long compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr, diff --git a/include/linux/futex.h b/include/linux/futex.h index 168ffd5996b4808491c05bdc7c8d0aeca1d37ee5..cd7c5d12c846566c56f3f3ea74b95e437a6e8193 100644 --- a/include/linux/futex.h +++ b/include/linux/futex.h @@ -56,6 +56,17 @@ union futex_key { #define FUTEX_KEY_INIT (union futex_key) { .both = { .ptr = 0ULL } } #ifdef CONFIG_FUTEX + +struct robust_list32 { + u32 next; +}; + +struct robust_list_head32 { + struct robust_list32 list; + s32 futex_offset; + u32 list_op_pending; +}; + enum { FUTEX_STATE_OK, FUTEX_STATE_EXITING, diff --git a/include/linux/sched.h b/include/linux/sched.h index 45e5953b8f326c2ff5e19de469d6cba27cc4c17d..51e5d05a9fcd407dcd53b7b7cb8c59783660a826 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1324,7 +1324,7 @@ struct task_struct { #ifdef CONFIG_FUTEX struct robust_list_head __user *robust_list; #ifdef CONFIG_COMPAT - struct compat_robust_list_head __user *compat_robust_list; + struct robust_list_head32 __user *compat_robust_list; #endif struct list_head pi_state_list; struct futex_pi_state *pi_state_cache; diff --git a/kernel/futex/core.c b/kernel/futex/core.c index 19a2c65f3d373c0b60c864a6fe0604787221d342..8640770aadc611b7341a3abb41bdb740e6394479 100644 --- a/kernel/futex/core.c +++ b/kernel/futex/core.c @@ -1144,13 +1144,14 @@ static inline int fetch_robust_entry(struct robust_list __user **entry, return 0; } +#ifdef CONFIG_64BIT /* * Walk curr->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) +static void exit_robust_list64(struct task_struct *curr) { struct robust_list_head __user *head = curr->robust_list; struct robust_list __user *entry, *next_entry, *pending; @@ -1211,8 +1212,13 @@ static void exit_robust_list(struct task_struct *curr) curr, pip, HANDLE_DEATH_PENDING); } } +#else +static void exit_robust_list64(struct task_struct *curr) +{ + pr_warn("32bit kernel should not allow ROBUST_LIST_64BIT"); +} +#endif -#ifdef CONFIG_COMPAT static void __user *futex_uaddr(struct robust_list __user *entry, compat_long_t futex_offset) { @@ -1226,13 +1232,13 @@ static void __user *futex_uaddr(struct robust_list __user *entry, * 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 *pi) +fetch_robust_entry32(u32 *uentry, struct robust_list __user **entry, + u32 __user *head, unsigned int *pi) { if (get_user(*uentry, head)) return -EFAULT; - *entry = compat_ptr((*uentry) & ~1); + *entry = (void __user *)(unsigned long)((*uentry) & ~1); *pi = (unsigned int)(*uentry) & 1; return 0; @@ -1244,21 +1250,21 @@ compat_fetch_robust_entry(compat_uptr_t *uentry, struct robust_list __user **ent * * We silently return on any sign of list-walking problem. */ -static void compat_exit_robust_list(struct task_struct *curr) +static void exit_robust_list32(struct task_struct *curr) { - struct compat_robust_list_head __user *head = curr->compat_robust_list; + struct robust_list_head32 __user *head = curr->compat_robust_list; struct robust_list __user *entry, *next_entry, *pending; unsigned int limit = ROBUST_LIST_LIMIT, pi, pip; unsigned int next_pi; - compat_uptr_t uentry, next_uentry, upending; - compat_long_t futex_offset; + u32 uentry, next_uentry, upending; + s32 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, &pi)) + if (fetch_robust_entry32((u32 *)&uentry, &entry, (u32 *)&head->list.next, &pi)) return; /* * Fetch the relative futex offset: @@ -1269,7 +1275,7 @@ static void compat_exit_robust_list(struct task_struct *curr) * Fetch any possibly pending lock-add first, and handle it * if it exists: */ - if (compat_fetch_robust_entry(&upending, &pending, + if (fetch_robust_entry32(&upending, &pending, &head->list_op_pending, &pip)) return; @@ -1279,8 +1285,8 @@ static void compat_exit_robust_list(struct task_struct *curr) * 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_pi); + rc = fetch_robust_entry32(&next_uentry, &next_entry, + (u32 __user *)&entry->next, &next_pi); /* * A pending lock might already be on the list, so * dont process it twice: @@ -1311,7 +1317,6 @@ static void compat_exit_robust_list(struct task_struct *curr) handle_futex_death(uaddr, curr, pip, HANDLE_DEATH_PENDING); } } -#endif #ifdef CONFIG_FUTEX_PI @@ -1406,14 +1411,21 @@ static inline void exit_pi_state_list(struct task_struct *curr) { } static void futex_cleanup(struct task_struct *tsk) { +#ifdef CONFIG_64BIT if (unlikely(tsk->robust_list)) { - exit_robust_list(tsk); + exit_robust_list64(tsk); tsk->robust_list = NULL; } +#else + if (unlikely(tsk->robust_list)) { + exit_robust_list32(tsk); + tsk->robust_list = NULL; + } +#endif #ifdef CONFIG_COMPAT if (unlikely(tsk->compat_robust_list)) { - compat_exit_robust_list(tsk); + exit_robust_list32(tsk); tsk->compat_robust_list = NULL; } #endif diff --git a/kernel/futex/syscalls.c b/kernel/futex/syscalls.c index 4b6da9116aa6c33db9796e3055ce0c90b02d7b91..dba193dfd216cc929c8f4d979aa2bcd99237e2d8 100644 --- a/kernel/futex/syscalls.c +++ b/kernel/futex/syscalls.c @@ -440,7 +440,7 @@ SYSCALL_DEFINE4(futex_requeue, #ifdef CONFIG_COMPAT COMPAT_SYSCALL_DEFINE2(set_robust_list, - struct compat_robust_list_head __user *, head, + struct robust_list_head32 __user *, head, compat_size_t, len) { if (unlikely(len != sizeof(*head))) @@ -455,7 +455,7 @@ COMPAT_SYSCALL_DEFINE3(get_robust_list, int, pid, compat_uptr_t __user *, head_ptr, compat_size_t __user *, len_ptr) { - struct compat_robust_list_head __user *head; + struct robust_list_head32 __user *head; unsigned long ret; struct task_struct *p; From patchwork Tue May 20 20:48:38 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andr=C3=A9_Almeida?= X-Patchwork-Id: 891404 Received: from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9B94F25CC61; Tue, 20 May 2025 20:49:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.97.179.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747774166; cv=none; b=OjXEqlt9dRh9lLqmTWpwmCV93M7dZuLgLv4AxTltY1d2euo/jjFtaA9+U3YLCJGFQ3EtjrNTYCbTtiAx/+7emav5NXy6jIZ/GK7H2PA+HH+bUE+l2beOfztwfxYX//t8BaYdc5wRmEWOjwGTG9NQFXt236hLzpyZ34iBJ5idA2s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747774166; c=relaxed/simple; bh=eE2PyitkntoNMoKoFD0RAgwDFQxOKSGVNOA1GV/xd28=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jyJiHcgge38GMEMdlZJQT3MpYCOU4v7ax802Frp/YJqmynW6AOtfyhJL8no1rNVA42qsw6pPzG3aaEjfRUyzeFRLXV6lOaSrpRlrr+Dkj4mc535PEWhXR2DXsI6ZlGo6lR9rz5Z443+v0RbUmfteLH8mu1ZItvtlXhjJaRYscWg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com; spf=pass smtp.mailfrom=igalia.com; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b=PC+An1ZM; arc=none smtp.client-ip=213.97.179.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=igalia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="PC+An1ZM" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Cc:To:In-Reply-To:References:Message-Id: Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date:From:Sender: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=l/grAn1V/PWLVqAuWAXwa7AZ2lhCZoBiGV75dOFYz/c=; b=PC+An1ZM6IQG/bTqS9yuAux4jA lgjAT4wKn3KP0nYQ1QgtE0TfQHq/iQ4RbIHp5UTV1RRqnGsVbANPlkltSRWpB3PEuHhbuAXH1Nlj/ uIM71RsAu15knw3fMXnQIowUXJFWQTkJM/wvaV0QiaVzo6DQmXRSYKbbxgRi8ap854UORLEe60vtu SILH5oKWCqo7XyEeBkN/dmdiJX2/OqKdzsAop1VfEwhThQ807KrDj+ZeLm7AS4nA0YVWfnIXX+/Zf skAR89/Ki6xKX1uZuvTA8BXOSy582WEedwfzEnbWVzRxrbKUnt26Z9MSVtrw2ifZLNleUq9pCPk2q 9brHCj1A==; Received: from [191.204.192.64] (helo=[192.168.15.100]) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1uHTtl-00AsVE-MG; Tue, 20 May 2025 22:49:17 +0200 From: =?utf-8?q?Andr=C3=A9_Almeida?= Date: Tue, 20 May 2025 17:48:38 -0300 Subject: [PATCH v4 5/7] futex: Wire up set_robust_list2 syscall Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250520-tonyk-robust_futex-v4-5-1123093e59de@igalia.com> References: <20250520-tonyk-robust_futex-v4-0-1123093e59de@igalia.com> In-Reply-To: <20250520-tonyk-robust_futex-v4-0-1123093e59de@igalia.com> To: Thomas Gleixner , Ingo Molnar , Peter Zijlstra , Darren Hart , Davidlohr Bueso , Shuah Khan , Arnd Bergmann , Sebastian Andrzej Siewior , Waiman Long Cc: linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-api@vger.kernel.org, =?utf-8?q?Andr=C3=A9_Almeida?= X-Mailer: b4 0.14.2 Wire up the new set_robust_list2 syscall in all available architectures. Signed-off-by: André Almeida --- arch/alpha/kernel/syscalls/syscall.tbl | 1 + arch/arm/tools/syscall.tbl | 1 + arch/m68k/kernel/syscalls/syscall.tbl | 1 + arch/microblaze/kernel/syscalls/syscall.tbl | 1 + arch/mips/kernel/syscalls/syscall_n32.tbl | 1 + arch/mips/kernel/syscalls/syscall_n64.tbl | 1 + arch/mips/kernel/syscalls/syscall_o32.tbl | 1 + arch/parisc/kernel/syscalls/syscall.tbl | 1 + arch/powerpc/kernel/syscalls/syscall.tbl | 1 + arch/s390/kernel/syscalls/syscall.tbl | 1 + arch/sh/kernel/syscalls/syscall.tbl | 1 + arch/sparc/kernel/syscalls/syscall.tbl | 1 + arch/x86/entry/syscalls/syscall_32.tbl | 1 + arch/x86/entry/syscalls/syscall_64.tbl | 1 + arch/xtensa/kernel/syscalls/syscall.tbl | 1 + kernel/sys_ni.c | 1 + scripts/syscall.tbl | 1 + 17 files changed, 17 insertions(+) diff --git a/arch/alpha/kernel/syscalls/syscall.tbl b/arch/alpha/kernel/syscalls/syscall.tbl index 2dd6340de6b4efddc406f0c235701c15cf02f650..aecc167ac7706d25da73db8099f0813e268b820c 100644 --- a/arch/alpha/kernel/syscalls/syscall.tbl +++ b/arch/alpha/kernel/syscalls/syscall.tbl @@ -507,3 +507,4 @@ 575 common listxattrat sys_listxattrat 576 common removexattrat sys_removexattrat 577 common open_tree_attr sys_open_tree_attr +578 common set_robust_list2 sys_robust_list2 diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl index 27c1d5ebcd91c8c296dc6676307f66bfdf4ab78d..2e47ae5dc9a426d8e5e9dacf29caa54223cf2f5a 100644 --- a/arch/arm/tools/syscall.tbl +++ b/arch/arm/tools/syscall.tbl @@ -482,3 +482,4 @@ 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat 467 common open_tree_attr sys_open_tree_attr +468 common set_robust_list2 sys_set_robust_list2 diff --git a/arch/m68k/kernel/syscalls/syscall.tbl b/arch/m68k/kernel/syscalls/syscall.tbl index 9fe47112c586f152662af38a9a7f90957cb96cf8..7bcc8cc628c80a44fea2b53d5c69ab5e5f10a1d2 100644 --- a/arch/m68k/kernel/syscalls/syscall.tbl +++ b/arch/m68k/kernel/syscalls/syscall.tbl @@ -467,3 +467,4 @@ 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat 467 common open_tree_attr sys_open_tree_attr +468 common set_robust_list2 sys_set_robust_list2 diff --git a/arch/microblaze/kernel/syscalls/syscall.tbl b/arch/microblaze/kernel/syscalls/syscall.tbl index 7b6e97828e552d4da90046ddfcd4a55723e522bb..cd23608afe7e7dadfbf8e21df0486b85bfcb99ce 100644 --- a/arch/microblaze/kernel/syscalls/syscall.tbl +++ b/arch/microblaze/kernel/syscalls/syscall.tbl @@ -473,3 +473,4 @@ 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat 467 common open_tree_attr sys_open_tree_attr +468 common set_robust_list2 sys_set_robust_list2 diff --git a/arch/mips/kernel/syscalls/syscall_n32.tbl b/arch/mips/kernel/syscalls/syscall_n32.tbl index aa70e371bb54ab5d9c8dd8923b6ecf9693ee914d..0a31452ef6ed8fee8f1e2ead5d44acfbbe275fe9 100644 --- a/arch/mips/kernel/syscalls/syscall_n32.tbl +++ b/arch/mips/kernel/syscalls/syscall_n32.tbl @@ -406,3 +406,4 @@ 465 n32 listxattrat sys_listxattrat 466 n32 removexattrat sys_removexattrat 467 n32 open_tree_attr sys_open_tree_attr +468 n32 set_robust_list2 sys_set_robust_list2 diff --git a/arch/mips/kernel/syscalls/syscall_n64.tbl b/arch/mips/kernel/syscalls/syscall_n64.tbl index 1e8c44c7b61492eabf00c777831e457a7a6e579c..4cb5a72256338f6fb407f940f1883d523113d609 100644 --- a/arch/mips/kernel/syscalls/syscall_n64.tbl +++ b/arch/mips/kernel/syscalls/syscall_n64.tbl @@ -382,3 +382,4 @@ 465 n64 listxattrat sys_listxattrat 466 n64 removexattrat sys_removexattrat 467 n64 open_tree_attr sys_open_tree_attr +468 n64 set_robust_list2 sys_set_robust_list2 diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl b/arch/mips/kernel/syscalls/syscall_o32.tbl index 114a5a1a62302e32dd74d1679ff423a2d57c3c6b..c46238e9edd00d2861edcfa87c5ce7a62bfdc3d4 100644 --- a/arch/mips/kernel/syscalls/syscall_o32.tbl +++ b/arch/mips/kernel/syscalls/syscall_o32.tbl @@ -455,3 +455,4 @@ 465 o32 listxattrat sys_listxattrat 466 o32 removexattrat sys_removexattrat 467 o32 open_tree_attr sys_open_tree_attr +468 o32 set_robust_list2 sys_set_robust_list2 diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl index 94df3cb957e9d547d192e8732c0cf23ef2b5ce5d..71071489a18375013bbfbe26578a634283c1e07b 100644 --- a/arch/parisc/kernel/syscalls/syscall.tbl +++ b/arch/parisc/kernel/syscalls/syscall.tbl @@ -466,3 +466,4 @@ 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat 467 common open_tree_attr sys_open_tree_attr +468 common set_robust_list2 sys_set_robust_list2 diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl index 9a084bdb892694bc562f514b55212d167cbac12f..edc4d0bef3f1c7ab826ea8180e7f5ceba4774c07 100644 --- a/arch/powerpc/kernel/syscalls/syscall.tbl +++ b/arch/powerpc/kernel/syscalls/syscall.tbl @@ -558,3 +558,4 @@ 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat 467 common open_tree_attr sys_open_tree_attr +468 common set_robust_list2 sys_set_robust_list2 diff --git a/arch/s390/kernel/syscalls/syscall.tbl b/arch/s390/kernel/syscalls/syscall.tbl index a4569b96ef06c54ce7aa795d039541c90a38284f..ff8c594073ec8c3486cc61544d14a338d3f3a906 100644 --- a/arch/s390/kernel/syscalls/syscall.tbl +++ b/arch/s390/kernel/syscalls/syscall.tbl @@ -470,3 +470,4 @@ 465 common listxattrat sys_listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat sys_removexattrat 467 common open_tree_attr sys_open_tree_attr sys_open_tree_attr +468 common set_robust_list2 sys_set_robust_list2 sys_set_robust_list2 diff --git a/arch/sh/kernel/syscalls/syscall.tbl b/arch/sh/kernel/syscalls/syscall.tbl index 52a7652fcff6394b96ace1f3b0ed72250ee5e669..507789194570a9e7b492b210be30bb41021be289 100644 --- a/arch/sh/kernel/syscalls/syscall.tbl +++ b/arch/sh/kernel/syscalls/syscall.tbl @@ -471,3 +471,4 @@ 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat 467 common open_tree_attr sys_open_tree_attr +468 common set_robust_list2 sys_set_robust_list2 diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl index 83e45eb6c095a36baaf749927628e6052fe900e6..8d1122c2235b8d5082a11392e68787efe55f58be 100644 --- a/arch/sparc/kernel/syscalls/syscall.tbl +++ b/arch/sparc/kernel/syscalls/syscall.tbl @@ -513,3 +513,4 @@ 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat 467 common open_tree_attr sys_open_tree_attr +468 common set_robust_list2 sys_set_robust_list2 diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl index ac007ea00979dc28b0ef7c002a0615ce86dd3101..cbc0c469e66ecf7b8a61e82c38b07ecc63f6fe23 100644 --- a/arch/x86/entry/syscalls/syscall_32.tbl +++ b/arch/x86/entry/syscalls/syscall_32.tbl @@ -473,3 +473,4 @@ 465 i386 listxattrat sys_listxattrat 466 i386 removexattrat sys_removexattrat 467 i386 open_tree_attr sys_open_tree_attr +468 i386 set_robust_list2 sys_set_robust_list2 diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl index cfb5ca41e30de1a4e073750096f5b51a2ec137d2..b420217c72fc50ad90f291812972019606c5ff69 100644 --- a/arch/x86/entry/syscalls/syscall_64.tbl +++ b/arch/x86/entry/syscalls/syscall_64.tbl @@ -391,6 +391,7 @@ 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat 467 common open_tree_attr sys_open_tree_attr +468 common set_robust_list2 sys_set_robust_list2 # # Due to a historical design error, certain syscalls are numbered differently diff --git a/arch/xtensa/kernel/syscalls/syscall.tbl b/arch/xtensa/kernel/syscalls/syscall.tbl index f657a77314f8667fa019a01e10c84ea270024adc..6b852ee8a1621c7dd24f6cd37fd990f5ff8d8527 100644 --- a/arch/xtensa/kernel/syscalls/syscall.tbl +++ b/arch/xtensa/kernel/syscalls/syscall.tbl @@ -438,3 +438,4 @@ 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat 467 common open_tree_attr sys_open_tree_attr +468 common set_robust_list2 sys_set_robust_list2 diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index c00a86931f8c6cb30d35a9d56cbcc5994add90e1..71fbac6176c8886f4fa8dd437b0aedd5f14e9f74 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c @@ -195,6 +195,7 @@ COND_SYSCALL(move_pages); COND_SYSCALL(set_mempolicy_home_node); COND_SYSCALL(cachestat); COND_SYSCALL(mseal); +COND_SYSCALL(set_robust_list2); COND_SYSCALL(perf_event_open); COND_SYSCALL(accept4); diff --git a/scripts/syscall.tbl b/scripts/syscall.tbl index 580b4e246aecd5f07d542943ba68fc4ed5961660..07d7e776d0329659e70a9a55ffff7ac18eb3ff87 100644 --- a/scripts/syscall.tbl +++ b/scripts/syscall.tbl @@ -408,3 +408,4 @@ 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat 467 common open_tree_attr sys_open_tree_attr +468 common set_robust_list2 sys_set_robust_list2 From patchwork Tue May 20 20:48:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andr=C3=A9_Almeida?= X-Patchwork-Id: 891403 Received: from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7C09825EFBD; Tue, 20 May 2025 20:49:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.97.179.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747774172; cv=none; b=RiHSa+Voh7Gi7LXO54fJLL5FEyV3665khuvWRk3GKQvX4xCvmM2kpQgzTAb/2+RRj4xhfVqogDLWuv2ZQwWAxEGXo9mxHbVlM8Ao4IFCNVLmR60BLHnp0zI+O3k1gEP86Dq8NolE2SHeu6Mqai7O+rf5nX1qI+0qna9srlkHcLs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747774172; c=relaxed/simple; bh=PecueBhb3qx1RHFBN98VuO4lhdtWIZM9jToHkTc/HLE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iQKks8mHcmANwcZRZ7aGfTGEFB4XcJ+TOgvcYZvEHWMN9yQx8dOIyYPOAbI4Wydi06yzO7YBaA70KXPP3Ttvt5HOJun4IHjhBauxsE5wadBtTr754VadjGE/n8T6B0M/bU4kg0pt5qxn526MOiqIsu72HWDNmPowIyEc5HjZxmY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com; spf=pass smtp.mailfrom=igalia.com; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b=QsSmc2fi; arc=none smtp.client-ip=213.97.179.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=igalia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="QsSmc2fi" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Cc:To:In-Reply-To:References:Message-Id: Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date:From:Sender: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=N5VA/SwJ6w5fExHAtI2s26hUsQkblQRmCfj6Ybce2s4=; b=QsSmc2fiAU/dBhF6op4s9dOnK7 8A3Swh8uMNx8/HOxBSDFeLbp7OchiP7AwIIYTYhbh0dGOQdtoLWkfPzx4K/sSmsnMItb22Yg5WuIT 9TJN/Iobd5w3dk8Fe3JtzZ6WocNrTnIPSaloUI5wSC3JLmDx0jX06jwLZH8AwdL/9rh6OqoiPL/lI abZ2y1DIZUNj4Z2NF9OngOkhGyY7HMDqRL8KR4fsGPRFw7T5REVcU5L/j36YnRRmfkofguADoOO/e NT2quKhTnOkkkam8WlovpGUb/FUw1WWCngOjFJrXyzFFZsmBg7L3lBZEJ6UIIcGJ41YES7jSOyHcF MoykCUew==; Received: from [191.204.192.64] (helo=[192.168.15.100]) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1uHTtr-00AsVE-NH; Tue, 20 May 2025 22:49:23 +0200 From: =?utf-8?q?Andr=C3=A9_Almeida?= Date: Tue, 20 May 2025 17:48:40 -0300 Subject: [PATCH v4 7/7] selftests: futex: Expand robust list test for the new interface Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250520-tonyk-robust_futex-v4-7-1123093e59de@igalia.com> References: <20250520-tonyk-robust_futex-v4-0-1123093e59de@igalia.com> In-Reply-To: <20250520-tonyk-robust_futex-v4-0-1123093e59de@igalia.com> To: Thomas Gleixner , Ingo Molnar , Peter Zijlstra , Darren Hart , Davidlohr Bueso , Shuah Khan , Arnd Bergmann , Sebastian Andrzej Siewior , Waiman Long Cc: linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-api@vger.kernel.org, =?utf-8?q?Andr=C3=A9_Almeida?= X-Mailer: b4 0.14.2 Expand the current robust list test for the new set_robust_list2 syscall. Create an option to make it possible to run the same tests using the new syscall, and also add two new relevant test: test long lists (bigger than ROBUST_LIST_LIMIT) and for unaligned addresses. Signed-off-by: André Almeida --- .../selftests/futex/functional/robust_list.c | 160 ++++++++++++++++++++- 1 file changed, 156 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/futex/functional/robust_list.c b/tools/testing/selftests/futex/functional/robust_list.c index 42690b2440fd29a9b12c46f67f9645ccc93d1147..004ad79ff6171c411fd47e699e3c38889544218e 100644 --- a/tools/testing/selftests/futex/functional/robust_list.c +++ b/tools/testing/selftests/futex/functional/robust_list.c @@ -35,16 +35,45 @@ #include #include #include +#include #define STACK_SIZE (1024 * 1024) #define FUTEX_TIMEOUT 3 +#define SYS_set_robust_list2 468 + +enum robust_list2_type { + ROBUST_LIST_32BIT, + ROBUST_LIST_64BIT, +}; + static pthread_barrier_t barrier, barrier2; +bool robust2 = false; + int set_robust_list(struct robust_list_head *head, size_t len) { - return syscall(SYS_set_robust_list, head, len); + int ret, flags; + + if (!robust2) { + return syscall(SYS_set_robust_list, head, len); + } + + if (sizeof(head) == 8) + flags = ROBUST_LIST_64BIT; + else + flags = ROBUST_LIST_32BIT; + + /* + * We act as we have just one list here. We try to use the first slot, + * but if it hasn't been alocated yet we allocate it. + */ + ret = syscall(SYS_set_robust_list2, head, 0, flags); + if (ret == -1 && errno == ENOENT) + ret = syscall(SYS_set_robust_list2, head, -1, flags); + + return ret; } int get_robust_list(int pid, struct robust_list_head **head, size_t *len_ptr) @@ -246,6 +275,11 @@ static void test_set_robust_list_invalid_size(void) size_t head_size = sizeof(struct robust_list_head); int ret; + if (robust2) { + ksft_test_result_skip("This test is only for old robust interface\n"); + return; + } + ret = set_robust_list(&head, head_size); ASSERT_EQ(ret, 0); @@ -321,6 +355,11 @@ static void test_get_robust_list_child(void) struct robust_list_head head, *get_head; size_t len_ptr; + if (robust2) { + ksft_test_result_skip("Not implemented in the new robust interface\n"); + return; + } + ret = pthread_barrier_init(&barrier, NULL, 2); ret = pthread_barrier_init(&barrier2, NULL, 2); ASSERT_EQ(ret, 0); @@ -332,7 +371,7 @@ static void test_get_robust_list_child(void) ret = get_robust_list(tid, &get_head, &len_ptr); ASSERT_EQ(ret, 0); - ASSERT_EQ(&head, get_head); + ASSERT_EQ(get_head, &head); pthread_barrier_wait(&barrier2); @@ -507,11 +546,119 @@ static void test_circular_list(void) ksft_test_result_pass("%s\n", __func__); } +#define ROBUST_LIST_LIMIT 2048 +#define CHILD_LIST_LIMIT (ROBUST_LIST_LIMIT + 10) + +static int child_robust_list_limit(void *arg) +{ + struct lock_struct *locks; + struct robust_list *list; + struct robust_list_head head; + int ret, i; + + locks = (struct lock_struct *) arg; + + ret = set_list(&head); + if (ret) + ksft_test_result_fail("set_list error\n"); + + /* + * Create a very long list of locks + */ + head.list.next = &locks[0].list; + + list = head.list.next; + for (i = 0; i < CHILD_LIST_LIMIT - 1; i++) { + list->next = &locks[i+1].list; + list = list->next; + } + list->next = &head.list; + + /* + * Grab the lock in the last one, and die without releasing it + */ + mutex_lock(&locks[CHILD_LIST_LIMIT], &head, false); + pthread_barrier_wait(&barrier); + + sleep(1); + + return 0; +} + +/* + * The old robust list used to have a limit of 2048 items from the kernel side. + * After this limit the kernel stops walking the list and ignore the other + * futexes, causing deadlocks. + * + * For the new interface, test if we can wait for a list of more than 2048 + * elements. + */ +static void test_robust_list_limit(void) +{ + struct lock_struct locks[CHILD_LIST_LIMIT + 1]; + _Atomic(unsigned int) *futex = &locks[CHILD_LIST_LIMIT].futex; + struct robust_list_head head; + int ret; + + if (!robust2) { + ksft_test_result_skip("This test is only for new robust interface\n"); + return; + } + + *futex = 0; + + ret = set_list(&head); + ASSERT_EQ(ret, 0); + + ret = pthread_barrier_init(&barrier, NULL, 2); + ASSERT_EQ(ret, 0); + + create_child(child_robust_list_limit, locks); + + /* + * After the child thread creates the very long list of locks, wait on + * the last one. + */ + pthread_barrier_wait(&barrier); + ret = mutex_lock(&locks[CHILD_LIST_LIMIT], &head, false); + + if (ret != 0) + printf("futex wait returned %d\n", errno); + ASSERT_EQ(ret, 0); + + ASSERT_TRUE(*futex | FUTEX_OWNER_DIED); + + wait(NULL); + pthread_barrier_destroy(&barrier); + + ksft_test_result_pass("%s\n", __func__); +} + +/* + * The kernel should refuse an unaligned head pointer + */ +static void test_unaligned_address(void) +{ + struct robust_list_head head, *h; + int ret; + + if (!robust2) { + ksft_test_result_skip("This test is only for new robust interface\n"); + return; + } + + h = (struct robust_list_head *) ((uintptr_t) &head + 1); + ret = set_list(h); + ASSERT_EQ(ret, -1); + ASSERT_EQ(errno, EINVAL); +} + void usage(char *prog) { printf("Usage: %s\n", prog); printf(" -c Use color\n"); printf(" -h Display this help message\n"); + printf(" -n Use robust2 syscall\n"); printf(" -v L Verbosity level: %d=QUIET %d=CRITICAL %d=INFO\n", VQUIET, VCRITICAL, VINFO); } @@ -520,7 +667,7 @@ int main(int argc, char *argv[]) { int c; - while ((c = getopt(argc, argv, "cht:v:")) != -1) { + while ((c = getopt(argc, argv, "chnt:v:")) != -1) { switch (c) { case 'c': log_color(1); @@ -531,6 +678,9 @@ int main(int argc, char *argv[]) case 'v': log_verbosity(atoi(optarg)); break; + case 'n': + robust2 = true; + break; default: usage(basename(argv[0])); exit(1); @@ -538,7 +688,7 @@ int main(int argc, char *argv[]) } ksft_print_header(); - ksft_set_plan(7); + ksft_set_plan(8); test_robustness(); @@ -548,6 +698,8 @@ int main(int argc, char *argv[]) test_set_list_op_pending(); test_robust_list_multiple_elements(); test_circular_list(); + test_robust_list_limit(); + test_unaligned_address(); ksft_print_cnts(); return 0;