From patchwork Tue Sep 15 11:36:37 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Will Deacon X-Patchwork-Id: 53637 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-lb0-f199.google.com (mail-lb0-f199.google.com [209.85.217.199]) by patches.linaro.org (Postfix) with ESMTPS id D603022A22 for ; Tue, 15 Sep 2015 11:38:37 +0000 (UTC) Received: by lbot4 with SMTP id t4sf7378241lbo.0 for ; Tue, 15 Sep 2015 04:38:36 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:subject:date:message-id :in-reply-to:references:precedence:list-id:list-unsubscribe :list-archive:list-post:list-help:list-subscribe:cc:mime-version :content-type:content-transfer-encoding:sender:errors-to :x-original-sender:x-original-authentication-results:mailing-list; bh=SOsmYvmw6A9XAP+Q9DCjHQQNjZLV3ZhQE4KJpLqgi1k=; b=L7C2OByCKPYS+plXLKqXKrVS2LJZTIS8glrCZagamv01DzCUKtlGRMfW3cBPrU0l9X sVjQNUFC05T2v9UGaAfq59e3P/WPwjq/6pID7DjqGHS7ExRgzc9UOHr0q/Rll5tw8TOy 1OPqIue/81JyoTrHDdk7eFeuyBlctu0WnQP0CSHjwmX6YiyrUkvwL5FHYTK9RXGp47mJ 2cIn7Ff6HqULgc9wY4harGhNpowbHgibXFHnuQt1huxJpqFxOjEo2JkvYX4NnPd2xIwJ bJS/ZOQEuJfP0tOhLMJRIpQCWZCvf+AI4V2CgWVzBYo8P6ypnKrq/hb9BS1sF/N2pa1t zobQ== X-Gm-Message-State: ALoCoQlgh1WSK955rQVu6wzvzE7CuAQX5LDBsPWL7FBS5+DbQ2EyMYJcM1WCiNTuExEMs91uuyYd X-Received: by 10.180.8.135 with SMTP id r7mr690605wia.0.1442317116822; Tue, 15 Sep 2015 04:38:36 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.180.201 with SMTP id dq9ls328589lac.53.gmail; Tue, 15 Sep 2015 04:38:36 -0700 (PDT) X-Received: by 10.112.156.193 with SMTP id wg1mr20148212lbb.24.1442317116626; Tue, 15 Sep 2015 04:38:36 -0700 (PDT) Received: from mail-la0-f49.google.com (mail-la0-f49.google.com. [209.85.215.49]) by mx.google.com with ESMTPS id be2si13032340lbc.119.2015.09.15.04.38.36 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 15 Sep 2015 04:38:36 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.49 as permitted sender) client-ip=209.85.215.49; Received: by lamp12 with SMTP id p12so104215248lam.0 for ; Tue, 15 Sep 2015 04:38:36 -0700 (PDT) X-Received: by 10.112.146.104 with SMTP id tb8mr18194569lbb.35.1442317116509; Tue, 15 Sep 2015 04:38:36 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.59.35 with SMTP id w3csp1744408lbq; Tue, 15 Sep 2015 04:38:35 -0700 (PDT) X-Received: by 10.107.15.159 with SMTP id 31mr36313269iop.159.1442317115421; Tue, 15 Sep 2015 04:38:35 -0700 (PDT) Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id sa2si10193054igb.75.2015.09.15.04.38.35 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 15 Sep 2015 04:38:35 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org designates 2001:1868:205::9 as permitted sender) client-ip=2001:1868:205::9; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZboXp-00086n-Ec; Tue, 15 Sep 2015 11:37:05 +0000 Received: from cam-admin0.cambridge.arm.com ([217.140.96.50]) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZboXm-0007rs-Sr for linux-arm-kernel@lists.infradead.org; Tue, 15 Sep 2015 11:37:03 +0000 Received: from edgewater-inn.cambridge.arm.com (edgewater-inn.cambridge.arm.com [10.1.203.139]) by cam-admin0.cambridge.arm.com (8.12.6/8.12.6) with ESMTP id t8FBacwo027054; Tue, 15 Sep 2015 12:36:38 +0100 (BST) Received: by edgewater-inn.cambridge.arm.com (Postfix, from userid 1000) id AB9D11AE33D7; Tue, 15 Sep 2015 12:36:44 +0100 (BST) From: Will Deacon To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 2/2] arm64: compat: fix vfp save/restore across signal handlers in big-endian Date: Tue, 15 Sep 2015 12:36:37 +0100 Message-Id: <1442316997-32282-2-git-send-email-will.deacon@arm.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1442316997-32282-1-git-send-email-will.deacon@arm.com> References: <1442316997-32282-1-git-send-email-will.deacon@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150915_043703_284674_85F1840F X-CRM114-Status: GOOD ( 16.09 ) X-Spam-Score: -6.9 (------) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-6.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at http://www.dnswl.org/, high trust [217.140.96.50 listed in list.dnswl.org] -0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , Cc: mark.rutland@arm.com, ard.biesheuvel@linaro.org, catalin.marinas@arm.com, victor.kamensky@linaro.org, Will Deacon , Dave.Martin@arm.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: will.deacon@arm.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.49 as permitted sender) smtp.mailfrom=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 When saving/restoring the VFP registers from a compat (AArch32) signal frame, we rely on the compat registers forming a prefix of the native register file and therefore make use of copy_{to,from}_user to transfer between the native fpsimd_state and the compat_vfp_sigframe. Unfortunately, this doesn't work so well in a big-endian environment. Our fpsimd save/restore code operates directly on 128-bit quantities (Q registers) whereas the compat_vfp_sigframe represents the registers as an array of 64-bit (D) registers. The architecture packs the compat D registers into the Q registers, with the least significant bytes holding the lower register. Consequently, we need to swap the 64-bit halves when converting between these two representations on a big-endian machine. This patch replaces the __copy_{to,from}_user invocations in our compat VFP signal handling code with explicit __put_user loops that operate on 64-bit values and swap them accordingly. Signed-off-by: Will Deacon Reviewed-by: Catalin Marinas --- arch/arm64/kernel/signal32.c | 47 +++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c index ae46ffad5aea..64e498e59f99 100644 --- a/arch/arm64/kernel/signal32.c +++ b/arch/arm64/kernel/signal32.c @@ -212,14 +212,32 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from) /* * VFP save/restore code. + * + * We have to be careful with endianness, since the fpsimd context-switch + * code operates on 128-bit (Q) register values whereas the compat ABI + * uses an array of 64-bit (D) registers. Consequently, we need to swap + * the two halves of each Q register when running on a big-endian CPU. */ +union __fpsimd_vreg { + __uint128_t raw; + struct { +#ifdef __AARCH64EB__ + u64 hi; + u64 lo; +#else + u64 lo; + u64 hi; +#endif + }; +}; + static int compat_preserve_vfp_context(struct compat_vfp_sigframe __user *frame) { struct fpsimd_state *fpsimd = ¤t->thread.fpsimd_state; compat_ulong_t magic = VFP_MAGIC; compat_ulong_t size = VFP_STORAGE_SIZE; compat_ulong_t fpscr, fpexc; - int err = 0; + int i, err = 0; /* * Save the hardware registers to the fpsimd_state structure. @@ -235,10 +253,15 @@ static int compat_preserve_vfp_context(struct compat_vfp_sigframe __user *frame) /* * Now copy the FP registers. Since the registers are packed, * we can copy the prefix we want (V0-V15) as it is. - * FIXME: Won't work if big endian. */ - err |= __copy_to_user(&frame->ufp.fpregs, fpsimd->vregs, - sizeof(frame->ufp.fpregs)); + for (i = 0; i < ARRAY_SIZE(frame->ufp.fpregs); i++) { + union __fpsimd_vreg vreg = { + .raw = fpsimd->vregs[i >> 1], + }; + + __put_user_error(vreg.lo, &frame->ufp.fpregs[i++], err); + __put_user_error(vreg.hi, &frame->ufp.fpregs[i], err); + } /* Create an AArch32 fpscr from the fpsr and the fpcr. */ fpscr = (fpsimd->fpsr & VFP_FPSCR_STAT_MASK) | @@ -263,7 +286,7 @@ static int compat_restore_vfp_context(struct compat_vfp_sigframe __user *frame) compat_ulong_t magic = VFP_MAGIC; compat_ulong_t size = VFP_STORAGE_SIZE; compat_ulong_t fpscr; - int err = 0; + int i, err = 0; __get_user_error(magic, &frame->magic, err); __get_user_error(size, &frame->size, err); @@ -275,12 +298,14 @@ static int compat_restore_vfp_context(struct compat_vfp_sigframe __user *frame) set_ti_thread_flag(current_thread_info(), TIF_FOREIGN_FPSTATE); - /* - * Copy the FP registers into the start of the fpsimd_state. - * FIXME: Won't work if big endian. - */ - err |= __copy_from_user(fpsimd.vregs, frame->ufp.fpregs, - sizeof(frame->ufp.fpregs)); + /* Copy the FP registers into the start of the fpsimd_state. */ + for (i = 0; i < ARRAY_SIZE(frame->ufp.fpregs); i++) { + union __fpsimd_vreg vreg; + + __get_user_error(vreg.lo, &frame->ufp.fpregs[i++], err); + __get_user_error(vreg.hi, &frame->ufp.fpregs[i], err); + fpsimd.vregs[i >> 1] = vreg.raw; + } /* Extract the fpsr and the fpcr from the fpscr */ __get_user_error(fpscr, &frame->ufp.fpscr, err);