From patchwork Thu Jan 11 19:27:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tulio Magno Quites Machado Filho X-Patchwork-Id: 859268 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-89107-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="fLGFCAqB"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zHbqR3pfNz9s4q for ; Fri, 12 Jan 2018 06:41:55 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id; q=dns; s= default; b=Jz1kQ9GsjR6WFCEnNsHO0L/fvWgIsCVc5igcw13iKmOcMgi+DlhvG NbTI3FeXWNi+S6tNWpdHcWbFuCTCJYDLkDCpL5MtZThP3c2aYWGlCUjy6eaDwtAM aM9yHDAEVm/No+Zq/qNLEx9tdQDQiQolv3+ttTtFvcLlOvJxOCyJr8= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id; s=default; bh=30ZsrRonrgQlC9zcEo4zRFQaNtQ=; b=fLGFCAqBs+h+7x/lIItsE2/hkOe4 4zqSNGMpeni2JC4T2e+UZEa0McfX+8eaaid9/Sg4mQyaxGzwVVLW8j1iUoBkBewl AxzavZQFAhW6f5jeor28WM9KJ4eI7ptmUcMxQu5OlDMBMg7yoEl5Ix5nQUzHg4C5 Lt/6YYMqxSmYNr8= Received: (qmail 92706 invoked by alias); 11 Jan 2018 19:41:43 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 92691 invoked by uid 89); 11 Jan 2018 19:41:43 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy=sk:INTERNA X-HELO: mx0a-001b2d01.pphosted.com From: "Tulio Magno Quites Machado Filho" To: libc-alpha@sourceware.org Cc: aurelien@aurel32.net Subject: [PATCH] powerpc: Fix syscalls during early process initialization [BZ #22685] Date: Thu, 11 Jan 2018 17:27:50 -0200 X-TM-AS-GCONF: 00 x-cbid: 18011119-0024-0000-0000-000017C74260 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00008361; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000245; SDB=6.00973584; UDB=6.00493321; IPR=6.00753529; BA=6.00005773; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00018984; XFM=3.00000015; UTC=2018-01-11 19:41:37 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18011119-0025-0000-0000-00004E40A50D Message-Id: <20180111192750.6256-1-tuliom@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2018-01-11_06:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1801110268 The tunables framework needs to make syscall early during process initialization, before the TCB is available for consumption. This behavior conflicts with powerpc{|64|64le}'s lock elision code, that tries to abort transactions before a syscall when lock elision is available and enabled. This patch adds the macro EARLY_INTERNAL_SYSCALL in order to let early syscalls happen without depending on the TCB initialization for powerpc{|64|64le}. Other architectures are redirected to INTERNAL_SYSCALL. Tested on powerpc{|64|64le}, s390x and x86_64. 2018-01-11 Tulio Magno Quites Machado Filho [BZ #22685] * sysdeps/unix/sysdep.h (__EARLY_INTERNAL_SYSCALL0, __EARLY_INTERNAL_SYSCALL1, __EARLY_INTERNAL_SYSCALL2, __EARLY_INTERNAL_SYSCALL3, __EARLY_INTERNAL_SYSCALL4, __EARLY_INTERNAL_SYSCALL5, __EARLY_INTERNAL_SYSCALL6, __EARLY_INTERNAL_SYSCALL7, EARLY_INTERNAL_SYSCALL_CALL): New macros (EARLY_INTERNAL_SYSCALL): New macro. Redirect to INTERNAL_SYSCALL by default. * sysdeps/unix/sysv/linux/not-errno.h (__access_noerrno): Replace INTERNAL_SYSCALL_CALL with EARLY_INTERNAL_SYSCALL_CALL. * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h (EARLY_INTERNAL_SYSCALL_NCS, EARLY_INTERNAL_SYSCALL): New macros. * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h (EARLY_INTERNAL_SYSCALL_NCS, EARLY_INTERNAL_SYSCALL): Likewise. Signed-off-by: Tulio Magno Quites Machado Filho Tested-by: Aurelien Jarno --- sysdeps/unix/sysdep.h | 25 +++++++++++++++ sysdeps/unix/sysv/linux/not-errno.h | 4 +-- sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h | 36 +++++++++++++++++++++- sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h | 34 +++++++++++++++++++- 4 files changed, 95 insertions(+), 4 deletions(-) diff --git a/sysdeps/unix/sysdep.h b/sysdeps/unix/sysdep.h index aac9303..689272e 100644 --- a/sysdeps/unix/sysdep.h +++ b/sysdeps/unix/sysdep.h @@ -57,6 +57,31 @@ #define INTERNAL_SYSCALL_CALL(...) \ __INTERNAL_SYSCALL_DISP (__INTERNAL_SYSCALL, __VA_ARGS__) +#define __EARLY_INTERNAL_SYSCALL0(name, err) \ + EARLY_INTERNAL_SYSCALL (name, err, 0) +#define __EARLY_INTERNAL_SYSCALL1(name, err, a1) \ + EARLY_INTERNAL_SYSCALL (name, err, 1, a1) +#define __EARLY_INTERNAL_SYSCALL2(name, err, a1, a2) \ + EARLY_INTERNAL_SYSCALL (name, err, 2, a1, a2) +#define __EARLY_INTERNAL_SYSCALL3(name, err, a1, a2, a3) \ + EARLY_INTERNAL_SYSCALL (name, err, 3, a1, a2, a3) +#define __EARLY_INTERNAL_SYSCALL4(name, err, a1, a2, a3, a4) \ + EARLY_INTERNAL_SYSCALL (name, err, 4, a1, a2, a3, a4) +#define __EARLY_INTERNAL_SYSCALL5(name, err, a1, a2, a3, a4, a5) \ + EARLY_INTERNAL_SYSCALL (name, err, 5, a1, a2, a3, a4, a5) +#define __EARLY_INTERNAL_SYSCALL6(name, err, a1, a2, a3, a4, a5, a6) \ + EARLY_INTERNAL_SYSCALL (name, err, 6, a1, a2, a3, a4, a5, a6) +#define __EARLY_INTERNAL_SYSCALL7(name, err, a1, a2, a3, a4, a5, a6, a7) \ + EARLY_INTERNAL_SYSCALL (name, err, 7, a1, a2, a3, a4, a5, a6, a7) + +/* It is similar to INTERNAL_SYSCALL_CALL, but it is reserved to system calls + during process initialization, when internal structures may not be + available, e.g. TCB on powerpc. */ +#define EARLY_INTERNAL_SYSCALL_CALL(...) \ + __INTERNAL_SYSCALL_DISP (__EARLY_INTERNAL_SYSCALL, __VA_ARGS__) +#define EARLY_INTERNAL_SYSCALL(name, err, nr, args...) \ + INTERNAL_SYSCALL (name, err, nr, args) + #define __INLINE_SYSCALL0(name) \ INLINE_SYSCALL (name, 0) #define __INLINE_SYSCALL1(name, a1) \ diff --git a/sysdeps/unix/sysv/linux/not-errno.h b/sysdeps/unix/sysv/linux/not-errno.h index 106ba5c..a033b7b 100644 --- a/sysdeps/unix/sysv/linux/not-errno.h +++ b/sysdeps/unix/sysv/linux/not-errno.h @@ -25,9 +25,9 @@ __access_noerrno (const char *pathname, int mode) int res; INTERNAL_SYSCALL_DECL (err); #ifdef __NR_access - res = INTERNAL_SYSCALL_CALL (access, err, pathname, mode); + res = EARLY_INTERNAL_SYSCALL_CALL (access, err, pathname, mode); #else - res = INTERNAL_SYSCALL_CALL (faccessat, err, AT_FDCWD, pathname, mode); + res = EARLY_INTERNAL_SYSCALL_CALL (faccessat, err, AT_FDCWD, pathname, mode); #endif if (INTERNAL_SYSCALL_ERROR_P (res, err)) return INTERNAL_SYSCALL_ERRNO (res, err); diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h index f7277d5..efc6cbc 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h @@ -89,7 +89,10 @@ On powerpc a system call basically clobbers the same registers like a function call, with the exception of LR (which is needed for the "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal - an error return status). */ + an error return status). + + Notice it requires the TCB to be allocated and completely set in order to + abort transactions before the syscall. */ # undef INTERNAL_SYSCALL_DECL # define INTERNAL_SYSCALL_DECL(err) long int err __attribute__ ((unused)) @@ -124,6 +127,37 @@ # define INTERNAL_SYSCALL(name, err, nr, args...) \ INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args) +/* Similar to INTERNAL_SYSCALL, but reserved to early process initialization + without requiring the TCB to allocated and completely set. */ +# undef EARLY_INTERNAL_SYSCALL +# define EARLY_INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ + ({ \ + register long int r0 __asm__ ("r0"); \ + register long int r3 __asm__ ("r3"); \ + register long int r4 __asm__ ("r4"); \ + register long int r5 __asm__ ("r5"); \ + register long int r6 __asm__ ("r6"); \ + register long int r7 __asm__ ("r7"); \ + register long int r8 __asm__ ("r8"); \ + register long int r9 __asm__ ("r9"); \ + register long int r10 __asm__ ("r10"); \ + register long int r11 __asm__ ("r11"); \ + register long int r12 __asm__ ("r12"); \ + LOADARGS_##nr(name, args); \ + __asm__ __volatile__ \ + ("sc \n\t" \ + "mfcr %0" \ + : "=&r" (r0), \ + "=&r" (r3), "=&r" (r4), "=&r" (r5), "=&r" (r6), "=&r" (r7), \ + "=&r" (r8), "=&r" (r9), "=&r" (r10), "=&r" (r11), "=&r" (r12) \ + : ASM_INPUT_##nr \ + : "cr0", "ctr", "memory"); \ + err = r0; \ + (int) r3; \ + }) +# define EARLY_INTERNAL_SYSCALL(name, err, nr, args...) \ + EARLY_INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args) + # undef INTERNAL_SYSCALL_ERROR_P # define INTERNAL_SYSCALL_ERROR_P(val, err) \ ((void) (val), __builtin_expect ((err) & (1 << 28), 0)) diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h index 0fc179a..d431fdb 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h @@ -118,7 +118,10 @@ call. This use is for internal calls that do not need to handle errors normally. It will never touch errno. This returns just what the kernel gave back in the non-error (CR0.SO cleared) case, otherwise (CR0.SO set) - the negation of the return value in the kernel gets reverted. */ + the negation of the return value in the kernel gets reverted. + + Notice it requires the TCB to be allocated and completely set in order to + abort transactions before the syscall. */ #undef INTERNAL_SYSCALL #define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ @@ -148,6 +151,35 @@ #define INTERNAL_SYSCALL(name, err, nr, args...) \ INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, args) +/* Similar to INTERNAL_SYSCALL, but reserved to early process initialization + without requiring the TCB to allocated and completely set. */ +#undef EARLY_INTERNAL_SYSCALL +#define EARLY_INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ + ({ \ + register long int r0 __asm__ ("r0"); \ + register long int r3 __asm__ ("r3"); \ + register long int r4 __asm__ ("r4"); \ + register long int r5 __asm__ ("r5"); \ + register long int r6 __asm__ ("r6"); \ + register long int r7 __asm__ ("r7"); \ + register long int r8 __asm__ ("r8"); \ + LOADARGS_##nr (name, ##args); \ + __asm__ __volatile__ \ + ("sc\n\t" \ + "mfcr %0\n\t" \ + "0:" \ + : "=&r" (r0), \ + "=&r" (r3), "=&r" (r4), "=&r" (r5), \ + "=&r" (r6), "=&r" (r7), "=&r" (r8) \ + : ASM_INPUT_##nr \ + : "r9", "r10", "r11", "r12", \ + "cr0", "ctr", "memory"); \ + err = r0; \ + r3; \ + }) +#define EARLY_INTERNAL_SYSCALL(name, err, nr, args...) \ + EARLY_INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, args) + #undef INTERNAL_SYSCALL_DECL #define INTERNAL_SYSCALL_DECL(err) long int err __attribute__ ((unused))