From patchwork Tue Aug 30 14:27:23 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 74991 Delivered-To: patch@linaro.org Received: by 10.140.29.52 with SMTP id a49csp2178507qga; Tue, 30 Aug 2016 07:27:45 -0700 (PDT) X-Received: by 10.98.27.11 with SMTP id b11mr6748180pfb.111.1472567261922; Tue, 30 Aug 2016 07:27:41 -0700 (PDT) Return-Path: Received: from ml01.01.org (ml01.01.org. [2001:19d0:306:5::1]) by mx.google.com with ESMTPS id n4si45383742pan.58.2016.08.30.07.27.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 30 Aug 2016 07:27:41 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) client-ip=2001:19d0:306:5::1; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 482591A1E2F; Tue, 30 Aug 2016 07:27:41 -0700 (PDT) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-wm0-x230.google.com (mail-wm0-x230.google.com [IPv6:2a00:1450:400c:c09::230]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 5E83C1A1E01 for ; Tue, 30 Aug 2016 07:27:38 -0700 (PDT) Received: by mail-wm0-x230.google.com with SMTP id o80so39080814wme.1 for ; Tue, 30 Aug 2016 07:27:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=hDaiZSn3uPejxOubAk88M7WwvW3NhfMzR6CtXd/TkIw=; b=NvT5MKc9P8K4kSYAtEWZU3mBl75gtYZ+bhFirunTRrv1SgeLMfQMZukJ2UCtAFCSyJ O5Z/Qse9eFKb+R7c5CDaCTIAFPWeHe2ZEL4kjzJjUjSH9zTe961UrQxyzszeAalemJJ6 SsKHUw0RWUcNjm66JO5oijsPi3Zk0/xFn3TQI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=hDaiZSn3uPejxOubAk88M7WwvW3NhfMzR6CtXd/TkIw=; b=dRbPxfO3Cq8ibSt5RZzcCA4WtqkZi/F8kPFtLQqHXr6OR94Cf+0SvnmVWcG5fgD94p TL7FmBU6GT9mD5z9QxFj3LRWvMiglhewHKWBQJh0CgdCOQDlqfVhTo5AT/xMMZY2iSbJ 8YXOWK8NNM0Dmfoj0LVjNseTqUF+n4eJO/jQY4NoFSZ+/YFsSbTQZnXhQBdeDOraZmDe 8VsHcIxhrad5VLQoH4zRA3hU8XW3fhBZX7cuuRjOFXZ3nwjQgGsf3yUnUDrHowyJoJbr 29gZ+XMbfgDy4ngbSWpKqpq8ixU7iYHrQEutigddSjW8RR2xCsu4/jJSY05h6JmlQQbg vZMw== X-Gm-Message-State: AE9vXwNMzf7rpXJjUFoThGtVuu0BGTtpzvg5/SaeMWvdDO4TJ7P5S5JWlNJYRy/HKjNNQ6aN X-Received: by 10.194.200.36 with SMTP id jp4mr4073423wjc.26.1472567256656; Tue, 30 Aug 2016 07:27:36 -0700 (PDT) Received: from localhost.localdomain ([160.165.12.73]) by smtp.gmail.com with ESMTPSA id us9sm39773620wjb.43.2016.08.30.07.27.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 30 Aug 2016 07:27:36 -0700 (PDT) From: Ard Biesheuvel To: edk2-devel@lists.01.org, leif.lindholm@linaro.org Date: Tue, 30 Aug 2016 15:27:23 +0100 Message-Id: <1472567244-32031-4-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1472567244-32031-1-git-send-email-ard.biesheuvel@linaro.org> References: <1472567244-32031-1-git-send-email-ard.biesheuvel@linaro.org> Subject: [edk2] [PATCH v4 3/4] MdeModulePkg/EbxDxe AARCH64: use tail call for EBC to native thunk X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Ard Biesheuvel MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" Instead of pessimistically copying at least 64 bytes from the VM stack to the native stack, and popping off the register arguments again before doing the native call, try to avoid touching the stack completely if the VM stack frame is <= 64 bytes. Also, if the stack frame does exceed 64 bytes, there is no need to copy the first 64 bytes, since we are passing those in registers anyway. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel --- MdeModulePkg/Universal/EbcDxe/AArch64/EbcLowLevel.S | 85 +++++++++++++++----- 1 file changed, 65 insertions(+), 20 deletions(-) -- 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel Reviewed-by: Leif Lindholm diff --git a/MdeModulePkg/Universal/EbcDxe/AArch64/EbcLowLevel.S b/MdeModulePkg/Universal/EbcDxe/AArch64/EbcLowLevel.S index b4b8531f1a01..34794c06a644 100644 --- a/MdeModulePkg/Universal/EbcDxe/AArch64/EbcLowLevel.S +++ b/MdeModulePkg/Universal/EbcDxe/AArch64/EbcLowLevel.S @@ -35,30 +35,75 @@ ASM_GLOBAL ASM_PFX(mEbcInstructionBufferTemplate) //**************************************************************************** // UINTN EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr) ASM_PFX(EbcLLCALLEXNative): - stp x19, x20, [sp, #-16]! - stp x29, x30, [sp, #-16]! + mov x8, x0 // Preserve x0 + mov x9, x1 // Preserve x1 - mov x19, x0 - mov x20, sp - sub x2, x2, x1 // Length = NewStackPointer-FramePtr - sub sp, sp, x2 - sub sp, sp, #64 // Make sure there is room for at least 8 args in the new stack - mov x0, sp - - bl CopyMem // Sp, NewStackPointer, Length - - ldp x0, x1, [sp], #16 - ldp x2, x3, [sp], #16 - ldp x4, x5, [sp], #16 - ldp x6, x7, [sp], #16 + // + // If the EBC stack frame is smaller than or equal to 64 bytes, we know there + // are no stacked arguments #9 and beyond that we need to copy to the native + // stack. In this case, we can perform a tail call which is much more + // efficient, since there is no need to touch the native stack at all. + // + sub x3, x2, x1 // Length = NewStackPointer - FramePtr + cmp x3, #64 + b.gt 1f - blr x19 + // + // While probably harmless in practice, we should not access the VM stack + // outside of the interval [NewStackPointer, FramePtr), which means we + // should not blindly fill all 8 argument registers with VM stack data. + // So instead, calculate how many argument registers we can fill based on + // the size of the VM stack frame, and skip the remaining ones. + // + adr x0, 0f // Take address of 'br' instruction below + bic x3, x3, #7 // Ensure correct alignment + sub x0, x0, x3, lsr #1 // Subtract 4 bytes for each arg to unstack + br x0 // Skip remaining argument registers + + ldr x7, [x9, #56] // Call with 8 arguments + ldr x6, [x9, #48] // | + ldr x5, [x9, #40] // | + ldr x4, [x9, #32] // | + ldr x3, [x9, #24] // | + ldr x2, [x9, #16] // | + ldr x1, [x9, #8] // V + ldr x0, [x9] // Call with 1 argument + +0: br x8 // Call with no arguments - mov sp, x20 - ldp x29, x30, [sp], #16 - ldp x19, x20, [sp], #16 + // + // More than 64 bytes: we need to build the full native stack frame and copy + // the part of the VM stack exceeding 64 bytes (which may contain stacked + // arguments) to the native stack + // +1: stp x29, x30, [sp, #-16]! + mov x29, sp - ret + // + // Ensure that the stack pointer remains 16 byte aligned, + // even if the size of the VM stack frame is not a multiple of 16 + // + add x1, x1, #64 // Skip over [potential] reg params + tbz x3, #3, 2f // Multiple of 16? + ldr x4, [x2, #-8]! // No? Then push one word + str x4, [sp, #-16]! // ... but use two slots + b 3f + +2: ldp x4, x5, [x2, #-16]! + stp x4, x5, [sp, #-16]! +3: cmp x2, x1 + b.gt 2b + + ldp x0, x1, [x9] + ldp x2, x3, [x9, #16] + ldp x4, x5, [x9, #32] + ldp x6, x7, [x9, #48] + + blr x8 + + mov sp, x29 + ldp x29, x30, [sp], #16 + ret //**************************************************************************** // EbcLLEbcInterpret