From patchwork Wed Oct 31 14:04:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Long X-Patchwork-Id: 149834 Delivered-To: patches@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp6836450ljp; Wed, 31 Oct 2018 07:05:04 -0700 (PDT) X-Received: by 2002:a67:8a88:: with SMTP id m130mr1331330vsd.206.1540994702612; Wed, 31 Oct 2018 07:05:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1540994701; cv=none; d=google.com; s=arc-20160816; b=jWempYuMbOEF9hAws4I7aTVsghrMcQntFE6YdBErTrSSZZicr8rvR8ju/YA3gpewVU gWh69V82/95uf3gBNi+y5VT6S/MsxyvVB7HmcZcjz1ITiJWNaxf6akHCKu17sqM51N3A 8RDPaYbZ7nnXSeHOFVupQV8TuXdekSU3YOwEBkcOpoGUtfvR9ESTJGRzdwsu+AX83ejs +wAIAVUYdHz1uxlW6JKBkfS9QZNBiPj25qFfA4cUDjh3bxKcH5ktfMaqEu2y1cQFoAhw iUrZ+w8JFOtO/uVkxcTB3pIZSRzmQX0f5hCBmfjJFY2CeZm3dBec0FpJv1VWAyBHEkut 5EeQ== 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=xy/UIMoNnpuW3No4gkHcbKZisJ/hrnSGJPSz10O8lGk=; b=fh7n/KN+HYa3nRpRKEbNrV+PQ/hqsHXvjKurTyJCRCfa4htWpY34iBK/yLd1FCoKm/ lb2GUDQJnHQvOyxa9EbO1uWGjudPJ4KegTYxcUC40tueskPcudg8xCb9DzTUv7a4mNWh gF1/eyjj3Mxj1MPbGiRfrM4JV9KCh02ersPHtNCuc5RXWMlJ00AgeqL5/ZMq3rpf1boN yu1SRgx+wehZU/lrUDsrAxJ3CeS+fZkAcQjQS6jKcs1kfNwHFw/2DIYcQYDXlUiKA6i+ nJbmuvF/s5X40RpIbVn/OFQ/6TgK8WB0HSL/llAlIVD95ZYWgAwyl5Bho7Zdbeat4BKz N5sQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=MZwhwEoP; 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 i188sor4728677vsi.84.2018.10.31.07.05.01 for (Google Transport Security); Wed, 31 Oct 2018 07:05:01 -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=MZwhwEoP; 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=xy/UIMoNnpuW3No4gkHcbKZisJ/hrnSGJPSz10O8lGk=; b=MZwhwEoPJCA+ODVwgJ4XgLeYnpdizOj7q0/rEpOfwY++TmLDzY1MZR/YEebCCEmtig 3yHLzekj2+d8jdOPAvv2i08cBcTxZyzn9S6OYKno7dMBknAN1z5Dfd+Cx3qJz5YBUhy0 2WluV9EpO1p+tc3/m9Wr0iob2f5CtNCLwI1aQ= 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=xy/UIMoNnpuW3No4gkHcbKZisJ/hrnSGJPSz10O8lGk=; b=EoMwO2VzJTWEHmEQl9e9Fg2OKjtE2cZPFzQlU+kPf6TMz700w0qakWS5lKEca5FRlw hRMsOhLcrN9gW4UcOExWT1Xaiodyw31cUTIq69DaPSPnNZLJcbfn5NvReBvzCPdwY6YX m0YRTuWbxIVjesigKOo3c/mn9hFN5W4yOitUqTFZfSVwXy7MnqwbMy67PtOguNPqYo9X F+iJ3XOklq2SjQ985/PhgdHdl15tfMGK9INsoevBWCJBQOsdW/ppX4YSodx6AzqLShU3 8bFRx3Ii28E3QqPrNMs3/LbeNNbJ1L2veFIML/Pu28HfXUvEihE9fztzO+/gfJganfPm qL7g== X-Gm-Message-State: AGRZ1gKKDX9TJ5H07grFfcyDgSq9Y/lSOKMgr3FytmQg21ZibJg2+s9J bZkS3Pnf7dY5jx1gywlbmMB8cWDk X-Google-Smtp-Source: AJdET5ffmNYm9V16tfW6pqMJPFfr/I/HzcRWDs5/DUoXL5ue22XZrKmddQSR4EMhaqe+MGRPGYtEyg== X-Received: by 2002:a67:2802:: with SMTP id o2mr1345033vso.220.1540994701155; Wed, 31 Oct 2018 07:05:01 -0700 (PDT) Return-Path: Received: from dave-Dell-System-XPS-L502X.hsd1.nh.comcast.net ([2603:3005:3403:7100:2c71:8680:34e1:a6aa]) by smtp.googlemail.com with ESMTPSA id 6sm6795632vsy.25.2018.10.31.07.04.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 31 Oct 2018 07:05:00 -0700 (PDT) From: David Long To: stable@vger.kernel.org, Russell King - ARM Linux , Florian Fainelli , Tony Lindgren , Marc Zyngier , Mark Rutland Cc: Greg KH , Mark Brown Subject: [PATCH 4.4 14/18] ARM: vfp: use __copy_from_user() when restoring VFP state Date: Wed, 31 Oct 2018 10:04:32 -0400 Message-Id: <20181031140436.2964-15-dave.long@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181031140436.2964-1-dave.long@linaro.org> References: <20181031140436.2964-1-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 | 18 ++++++++---------- arch/arm/vfp/vfpmodule.c | 17 +++++++---------- 3 files changed, 17 insertions(+), 22 deletions(-) -- 2.17.1 diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index 776757d1604a..57d2ad9c75ca 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 a592bc0287f8..76f85c38f2b8 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -107,21 +107,19 @@ static int preserve_vfp_context(struct vfp_sigframe __user *frame) return vfp_preserve_user_clear_hwstate(&frame->ufp, &frame->ufp_exc); } -static int restore_vfp_context(struct vfp_sigframe __user *frame) +static int restore_vfp_context(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, (char __user *) 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; - return vfp_restore_user_hwstate(&frame->ufp, &frame->ufp_exc); + 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 2a61e4b04600..7aa6366b2a8d 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -601,13 +601,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); @@ -616,17 +614,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; @@ -635,10 +632,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; } /*