From patchwork Mon Oct 15 15:32:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Long X-Patchwork-Id: 148870 Delivered-To: patches@linaro.org Received: by 2002:a2e:8595:0:0:0:0:0 with SMTP id b21-v6csp3934084lji; Mon, 15 Oct 2018 08:32:42 -0700 (PDT) X-Received: by 2002:ac8:5314:: with SMTP id t20-v6mr16269237qtn.309.1539617562737; Mon, 15 Oct 2018 08:32:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539617562; cv=none; d=google.com; s=arc-20160816; b=ZSbRkAinVSfVEJbHZLodSRgj3K9kUqnYAZkfCCoW1WLWTnKXjQbdAUR1WX5ptaAgsI l0viUBp8lsJQY3XaevZEpWUmm8lB9Dp2ZggE+gefTI259RNj8QcQ3PZWg9Z/d1qKMRla MzduuHYYmvmeFdbnFfSM/rovpx6zXc1NzbFWQ5ZdIof1AwJnzNBv18L/aFqv/97c110P AM3PaNyqCRB4ejfwz4HTIBZt8XGHv4UfVqQWy1iU4Wmm3IMRrECkHAXiS2oD0V6KYuLQ AdjaZ10q1hE6dGgKDSf1rXHWoJWnRZsxrpYCAqpK0fSt2wdg7YpPeP+BrRw3JV07Zc/0 V34w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=jXzS1hOgnsqVT/8BqS8xcGLGCsKl0FR3F0fdq+38RJI=; b=H439RWTvUR+AZetNN+eJddIzmL5LAetrEpDsXB2WUxiarMflgGy7DWdySnciDbtolp ANduZeUed04t5CZIF40KtRcMf/SqRTT6pI0rpTZGDCR6EXuA9CAPdxmLh9SQNkmrTZC9 yFNDcyocpqym772siu66RPAhjtHbEUU0XP4RbyPd6gJ1fvFWwq9IFkOTzvsHA73z9SIS JOsy88I34QnNCR9evSyoYDpTSRKiG2BrpDDmXqRoCu1xiJBeAlhvqMj+ZyaPYMTUmAc5 Si+tXl4zCkjAyhatNLacTxwob0gM21QS+S0uFABYJwWBVDqP6RolaKWqR/CDU3sBGxNo l8dQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ZUnNYo4W; spf=pass (google.com: domain of dave.long@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=dave.long@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id d16sor12039828qvd.28.2018.10.15.08.32.42 for (Google Transport Security); Mon, 15 Oct 2018 08:32:42 -0700 (PDT) Received-SPF: pass (google.com: domain of dave.long@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ZUnNYo4W; spf=pass (google.com: domain of dave.long@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=dave.long@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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=jXzS1hOgnsqVT/8BqS8xcGLGCsKl0FR3F0fdq+38RJI=; b=ZUnNYo4WdZc8dQks5isWQbJjGOO3KJ352FdtnSFWCr8TkW9RXf6AhUitkfI6wTIPY6 KpdIOGpEy6SCaNuLTkZKqp0wE+EFpUhKz36ztHU45xYoYpdakYiy13GCLcnH74SI7pCf cnHFzxcMjcka8OXKlF3eY7bPPp0GoUxpbyp3s= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=jXzS1hOgnsqVT/8BqS8xcGLGCsKl0FR3F0fdq+38RJI=; b=q07zatI55CKqlmsEVo1Lw64BzW5K7TaQa0kuoCGhVrvhy02WOnNfRzORpKmza6d9DL XXaC32RAzV98uca40FV0HrBdMyNM+ZFcGTPX52PjaXYo5ytM5rpoNpwfWE+s16L/cbGu 2KE80TDTUFbHGXUwXaBqlayHOzsv/86bFUllBjli1NxSU6EAPjZZ9iDJYoUKSOGpXDZ9 xz4Mk9B28H0QBfHcR+jYIiC8xHc6TRw3unywwdY+xg+M4PMcNc8207BQUtZOjFOHU8Zs VD4cDuhAthv9fvLPJUVaDYFTkplIH4wnJ8P0fLwNaCOgGVyIEIzki5+u1r/HM1huUuQP DUlQ== X-Gm-Message-State: ABuFfoi6Pg/AjCtgpuS9hRDTsqCbAwAbqjZbXGfcm9U7jcs8UxZf+hY6 HKN9PAFWmJswqP6/7X03WkvSfg5l X-Google-Smtp-Source: ACcGV60LS79e9RQE50nGfkWN3O+qyiu7SwBp8nldwjG5j1rXlceSBHd88b7pNoIKExNhXI6u3azGIA== X-Received: by 2002:a0c:953a:: with SMTP id l55mr17445514qvl.22.1539617562294; Mon, 15 Oct 2018 08:32:42 -0700 (PDT) Return-Path: Received: from localhost.localdomain ([72.71.243.63]) by smtp.googlemail.com with ESMTPSA id g82-v6sm10087768qkh.24.2018.10.15.08.32.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 15 Oct 2018 08:32:41 -0700 (PDT) From: David Long To: , Russell King - ARM Linux , Florian Fainelli , Tony Lindgren , Marc Zyngier , Mark Rutland Cc: Greg KH , Mark Brown Subject: [PATCH 4.14 20/24] ARM: vfp: use __copy_from_user() when restoring VFP state Date: Mon, 15 Oct 2018 11:32:14 -0400 Message-Id: <1539617538-22328-21-git-send-email-dave.long@linaro.org> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1539617538-22328-1-git-send-email-dave.long@linaro.org> References: <1539617538-22328-1-git-send-email-dave.long@linaro.org> From: Russell King Commit 42019fc50dfadb219f9e6ddf4c354f3837057d80 upstream. __get_user_error() is used as a fast accessor to make copying structure members in the signal handling path as efficient as possible. However, with software PAN and the recent Spectre variant 1, the efficiency is reduced as these are no longer fast accessors. In the case of software PAN, it has to switch the domain register around each access, and with Spectre variant 1, it would have to repeat the access_ok() check for each access. Use __copy_from_user() rather than __get_user_err() for individual members when restoring VFP state. Acked-by: Mark Rutland Signed-off-by: Russell King Signed-off-by: David A. Long --- arch/arm/include/asm/thread_info.h | 4 ++-- arch/arm/kernel/signal.c | 20 ++++++++------------ arch/arm/vfp/vfpmodule.c | 17 +++++++---------- 3 files changed, 17 insertions(+), 24 deletions(-) -- 2.5.0 diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index 776757d..57d2ad9 100644 --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h @@ -126,8 +126,8 @@ struct user_vfp_exc; extern int vfp_preserve_user_clear_hwstate(struct user_vfp __user *, struct user_vfp_exc __user *); -extern int vfp_restore_user_hwstate(struct user_vfp __user *, - struct user_vfp_exc __user *); +extern int vfp_restore_user_hwstate(struct user_vfp *, + struct user_vfp_exc *); #endif /* diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 80da0cd..cdfe52b 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -149,22 +149,18 @@ static int preserve_vfp_context(struct vfp_sigframe __user *frame) static int restore_vfp_context(char __user **auxp) { - struct vfp_sigframe __user *frame = - (struct vfp_sigframe __user *)*auxp; - unsigned long magic; - unsigned long size; - int err = 0; - - __get_user_error(magic, &frame->magic, err); - __get_user_error(size, &frame->size, err); + struct vfp_sigframe frame; + int err; + err = __copy_from_user(&frame, *auxp, sizeof(frame)); if (err) - return -EFAULT; - if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE) + return err; + + if (frame.magic != VFP_MAGIC || frame.size != VFP_STORAGE_SIZE) return -EINVAL; - *auxp += size; - return vfp_restore_user_hwstate(&frame->ufp, &frame->ufp_exc); + *auxp += sizeof(frame); + return vfp_restore_user_hwstate(&frame.ufp, &frame.ufp_exc); } #endif diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index aa7496b..6abcd4a 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -597,13 +597,11 @@ int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp, } /* Sanitise and restore the current VFP state from the provided structures. */ -int vfp_restore_user_hwstate(struct user_vfp __user *ufp, - struct user_vfp_exc __user *ufp_exc) +int vfp_restore_user_hwstate(struct user_vfp *ufp, struct user_vfp_exc *ufp_exc) { struct thread_info *thread = current_thread_info(); struct vfp_hard_struct *hwstate = &thread->vfpstate.hard; unsigned long fpexc; - int err = 0; /* Disable VFP to avoid corrupting the new thread state. */ vfp_flush_hwstate(thread); @@ -612,17 +610,16 @@ int vfp_restore_user_hwstate(struct user_vfp __user *ufp, * Copy the floating point registers. There can be unused * registers see asm/hwcap.h for details. */ - err |= __copy_from_user(&hwstate->fpregs, &ufp->fpregs, - sizeof(hwstate->fpregs)); + memcpy(&hwstate->fpregs, &ufp->fpregs, sizeof(hwstate->fpregs)); /* * Copy the status and control register. */ - __get_user_error(hwstate->fpscr, &ufp->fpscr, err); + hwstate->fpscr = ufp->fpscr; /* * Sanitise and restore the exception registers. */ - __get_user_error(fpexc, &ufp_exc->fpexc, err); + fpexc = ufp_exc->fpexc; /* Ensure the VFP is enabled. */ fpexc |= FPEXC_EN; @@ -631,10 +628,10 @@ int vfp_restore_user_hwstate(struct user_vfp __user *ufp, fpexc &= ~(FPEXC_EX | FPEXC_FP2V); hwstate->fpexc = fpexc; - __get_user_error(hwstate->fpinst, &ufp_exc->fpinst, err); - __get_user_error(hwstate->fpinst2, &ufp_exc->fpinst2, err); + hwstate->fpinst = ufp_exc->fpinst; + hwstate->fpinst2 = ufp_exc->fpinst2; - return err ? -EFAULT : 0; + return 0; } /*