From patchwork Wed Feb 5 17:13:35 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 24213 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-oa0-f72.google.com (mail-oa0-f72.google.com [209.85.219.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 1C04920675 for ; Wed, 5 Feb 2014 17:13:43 +0000 (UTC) Received: by mail-oa0-f72.google.com with SMTP id i4sf3616801oah.11 for ; Wed, 05 Feb 2014 09:13:43 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=+lIghrY/l/xemvEQmYBNb2rc4fddhTIecD5ROkXMw7c=; b=Dhm3GRl3992c/PV8UA/NtL/UQne3LjZVLm1lC0VCtDoaTJ+e2020HJ9+92jQjsuJn1 uJBzM2pA0JvvMqlyYywEivK4F4nFb5E1320SkhNBm8bTVLtIWXEUOMTCO06r86EkUZ7h IiNw1TkVJuXJ5OrswyTC50xyg7UVDOkFs3NamMKW6x2Og4BZaYcFKrN5ZoRLNRwC7AY2 HpHa9kgDPeCBaAVDO4MnTNeS8Uv+dPsR9pQTFGePUSXqu0sYnD7kckDAq0LQHtCQt5R3 badi1rE/lCeZwlyeiFZudz+2ZZuNaBHJXModbaoOOZsxTk+NQ9qetj2GJxoSv4Fj/aUO 4lfw== X-Gm-Message-State: ALoCoQnI4e7FR8NdjmkJa41ibOG4KqaDboN1qEAuvSDEfv8al2SvKfGNjrgzXiRL7dSZwFWomajk X-Received: by 10.182.19.164 with SMTP id g4mr1018592obe.21.1391620423145; Wed, 05 Feb 2014 09:13:43 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.39.134 with SMTP id v6ls240050qgv.36.gmail; Wed, 05 Feb 2014 09:13:43 -0800 (PST) X-Received: by 10.52.243.102 with SMTP id wx6mr1491637vdc.12.1391620423034; Wed, 05 Feb 2014 09:13:43 -0800 (PST) Received: from mail-ve0-f181.google.com (mail-ve0-f181.google.com [209.85.128.181]) by mx.google.com with ESMTPS id uw4si2063553vdc.144.2014.02.05.09.13.43 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 05 Feb 2014 09:13:43 -0800 (PST) Received-SPF: neutral (google.com: 209.85.128.181 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.128.181; Received: by mail-ve0-f181.google.com with SMTP id cz12so533463veb.40 for ; Wed, 05 Feb 2014 09:13:43 -0800 (PST) X-Received: by 10.220.192.71 with SMTP id dp7mr213075vcb.45.1391620422912; Wed, 05 Feb 2014 09:13:42 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.174.196 with SMTP id u4csp65738vcz; Wed, 5 Feb 2014 09:13:42 -0800 (PST) X-Received: by 10.181.13.11 with SMTP id eu11mr17617852wid.30.1391620421897; Wed, 05 Feb 2014 09:13:41 -0800 (PST) Received: from mail-we0-f181.google.com (mail-we0-f181.google.com [74.125.82.181]) by mx.google.com with ESMTPS id pk3si15471911wjc.168.2014.02.05.09.13.41 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 05 Feb 2014 09:13:41 -0800 (PST) Received-SPF: neutral (google.com: 74.125.82.181 is neither permitted nor denied by best guess record for domain of ard.biesheuvel@linaro.org) client-ip=74.125.82.181; Received: by mail-we0-f181.google.com with SMTP id w61so508326wes.40 for ; Wed, 05 Feb 2014 09:13:41 -0800 (PST) X-Received: by 10.180.37.162 with SMTP id z2mr3339607wij.51.1391620421223; Wed, 05 Feb 2014 09:13:41 -0800 (PST) Received: from ards-macbook-pro.local (cag06-7-83-153-85-71.fbx.proxad.net. [83.153.85.71]) by mx.google.com with ESMTPSA id y13sm62961628wjr.8.2014.02.05.09.13.39 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 05 Feb 2014 09:13:40 -0800 (PST) From: Ard Biesheuvel To: will.deacon@arm.com, catalin.marinas@arm.com, linux-arm-kernel@lists.infradead.org Cc: patches@linaro.org, Ard Biesheuvel Subject: [PATCH v2 1/4] arm64: add abstractions for FPSIMD state manipulation Date: Wed, 5 Feb 2014 18:13:35 +0100 Message-Id: <1391620418-3999-2-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1391620418-3999-1-git-send-email-ard.biesheuvel@linaro.org> References: <1391620418-3999-1-git-send-email-ard.biesheuvel@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: ard.biesheuvel@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.128.181 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , This is a preparatory patch that replaces code that saves or restores the on-CPU or preserved FPSIMD state directly with wrapper functions, resulting in all direct manipulation of the FPSIMD state to be concentrated in fpsimd.c Signed-off-by: Ard Biesheuvel --- arch/arm64/include/asm/fpsimd.h | 9 ++++++--- arch/arm64/kernel/fpsimd.c | 31 +++++++++++++++++++++++++++++++ arch/arm64/kernel/process.c | 2 +- arch/arm64/kernel/ptrace.c | 22 +++++++++++++--------- arch/arm64/kernel/signal.c | 6 +++--- arch/arm64/kernel/signal32.c | 6 +++--- 6 files changed, 57 insertions(+), 19 deletions(-) diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h index c43b4ac13008..7807974b49ee 100644 --- a/arch/arm64/include/asm/fpsimd.h +++ b/arch/arm64/include/asm/fpsimd.h @@ -52,12 +52,15 @@ struct fpsimd_state { struct task_struct; -extern void fpsimd_save_state(struct fpsimd_state *state); -extern void fpsimd_load_state(struct fpsimd_state *state); - extern void fpsimd_thread_switch(struct task_struct *next); extern void fpsimd_flush_thread(void); +struct fpsimd_state *fpsimd_get_task_state(void); +void fpsimd_set_task_state(struct fpsimd_state *state); + +struct user_fpsimd_state *fpsimd_get_user_state(struct task_struct *t); +void fpsimd_set_user_state(struct task_struct *t, struct user_fpsimd_state *st); + #endif #endif diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index 4aef42a04bdc..eeb003f54ad0 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -34,6 +34,10 @@ #define FPEXC_IXF (1 << 4) #define FPEXC_IDF (1 << 7) +/* defined in entry-fpsimd.S but only used in this unit */ +void fpsimd_save_state(struct fpsimd_state *state); +void fpsimd_load_state(struct fpsimd_state *state); + /* * Trapped FP/ASIMD access. */ @@ -87,6 +91,33 @@ void fpsimd_flush_thread(void) preempt_enable(); } +/* + * Sync the saved FPSIMD context with the FPSIMD register file + */ +struct fpsimd_state *fpsimd_get_task_state(void) +{ + fpsimd_save_state(¤t->thread.fpsimd_state); + return ¤t->thread.fpsimd_state; +} + +/* + * Load a new FPSIMD state into the FPSIMD register file. + */ +void fpsimd_set_task_state(struct fpsimd_state *state) +{ + fpsimd_load_state(state); +} + +struct user_fpsimd_state *fpsimd_get_user_state(struct task_struct *t) +{ + return &t->thread.fpsimd_state.user_fpsimd; +} + +void fpsimd_set_user_state(struct task_struct *t, struct user_fpsimd_state *st) +{ + t->thread.fpsimd_state.user_fpsimd = *st; +} + #ifdef CONFIG_KERNEL_MODE_NEON /* diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 1c0a9be2ffa8..bfa8214f92d1 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -199,7 +199,7 @@ void release_thread(struct task_struct *dead_task) int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) { - fpsimd_save_state(¤t->thread.fpsimd_state); + fpsimd_get_task_state(); *dst = *src; return 0; } diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index 6a8928bba03c..d0b35af14539 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -500,8 +500,7 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { - struct user_fpsimd_state *uregs; - uregs = &target->thread.fpsimd_state.user_fpsimd; + struct user_fpsimd_state *uregs = fpsimd_get_user_state(target); return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0, -1); } @@ -516,7 +515,7 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset, if (ret) return ret; - target->thread.fpsimd_state.user_fpsimd = newstate; + fpsimd_set_user_state(target, &newstate); return ret; } @@ -723,7 +722,7 @@ static int compat_vfp_get(struct task_struct *target, compat_ulong_t fpscr; int ret; - uregs = &target->thread.fpsimd_state.user_fpsimd; + uregs = fpsimd_get_user_state(target); /* * The VFP registers are packed into the fpsimd_state, so they all sit @@ -746,24 +745,29 @@ static int compat_vfp_set(struct task_struct *target, unsigned int pos, unsigned int count, const void *kbuf, const void __user *ubuf) { - struct user_fpsimd_state *uregs; + struct user_fpsimd_state newstate; compat_ulong_t fpscr; int ret; if (pos + count > VFP_STATE_SIZE) return -EIO; - uregs = &target->thread.fpsimd_state.user_fpsimd; + /* + * We will not overwrite the entire FPSIMD state, so we need to + * initialize 'newstate' with sane values. + */ + newstate = *fpsimd_get_user_state(target); - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, uregs, 0, + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &newstate, 0, VFP_STATE_SIZE - sizeof(compat_ulong_t)); if (count && !ret) { ret = get_user(fpscr, (compat_ulong_t *)ubuf); - uregs->fpsr = fpscr & VFP_FPSCR_STAT_MASK; - uregs->fpcr = fpscr & VFP_FPSCR_CTRL_MASK; + newstate.fpsr = fpscr & VFP_FPSCR_STAT_MASK; + newstate.fpcr = fpscr & VFP_FPSCR_CTRL_MASK; } + fpsimd_set_user_state(target, &newstate); return ret; } diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 890a591f75dd..54e1092c5b4c 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -47,11 +47,11 @@ struct rt_sigframe { static int preserve_fpsimd_context(struct fpsimd_context __user *ctx) { - struct fpsimd_state *fpsimd = ¤t->thread.fpsimd_state; + struct fpsimd_state *fpsimd; int err; /* dump the hardware registers to the fpsimd_state structure */ - fpsimd_save_state(fpsimd); + fpsimd = fpsimd_get_task_state(); /* copy the FP and status/control registers */ err = __copy_to_user(ctx->vregs, fpsimd->vregs, sizeof(fpsimd->vregs)); @@ -88,7 +88,7 @@ static int restore_fpsimd_context(struct fpsimd_context __user *ctx) /* load the hardware registers from the fpsimd_state structure */ if (!err) { preempt_disable(); - fpsimd_load_state(&fpsimd); + fpsimd_set_task_state(&fpsimd); preempt_enable(); } diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c index b3fc9f5ec6d3..88e4535c3a45 100644 --- a/arch/arm64/kernel/signal32.c +++ b/arch/arm64/kernel/signal32.c @@ -208,7 +208,7 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from) */ static int compat_preserve_vfp_context(struct compat_vfp_sigframe __user *frame) { - struct fpsimd_state *fpsimd = ¤t->thread.fpsimd_state; + struct fpsimd_state *fpsimd; compat_ulong_t magic = VFP_MAGIC; compat_ulong_t size = VFP_STORAGE_SIZE; compat_ulong_t fpscr, fpexc; @@ -219,7 +219,7 @@ static int compat_preserve_vfp_context(struct compat_vfp_sigframe __user *frame) * Note that this also saves V16-31, which aren't visible * in AArch32. */ - fpsimd_save_state(fpsimd); + fpsimd = fpsimd_get_task_state(); /* Place structure header on the stack */ __put_user_error(magic, &frame->magic, err); @@ -284,7 +284,7 @@ static int compat_restore_vfp_context(struct compat_vfp_sigframe __user *frame) */ if (!err) { preempt_disable(); - fpsimd_load_state(&fpsimd); + fpsimd_set_task_state(&fpsimd); preempt_enable(); }