From patchwork Fri Sep 13 14:21:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 97537 X-Patchwork-Delegate: azanella@linux.vnet.ibm.com Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0C25D385DC20 for ; Fri, 13 Sep 2024 14:23:15 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pg1-x536.google.com (mail-pg1-x536.google.com [IPv6:2607:f8b0:4864:20::536]) by sourceware.org (Postfix) with ESMTPS id 056063858D28 for ; Fri, 13 Sep 2024 14:22:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 056063858D28 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 056063858D28 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::536 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1726237367; cv=none; b=sNHRjimNhE1hNk7R2ihHBy+m2kXgfmHZWk4c511XagnOV9g/ASV1hCGzCGA8Ap0C+nrLghfEPfb/2z681ISE4DwGPyfoWwr8vsHNbIi6LbawoNE1f9+6UIu4uCxPfi+X3NPftu84xOSoNd0czkvmeTs1m9DQ7aOauv7nUxDCF50= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1726237367; c=relaxed/simple; bh=IjaL6IZl4OCTwvqkqYwpGupdYOp5QzIg2jsZW6Zno1s=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=e2Y6Vi8LLgTG0jGx0JfiGE4clKD+hU/jr3bIAQQ8TrpnApa+Z201/xeLxLWrf0FS7H/4848v2YCv64fpgcS/D3xHIeuBYsMAThuAugPVqgfwOJSkiktu0Dv+VfJWVPsiQ/uhEvZFMq4Y1UItIfJPXdqRWbUPHt1KcckCOD8H8jE= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pg1-x536.google.com with SMTP id 41be03b00d2f7-6bce380eb96so1379184a12.0 for ; Fri, 13 Sep 2024 07:22:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1726237363; x=1726842163; darn=sourceware.org; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:from:to:cc:subject:date:message-id:reply-to; bh=WDnTt9osecIJdnZENUJGRARATifZMUGPlHNJ+ZNAly4=; b=t3oo7pJn43Q+D9AAIgdKDSO5W190pG7rMNx237GBSUof6N2pjdvn4rEssAKS/3+8t+ 06wO5DkHTJ/zgzq7nho0kfQy0xjJNTrXXCLK80fNFTBjbOK5q9ZoMye54XDFx8mFxZxd 85DiYDQDT0BrJGdFUg07aVsCuBAVuJQqSf5H26ry+H/K+5Q6jjaC9CItAg/yvyJrCaxt Md/tC+uvTo8Y2ibD83HgjuPK0hSqnllE2d9HAo3cc9cX5imCRWReYuQIiKNQrkvekvBQ T86DflY3gK/4Vstd9GELMH8WgMBaBBdDT7MJzab+D0VKKCB+Q4ix1LULjnfVf55lhn+V GGLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726237363; x=1726842163; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=WDnTt9osecIJdnZENUJGRARATifZMUGPlHNJ+ZNAly4=; b=hg7IKAqCx29koMwCYR2R3iKM3XGDrr2V2lhqNGgWYIU8g4PBJ/gi3eFUP9gpKQ8N1I xwfiOlXNq63X9l6bdJgWFyU3YV/RGxV7ZX13cdV+t5eL86mM+PzTxHWJscNeMSjYfHXY kBTzfFErDczh4W2CzAS4vFxnnFlOcjjNHhSeFcvr6bDC86FPOrSB0zyNl7Z9z0VccIQh SSGtm1Frne/F3nJYKyJnM/plgzrap4qYJf2ePm5tfNTXCoUcOzyYPNk4v3GdbgXyhibj A0ui33H1WNRcRoweP2rXGZFSqP7Ki4zZDUeYh6LtQHV0eWCjhMDKvG0bSPwGLUp305k1 veJg== X-Gm-Message-State: AOJu0YxbIQomKrcPn3Km8cWPig1An0qDWbGbWH4bnL5Nja50KC5L+zxF XW2jSsy+S8/AXiyCwN7sbRHJwhgWBTeM7Ko8ZvTv2ELGbcpnbDWIWAg1YafM8m0Ti4ct25VKgP9 S X-Google-Smtp-Source: AGHT+IH50VX9yi9i+mgsZCSlk/U40EseCE/4AhFNljwUCikIKoyloE086tbLElyiH3MM4ok+0jq9+w== X-Received: by 2002:a17:90b:1c07:b0:2d3:da82:28e0 with SMTP id 98e67ed59e1d1-2db9ffc1c9fmr6923237a91.9.1726237363195; Fri, 13 Sep 2024 07:22:43 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c0:80ff:89a7:2ddb:21db:5421]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2dbb9c4f447sm1813440a91.6.2024.09.13.07.22.41 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 13 Sep 2024 07:22:42 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 1/2] support: Make support_process_state_wait return the found state Date: Fri, 13 Sep 2024 11:21:51 -0300 Message-ID: <20240913142239.2949727-1-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 X-Spam-Status: No, score=-12.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org So caller can check which state was found if multiple ones are asked. Checked on x86_64-linux-gnu. Reviewed-by: Florian Weimer --- support/process_state.h | 7 +++++-- support/support_process_state.c | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/support/process_state.h b/support/process_state.h index 1cf902e91b..9541d8c343 100644 --- a/support/process_state.h +++ b/support/process_state.h @@ -31,13 +31,16 @@ enum support_process_state support_process_state_dead = 0x20, /* X (dead). */ support_process_state_zombie = 0x40, /* Z (zombie). */ support_process_state_parked = 0x80, /* P (parked). */ + support_process_state_invalid = 0x100 /* Invalid state. */ }; /* Wait for process PID to reach state STATE. It can be a combination of multiple possible states ('process_state_running | process_state_sleeping') where the function return when any of these state are observed. For an invalid state not represented by SUPPORT_PROCESS_STATE, it fallbacks - to a 2 second sleep. */ -void support_process_state_wait (pid_t pid, enum support_process_state state); + to a 2 second sleep. + Return the found process state. */ +enum support_process_state +support_process_state_wait (pid_t pid, enum support_process_state state); #endif diff --git a/support/support_process_state.c b/support/support_process_state.c index 062335234f..ae8e0a531c 100644 --- a/support/support_process_state.c +++ b/support/support_process_state.c @@ -27,7 +27,7 @@ #include #include -void +enum support_process_state support_process_state_wait (pid_t pid, enum support_process_state state) { #ifdef __linux__ @@ -75,7 +75,7 @@ support_process_state_wait (pid_t pid, enum support_process_state state) { free (line); xfclose (fstatus); - return; + return process_states[i].s; } rewind (fstatus); @@ -90,4 +90,6 @@ support_process_state_wait (pid_t pid, enum support_process_state state) /* Fallback to nanosleep if an invalid state is found. */ #endif nanosleep (&(struct timespec) { 1, 0 }, NULL); + + return support_process_state_invalid; } From patchwork Fri Sep 13 14:21:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 97538 X-Patchwork-Delegate: fweimer@redhat.com Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5C719385DC1E for ; Fri, 13 Sep 2024 14:23:19 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pg1-x532.google.com (mail-pg1-x532.google.com [IPv6:2607:f8b0:4864:20::532]) by sourceware.org (Postfix) with ESMTPS id F146A3858C98 for ; Fri, 13 Sep 2024 14:22:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org F146A3858C98 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org F146A3858C98 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::532 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1726237371; cv=none; b=scJmfnNVxW/AEQxmdxRfGRSe87BsMuejrfvgAjrUXUOZsKD4X1Cj/qy2G8HEUnoAxRsrFOO6YwsCsqm0oqeeYCa9lGrxbQ4BkaSjSsexdcaISy1dNTvXyDo67W3k/i2XjtLQQ6ub+rflU8Pqm1OE5xBOVqFD5sFKr2sLZmRLdRg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1726237371; c=relaxed/simple; bh=pBtzJhHJ1mXh6eVzSNF688+KsD6tKM/o0aJpwxt7W08=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=OECPFhzJLKf921PA3DT4Op2kR5AdQrBEPa41iO0bsEc1G1+rasg9pWvruS8kPVu3MM83RsCISxmC5UeO31nx6ACdGGHStJtHpeS/tOEOxf8aW2Rhcj215lM5ZdEzPVYT5VxkVrodqZwZQuFopDv64jrmLLliZR4WLcW94/KtWG0= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pg1-x532.google.com with SMTP id 41be03b00d2f7-7d50b3a924bso911604a12.0 for ; Fri, 13 Sep 2024 07:22:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1726237366; x=1726842166; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=1FN4KR0Y7cYdCq07Pl+y7wYcsC+Jqe8QGi1h7QUsFGc=; b=SP+Yn8TzU4lC+vgJqcpyRk8TXvGW4Wb4qKv26BEe053WOz68WRVR5o7GknWH8jpSYk /bnST6e03s2tQRO7Dx4F+R+zXnJH8dbnHLEJtTfOBTSRiQD8fjMXPDEmx2/qU39PUg2Q dj4CHdK06O5de5cJSivAgRiAUdwOhZf7BLEJW6NAP6koJGnKlDrB2BH6hHOv/p13FD/h OQUmW7c42ycpd3Xn0EY71rfZWbyaJd7vGtlvy5rw23nwB0pFLOa3peqGqEvTMlLbIH01 LqQPAO5yKHAQSPuDfQgtUDiBzBrr6AsXEOrPlVxHz0Ksooizady1KlopO7XhBf2HS0sx MLbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726237366; x=1726842166; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1FN4KR0Y7cYdCq07Pl+y7wYcsC+Jqe8QGi1h7QUsFGc=; b=SUfLRgzggatxKP/qzLI+3QhZEf7WOB7EGBY1DL7r1lP4//oH1EbJYt4L/N7AIHrybf qaGG2iNSdErJCjCp8OWq2qU7bMaItR/PjEEn4yZnuATSnWQtJZdmM9FDTCUy64h5O5yb +bpl+1Nbpi65DvMGwJXllFP0mQx0XmKBLI3olplMNh43jRUOHKPdzORS00UezAzCSzPA 2rKKwM9XRGypm1+xIYr/O9PML+G76YuY8OO3nbXLJP6QNNtjs5mC/lfBn/g2GBaS3oOi WIA59N5StK12tWs76MFG/E3ftKJRd5zv5pE/Km8r8m/opBK5Au1o348tATaLr5+Z2Pn1 TG9g== X-Gm-Message-State: AOJu0YyVMIRh1tEbXq5RNL12w1x6ZmY60KoNmdBPwocOnGMOiKHOubD/ BGvAe2qA+HGunpls0aA1IyIhdexXbr7CLh/ljQO3ZkYW/yH20plYXXnGc2cnxioQQmgbafltfYC p X-Google-Smtp-Source: AGHT+IH4+9p5iW6ocs01Tt/RB3oPp0h+4Ec0EPofb2C5tsjnQcU/038N96WB/AQaqHhnQDb/hfYljg== X-Received: by 2002:a05:6a21:4581:b0:1cc:dd58:e23b with SMTP id adf61e73a8af0-1cf75d7fe6dmr9841612637.10.1726237366169; Fri, 13 Sep 2024 07:22:46 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c0:80ff:89a7:2ddb:21db:5421]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2dbb9c4f447sm1813440a91.6.2024.09.13.07.22.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 13 Sep 2024 07:22:45 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: =?utf-8?q?Ren=C3=A9_Rebe?= Subject: [PATCH 2/2] sparc: Fix restartable syscalls (BZ 32173) Date: Fri, 13 Sep 2024 11:21:52 -0300 Message-ID: <20240913142239.2949727-2-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240913142239.2949727-1-adhemerval.zanella@linaro.org> References: <20240913142239.2949727-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org The commit 'sparc: Use Linux kABI for syscall return' (86c5d2cf0ce046279baddc7faa27da71f1a89fde) did not take into consideration a subtle sparc syscall kABI constraint. For syscalls that might block indefinitely, on an interrupt (like SIGCONT) the kernel will set the instruction pointer to just before the syscall: arch/sparc/kernel/signal_64.c 476 static void do_signal(struct pt_regs *regs, unsigned long orig_i0) 477 { [...] 525 if (restart_syscall) { 526 switch (regs->u_regs[UREG_I0]) { 527 case ERESTARTNOHAND: 528 case ERESTARTSYS: 529 case ERESTARTNOINTR: 530 /* replay the system call when we are done */ 531 regs->u_regs[UREG_I0] = orig_i0; 532 regs->tpc -= 4; 533 regs->tnpc -= 4; 534 pt_regs_clear_syscall(regs); 535 fallthrough; 536 case ERESTART_RESTARTBLOCK: 537 regs->u_regs[UREG_G1] = __NR_restart_syscall; 538 regs->tpc -= 4; 539 regs->tnpc -= 4; 540 pt_regs_clear_syscall(regs); 541 } However, on a SIGCONT it seems that 'g1' register is being clobbered after the syscall returns. Before 86c5d2cf0ce046279, the 'g1' was always placed jus before the 'ta' instruction which then reloads the syscall number and restarts the syscall. On master, where 'g1' might be placed before 'ta': $ cat test.c #include int main () { pause (); } $ gcc test.c -o test $ strace -f ./t [...] ppoll(NULL, 0, NULL, NULL, 0 On another terminal $ kill -STOP 2262828 $ strace -f ./t [...] --- SIGSTOP {si_signo=SIGSTOP, si_code=SI_USER, si_pid=2521813, si_uid=8289} --- --- stopped by SIGSTOP --- And then $ kill -CONT 2262828 Results in: --- SIGCONT {si_signo=SIGCONT, si_code=SI_USER, si_pid=2521813, si_uid=8289} --- restart_syscall(<... resuming interrupted ppoll ...>) = -1 EINTR (Interrupted system call) Where the expected behaviour would be: $ strace -f ./t [...] ppoll(NULL, 0, NULL, NULL, 0) = ? ERESTARTNOHAND (To be restarted if no handler) --- SIGSTOP {si_signo=SIGSTOP, si_code=SI_USER, si_pid=2521813, si_uid=8289} --- --- stopped by SIGSTOP --- --- SIGCONT {si_signo=SIGCONT, si_code=SI_USER, si_pid=2521813, si_uid=8289} --- ppoll(NULL, 0, NULL, NULL, 0 Just moving the 'g1' setting near the syscall asm is not suffice, the compiler might optimize it away (as I saw on cancellation.c by trying this fix). Instead, I have change the inline asm to put the 'g1' setup in ithe asm block. This would require to change the asm constraint for INTERNAL_SYSCALL_NCS, since the syscall number is not constant. Checked on sparc64-linux-gnu. Reported-by: René Rebe Tested-by: Sam James --- sysdeps/unix/sysv/linux/Makefile | 1 + .../sysv/linux/sparc/sparc32/syscall_cancel.S | 4 +- .../unix/sysv/linux/sparc/sparc32/sysdep.h | 3 +- .../sysv/linux/sparc/sparc64/syscall_cancel.S | 4 +- .../unix/sysv/linux/sparc/sparc64/sysdep.h | 3 +- sysdeps/unix/sysv/linux/sparc/sysdep.h | 74 +++++++----- sysdeps/unix/sysv/linux/tst-syscall-restart.c | 112 ++++++++++++++++++ 7 files changed, 165 insertions(+), 36 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/tst-syscall-restart.c diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 7df51a325c..527c7a5ae8 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -230,6 +230,7 @@ tests += \ tst-scm_rights \ tst-sigtimedwait \ tst-sync_file_range \ + tst-syscall-restart \ tst-sysconf-iov_max \ tst-sysvmsg-linux \ tst-sysvsem-linux \ diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/syscall_cancel.S b/sysdeps/unix/sysv/linux/sparc/sparc32/syscall_cancel.S index aa5c658ce1..20f665d861 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/syscall_cancel.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/syscall_cancel.S @@ -44,13 +44,13 @@ __syscall_cancel_arch_start: andcc %g2, TCB_CANCELED_BITMASK, %g0 bne,pn %icc, 2f /* Issue a 6 argument syscall. */ - mov %i1, %g1 - mov %i2, %o0 + mov %i2, %o0 mov %i3, %o1 mov %i4, %o2 mov %i5, %o3 ld [%fp+92], %o4 ld [%fp+96], %o5 + mov %i1, %g1 ta 0x10 .globl __syscall_cancel_arch_end diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h index d2d68f5312..c2ffbb5c8f 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h @@ -107,6 +107,7 @@ ENTRY(name); \ #else /* __ASSEMBLER__ */ #define __SYSCALL_STRING \ + "mov %[scn], %%g1;" \ "ta 0x10;" \ "bcc 1f;" \ " nop;" \ @@ -114,7 +115,7 @@ ENTRY(name); \ "1:" #define __SYSCALL_CLOBBERS \ - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ + "g1", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \ diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/syscall_cancel.S b/sysdeps/unix/sysv/linux/sparc/sparc64/syscall_cancel.S index 21b0728d5a..6c8d1330cb 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/syscall_cancel.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/syscall_cancel.S @@ -46,13 +46,13 @@ __syscall_cancel_arch_start: andcc %g2, TCB_CANCELED_BITMASK, %g0 bne,pn %xcc, 2f /* Issue a 6 argument syscall. */ - mov %i1, %g1 - mov %i2, %o0 + mov %i2, %o0 mov %i3, %o1 mov %i4, %o2 mov %i5, %o3 ldx [%fp + STACK_BIAS + 176], %o4 ldx [%fp + STACK_BIAS + 184], %o5 + mov %i1, %g1 ta 0x6d .global __syscall_cancel_arch_end diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h index 96047424e9..5598fab08a 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h @@ -106,6 +106,7 @@ ENTRY(name); \ #else /* __ASSEMBLER__ */ #define __SYSCALL_STRING \ + "mov %[scn], %%g1;" \ "ta 0x6d;" \ "bcc,pt %%xcc, 1f;" \ " nop;" \ @@ -113,7 +114,7 @@ ENTRY(name); \ "1:" #define __SYSCALL_CLOBBERS \ - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ + "g1", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \ diff --git a/sysdeps/unix/sysv/linux/sparc/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sysdep.h index dcabb57fe2..c287740a8c 100644 --- a/sysdeps/unix/sysv/linux/sparc/sysdep.h +++ b/sysdeps/unix/sysv/linux/sparc/sysdep.h @@ -50,97 +50,109 @@ #undef INTERNAL_SYSCALL_NCS #define INTERNAL_SYSCALL_NCS(name, nr, args...) \ - internal_syscall##nr(__SYSCALL_STRING, name, args) + _internal_syscall##nr(__SYSCALL_STRING, "p", name, args) -#define internal_syscall0(string,name,dummy...) \ +#define _internal_syscall0(string,nc,name,dummy...) \ ({ \ - register long int __g1 __asm__ ("g1") = (name); \ register long __o0 __asm__ ("o0"); \ + long int _name = (long int) (name); \ __asm __volatile (string : "=r" (__o0) : \ - "r" (__g1) : \ + [scn] nc (_name) : \ __SYSCALL_CLOBBERS); \ __o0; \ }) +#define internal_syscall0(string,name,args...) \ + _internal_syscall0(string, "i", name, args) -#define internal_syscall1(string,name,arg1) \ +#define _internal_syscall1(string,nc,name,arg1) \ ({ \ long int _arg1 = (long int) (arg1); \ - register long int __g1 __asm__("g1") = (name); \ + long int _name = (long int) (name); \ register long int __o0 __asm__ ("o0") = _arg1; \ - __asm __volatile (string : "=r" (__o0) : \ - "r" (__g1), "0" (__o0) : \ + __asm __volatile (string : "+r" (__o0) : \ + [scn] nc (_name) : \ __SYSCALL_CLOBBERS); \ __o0; \ }) +#define internal_syscall1(string,name,args...) \ + _internal_syscall1(string, "i", name, args) -#define internal_syscall2(string,name,arg1,arg2) \ +#define _internal_syscall2(string,nc,name,arg1,arg2) \ ({ \ long int _arg1 = (long int) (arg1); \ long int _arg2 = (long int) (arg2); \ - register long int __g1 __asm__("g1") = (name); \ + long int _name = (long int) (name); \ register long int __o0 __asm__ ("o0") = _arg1; \ register long int __o1 __asm__ ("o1") = _arg2; \ - __asm __volatile (string : "=r" (__o0) : \ - "r" (__g1), "0" (__o0), "r" (__o1) : \ + __asm __volatile (string : "+r" (__o0) : \ + [scn] nc (_name), "r" (__o1) : \ __SYSCALL_CLOBBERS); \ __o0; \ }) +#define internal_syscall2(string,name,args...) \ + _internal_syscall2(string, "i", name, args) -#define internal_syscall3(string,name,arg1,arg2,arg3) \ +#define _internal_syscall3(string,nc,name,arg1,arg2,arg3) \ ({ \ long int _arg1 = (long int) (arg1); \ long int _arg2 = (long int) (arg2); \ long int _arg3 = (long int) (arg3); \ - register long int __g1 __asm__("g1") = (name); \ + long int _name = (long int) (name); \ register long int __o0 __asm__ ("o0") = _arg1; \ register long int __o1 __asm__ ("o1") = _arg2; \ register long int __o2 __asm__ ("o2") = _arg3; \ - __asm __volatile (string : "=r" (__o0) : \ - "r" (__g1), "0" (__o0), "r" (__o1), \ + __asm __volatile (string : "+r" (__o0) : \ + [scn] nc (_name), "r" (__o1), \ "r" (__o2) : \ __SYSCALL_CLOBBERS); \ __o0; \ }) +#define internal_syscall3(string,name,args...) \ + _internal_syscall3(string, "i", name, args) -#define internal_syscall4(string,name,arg1,arg2,arg3,arg4) \ +#define _internal_syscall4(string,nc,name,arg1,arg2,arg3,arg4) \ ({ \ long int _arg1 = (long int) (arg1); \ long int _arg2 = (long int) (arg2); \ long int _arg3 = (long int) (arg3); \ long int _arg4 = (long int) (arg4); \ - register long int __g1 __asm__("g1") = (name); \ + long int _name = (long int) (name); \ register long int __o0 __asm__ ("o0") = _arg1; \ register long int __o1 __asm__ ("o1") = _arg2; \ register long int __o2 __asm__ ("o2") = _arg3; \ register long int __o3 __asm__ ("o3") = _arg4; \ - __asm __volatile (string : "=r" (__o0) : \ - "r" (__g1), "0" (__o0), "r" (__o1), \ + __asm __volatile (string : "+r" (__o0) : \ + [scn] nc (_name), "r" (__o1), \ "r" (__o2), "r" (__o3) : \ __SYSCALL_CLOBBERS); \ __o0; \ }) +#define internal_syscall4(string,name,args...) \ + _internal_syscall4(string, "i", name, args) -#define internal_syscall5(string,name,arg1,arg2,arg3,arg4,arg5) \ +#define _internal_syscall5(string,nc,name,arg1,arg2,arg3,arg4,arg5) \ ({ \ long int _arg1 = (long int) (arg1); \ long int _arg2 = (long int) (arg2); \ long int _arg3 = (long int) (arg3); \ long int _arg4 = (long int) (arg4); \ long int _arg5 = (long int) (arg5); \ - register long int __g1 __asm__("g1") = (name); \ + long int _name = (long int) (name); \ register long int __o0 __asm__ ("o0") = _arg1; \ register long int __o1 __asm__ ("o1") = _arg2; \ register long int __o2 __asm__ ("o2") = _arg3; \ register long int __o3 __asm__ ("o3") = _arg4; \ register long int __o4 __asm__ ("o4") = _arg5; \ - __asm __volatile (string : "=r" (__o0) : \ - "r" (__g1), "0" (__o0), "r" (__o1), \ + __asm __volatile (string : "+r" (__o0) : \ + [scn] nc (_name), "r" (__o1), \ "r" (__o2), "r" (__o3), "r" (__o4) : \ __SYSCALL_CLOBBERS); \ __o0; \ }) +#define internal_syscall5(string,name,args...) \ + _internal_syscall5(string, "i", name, args) -#define internal_syscall6(string,name,arg1,arg2,arg3,arg4,arg5,arg6) \ +#define _internal_syscall6(string,nc,name,arg1,arg2,arg3,arg4,arg5,arg6)\ ({ \ long int _arg1 = (long int) (arg1); \ long int _arg2 = (long int) (arg2); \ @@ -148,20 +160,22 @@ long int _arg4 = (long int) (arg4); \ long int _arg5 = (long int) (arg5); \ long int _arg6 = (long int) (arg6); \ - register long int __g1 __asm__("g1") = (name); \ + long int _name = (long int) (name); \ register long int __o0 __asm__ ("o0") = _arg1; \ register long int __o1 __asm__ ("o1") = _arg2; \ register long int __o2 __asm__ ("o2") = _arg3; \ register long int __o3 __asm__ ("o3") = _arg4; \ register long int __o4 __asm__ ("o4") = _arg5; \ register long int __o5 __asm__ ("o5") = _arg6; \ - __asm __volatile (string : "=r" (__o0) : \ - "r" (__g1), "0" (__o0), "r" (__o1), \ + __asm __volatile (string : "+r" (__o0) : \ + [scn] nc (_name), "r" (__o1), \ "r" (__o2), "r" (__o3), "r" (__o4), \ "r" (__o5) : \ __SYSCALL_CLOBBERS); \ __o0; \ }) +#define internal_syscall6(string,name,args...) \ + _internal_syscall6(string, "i", name, args) #define INLINE_CLONE_SYSCALL(arg1,arg2,arg3,arg4,arg5) \ ({ \ @@ -170,15 +184,15 @@ long int _arg3 = (long int) (arg3); \ long int _arg4 = (long int) (arg4); \ long int _arg5 = (long int) (arg5); \ + long int _name = __NR_clone; \ register long int __o0 __asm__ ("o0") = _arg1; \ register long int __o1 __asm__ ("o1") = _arg2; \ register long int __o2 __asm__ ("o2") = _arg3; \ register long int __o3 __asm__ ("o3") = _arg4; \ register long int __o4 __asm__ ("o4") = _arg5; \ - register long int __g1 __asm__ ("g1") = __NR_clone; \ __asm __volatile (__SYSCALL_STRING : \ "=r" (__o0), "=r" (__o1) : \ - "r" (__g1), "0" (__o0), "1" (__o1), \ + [scn] "i" (_name), "0" (__o0), "1" (__o1), \ "r" (__o2), "r" (__o3), "r" (__o4) : \ __SYSCALL_CLOBBERS); \ if (__glibc_unlikely ((unsigned long int) (__o0) > -4096UL)) \ diff --git a/sysdeps/unix/sysv/linux/tst-syscall-restart.c b/sysdeps/unix/sysv/linux/tst-syscall-restart.c new file mode 100644 index 0000000000..f18443abe3 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-syscall-restart.c @@ -0,0 +1,112 @@ +/* Test if a syscall is correctly restarted. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include +#include + +static int +check_pid (pid_t pid) +{ + /* Wait until child has called pause and it blocking on kernel. */ + support_process_state_wait (pid, support_process_state_sleeping); + + TEST_COMPARE (kill (pid, SIGSTOP), 0); + + /* Adding process_state_tracing_stop ('t') allows the test to work under + trace programs such as ptrace. */ + support_process_state_wait (pid, support_process_state_stopped + | support_process_state_tracing_stop); + + TEST_COMPARE (kill (pid, SIGCONT), 0); + + enum support_process_state state + = support_process_state_wait (pid, support_process_state_sleeping + | support_process_state_zombie); + + TEST_COMPARE (state, support_process_state_sleeping); + + TEST_COMPARE (kill (pid, SIGTERM), 0); + + siginfo_t info; + TEST_COMPARE (waitid (P_PID, pid, &info, WEXITED), 0); + TEST_COMPARE (info.si_signo, SIGCHLD); + TEST_COMPARE (info.si_code, CLD_KILLED); + TEST_COMPARE (info.si_status, SIGTERM); + TEST_COMPARE (info.si_pid, pid); + + return 0; +} + +static void * +tf (void *) +{ + pause (); + return NULL; +} + +static void +child_mt (void) +{ + /* Let only the created thread to handle signals. */ + sigset_t set; + sigfillset (&set); + xpthread_sigmask (SIG_BLOCK, &set, NULL); + + sigdelset (&set, SIGSTOP); + sigdelset (&set, SIGCONT); + sigdelset (&set, SIGTERM); + + pthread_attr_t attr; + xpthread_attr_init (&attr); + TEST_COMPARE (pthread_attr_setsigmask_np (&attr, &set), 0); + + xpthread_join (xpthread_create (&attr, tf, NULL)); +} + +static void +do_test_syscall (bool multithread) +{ + pid_t pid = xfork (); + if (pid == 0) + { + if (multithread) + child_mt (); + else + pause (); + _exit (127); + } + + check_pid (pid); +} + +static int +do_test (void) +{ + /* Check for both single and multi thread, since they use different syscall + mechanisms. */ + do_test_syscall (false); + do_test_syscall (true); + + return 0; +} + +#include