From patchwork Wed Sep 11 21:04:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Isaku Yamahata X-Patchwork-Id: 1161284 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-105154-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="eBMWVkoA"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="c9Bxq1g1"; 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 46TDwP4F6Pz9s00 for ; Thu, 12 Sep 2019 07:06:29 +1000 (AEST) 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:in-reply-to :references:in-reply-to:references; q=dns; s=default; b=VPx5pUXD R5ks5157G9uSkK+jVVBKxBLQWKRFe99c+yZKgddbRfbmInU8Sf0e36G3biyYcmcc 95pcQTGA0I5GzgRu4fTvrr3WRW36gWQPEd4NuG4wFKcJzs0TmcRSIu3RHhygBz4N io4eaCYoJvPnm1bDteF3b6nTQdUjqtGjbnE= 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:in-reply-to :references:in-reply-to:references; s=default; bh=/AAZLrYzLI9dz7 uxeE7+VUhql+w=; b=eBMWVkoA4Q1q67NE/xQkyvsWg88lldnRCU5NsXEX7/wfFs cA6NTrCnqF0vlhSogKOVIr+xtgfOWVlJ63SBFf2436ZAxKwodnvipyrucZ7v7yDC YAFVAa6qODOQC4Ji6qZ0ff2T5Yv7j+k9JZdl3YtNfWYIrBSWe8gQeELTy+Yc0= Received: (qmail 95819 invoked by alias); 11 Sep 2019 21:05:22 -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 95702 invoked by uid 89); 11 Sep 2019 21:05:21 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.0 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=challenges, difficulties X-HELO: mail-pf1-f193.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=GB20bNAZ9mR00f/034bfGfBhR1qOOeAefW9zqzirPRc=; b=c9Bxq1g1xHJE0QGhHYPzresUHznaRC8Azo3muptzmcDl959piPSVxrTmmA2fDwnUYE c+4jBSlRtWSOgWlLkBBshnzheXif73Er3+bBRdY5xuB6fMLnHgJMl7jVThLqXo+XSHs7 Mf3UYZ89LVtgBipzMiMyz40xXw99gBOvEgkRHxTG8S/hadxYggQus5EfLZpxpvR37O74 tl7P6mIHp4K3Cu4jQeL8RT/3Sy8sCY0u5Aah6xyH/WdbMipEouAg+n1/ctkqnEEVAUwb F/OggsFdtNstKNbzEweQpXifV5kZ+eRA+NvCvaFqmfBiQk4j5CTTYUdamTLEJF4Q4aEP x8OQ== From: Isaku Yamahata To: libc-alpha@sourceware.org Cc: isaku.yamahata@intel.com, Isaku Yamahata Subject: [RFC PATCH 09/11] x86-64: add nop instruction after syscall instrunction Date: Wed, 11 Sep 2019 14:04:07 -0700 Message-Id: <48e2b8f06d60dbc03b58d44e02af36baa003b952.1568219400.git.isaku.yamahata@gmail.com> In-Reply-To: References: In-Reply-To: References: This patch replaces syscall instruction with syscall + nops with annotation. The impact on traditional runtime is, extra nops and list of syscall instruction. LibOS hooks system call and redirects the control to it so that it can handle system call instead of kernel. The fallback way is trap-and-emulate(e.g. by SIGSYS, SIGILL), but it's slow. As optimization syscall instruction is replaced somehow. The approach can vary among LibOSes. The common challenges are a) identify syscall instruction and b) replace syscall with instruction sequence. x86-64 instruction has variable length and syscall instruciton has 2 bytes. On the other hand 4 byte call/jump requires 5 bytes which imposes difficulties. (If 8 bytes absolute address jump is wanted, more space is needed.) This patch create a list of syscall instructions and adds nops after syscall instruction to keep enough room for binary editing without fragile complex tricks. The assumed instruction sequence to replace syscall instrction is as follows. But LibOSes can do whatever they want. Notice that Linux x86-64 syscall ABI is stricter than normal function call convention. (%rcx, %r11 clobbered, %rflags preserved, redzone can't be used.) If we can relax it, those snippets can be optimized/shortened. Actually almost all the callers of syscall instruction allow the use of redzone, %rflags clobbered. For now those sequence is chosen to minimize glibc impact. syscall sequence: > syscall > nop; nop; ... (add enough room for binary editing) replacing sequence: > leaq 1f(%rip), %rcx > jmp syscall_func > 1f: > > 48 8d 0d 06 00 00 00 leaq 0x6(%rip),%rcx > e9 00 00 00 00 jmpq 0x79 > R_X86_64_PC32 syscall_func-0x4 the callee function looks something like this. save %rflags, reserve redzone and call LibOS entry point, restore redzone, restore %rflags and jump back to the caller. > syscall_func: > xchgq %r11, -8(%rsp) > pushfq > xchgq %r11, (%rsp) > subq $120, %rsp > pushq %r11 > pushq %rcx > callq > popq %rcx > popq %r11 > addq $120, %rsp > xchgq %r11, (%rsp) > popfq > xchgq %r11, -8(%rsp) > jmpq *%rcx Signed-off-by: Isaku Yamahata --- sysdeps/unix/sysv/linux/x86_64/sysdep.h | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h index 4f1aab7209..d958c1ca7a 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h +++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h @@ -27,9 +27,28 @@ #include #ifdef __ASSEMBLER__ -# define SYSCALL_INST syscall +.macro SYSCALL_INST + 551: + syscall + nop;nop;nop;nop;nop;nop;nop;nop;nop;nop + 552: + .pushsection .libos.instructions.syscall, "a" + .balign 8 + .quad 551b + .byte 552b - 551b + .popsection +.endm #else -# define SYSCALL_INST "syscall\n\t" +#define SYSCALL_INST \ + "551:\n\t" \ + "syscall\n\t" \ + "nop;nop;nop;nop;nop;nop;nop;nop;nop;nop\n\t" \ + "552:\n\t" \ + ".pushsection .libos.instructions.syscall, \"a\"\n\t" \ + ".balign 8\n\t" \ + ".quad 551b\n\t" \ + ".byte 552b-551b\n\t" \ + ".popsection\n\t" #endif /* For Linux we can use the system call table in the header file