Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp5477050imm; Wed, 12 Sep 2018 06:37:07 -0700 (PDT) X-Google-Smtp-Source: ANB0VdaOWmVVHq5exQAvLtHaf5VSzofZ0J1RNekX+VzI80jMhVZvfDCG/odcSKn3o8a+MNI2quxK X-Received: by 2002:a63:549:: with SMTP id 70-v6mr2421692pgf.385.1536759427300; Wed, 12 Sep 2018 06:37:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1536759427; cv=none; d=google.com; s=arc-20160816; b=H98phNuPpmdCv8lgysxPFJx3/KZo3yvmHb25DS8wVLUw9dFqrWOspD6adR5NYWQTgm VFLZ6OrwTIvh7YIwN2UX0miWdKKE3VSLlt/OYBob1t2CFkE/3GZFCMGO0805iFzbtCKN lRUy/qidVzGtNpOvM9iOjCKZxhBQt78Qa9+vua6vV8xSCZ+ZYjCUuHbNmCav+HiJdsxR 8GDjsNwOWrIVq93/OodJFw85CG80F9bqcCnQZw9VpEbKDpnT95A/e6ZUxgKRwj3vgTDG B8GNMXKkcUbzWYQIWoOB/sGaGaJ6UA2Y5c1hNoj+01hfE/Y8wjJNnQ+jTyOoQS00XqO2 V2JA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=EKZSDVX9cOEoBAjWV/n3GTIuydZpF/BAYuMtEvl5kqU=; b=maJ/v8HQF5LvlwfVV95EyUpIPnQkIftn6kUoch/DMc2rd0cuJTKqn6YUk3DGIXrH7M 3jH4NJmLiWUpgTfnm1IZqgMnRh9PpGyGjmIjrAQJ+IOqIEHVYojNi0HiSWuRTig2jKpQ BYY9z+QVVfPYoFgThJJe0P71op9CGZQHgCkAtNGnasGu0JNduirJWLNtTKJsuCa6X5ig FVMMJj7lkYB/TaT1JMuHyMvm5tO8GJciAk/H3LPNnUkaNMoAwEbN6dV1MnY4SLG6hVbF xTX5YeZCdGWmI+n54QLxBtwQ0PuDjONyLY20O+obKa5FfytHtJu9RiuDHVnWErVYisAr Y9Ug== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id b24-v6si1025334pfo.54.2018.09.12.06.36.44; Wed, 12 Sep 2018 06:37:07 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728073AbeILSkf (ORCPT + 99 others); Wed, 12 Sep 2018 14:40:35 -0400 Received: from Galois.linutronix.de ([146.0.238.70]:43904 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727838AbeILSke (ORCPT ); Wed, 12 Sep 2018 14:40:34 -0400 Received: from localhost ([127.0.0.1] helo=bazinga.breakpoint.cc) by Galois.linutronix.de with esmtp (Exim 4.80) (envelope-from ) id 1g05JE-0001Ap-4b; Wed, 12 Sep 2018 15:35:56 +0200 From: Sebastian Andrzej Siewior To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, Andy Lutomirski , Paolo Bonzini , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= , kvm@vger.kernel.org, "Jason A. Donenfeld" , Rik van Riel , Sebastian Andrzej Siewior Subject: [RFC PATCH 06/10] x86/fpu: Always store the registers in copy_fpstate_to_sigframe() Date: Wed, 12 Sep 2018 15:33:49 +0200 Message-Id: <20180912133353.20595-7-bigeasy@linutronix.de> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180912133353.20595-1-bigeasy@linutronix.de> References: <20180912133353.20595-1-bigeasy@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Rik van Riel copy_fpstate_to_sigframe() has two callers and both invoke the function only if fpu->initialized is set. So the check in the function for ->initialized makes no sense. It might be a relict from the lazy-FPU time: If the FPU registers were "loaded" then we would could save them directly. Otherwise (the FPU registers are not up to date) then they are saved in the fpu struct and those could be used for memcpy(). Since the registers always loaded at this point, save them and copy later. This code is extracted from an earlier version of the patchset while there still was lazy-FPU on x86. This is a preparation for loading the FPU registers on return to userland. Signed-off-by: Rik van Riel Signed-off-by: Sebastian Andrzej Siewior --- arch/x86/include/asm/fpu/internal.h | 45 --------------------------- arch/x86/kernel/fpu/signal.c | 48 ++++++++--------------------- 2 files changed, 12 insertions(+), 81 deletions(-) diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h index 57bd1576e033d..184d76c6470b1 100644 --- a/arch/x86/include/asm/fpu/internal.h +++ b/arch/x86/include/asm/fpu/internal.h @@ -125,22 +125,6 @@ extern void fpstate_sanitize_xstate(struct fpu *fpu); _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_fprestore) \ : output : input) -static inline int copy_fregs_to_user(struct fregs_state __user *fx) -{ - return user_insn(fnsave %[fx]; fwait, [fx] "=m" (*fx), "m" (*fx)); -} - -static inline int copy_fxregs_to_user(struct fxregs_state __user *fx) -{ - if (IS_ENABLED(CONFIG_X86_32)) - return user_insn(fxsave %[fx], [fx] "=m" (*fx), "m" (*fx)); - else if (IS_ENABLED(CONFIG_AS_FXSAVEQ)) - return user_insn(fxsaveq %[fx], [fx] "=m" (*fx), "m" (*fx)); - - /* See comment in copy_fxregs_to_kernel() below. */ - return user_insn(rex64/fxsave (%[fx]), "=m" (*fx), [fx] "R" (fx)); -} - static inline void copy_kernel_to_fxregs(struct fxregs_state *fx) { if (IS_ENABLED(CONFIG_X86_32)) { @@ -351,35 +335,6 @@ static inline void copy_kernel_to_xregs(struct xregs_state *xstate, u64 mask) XSTATE_XRESTORE(xstate, lmask, hmask); } -/* - * Save xstate to user space xsave area. - * - * We don't use modified optimization because xrstor/xrstors might track - * a different application. - * - * We don't use compacted format xsave area for - * backward compatibility for old applications which don't understand - * compacted format of xsave area. - */ -static inline int copy_xregs_to_user(struct xregs_state __user *buf) -{ - int err; - - /* - * Clear the xsave header first, so that reserved fields are - * initialized to zero. - */ - err = __clear_user(&buf->header, sizeof(buf->header)); - if (unlikely(err)) - return -EFAULT; - - stac(); - XSTATE_OP(XSAVE, buf, -1, -1, err); - clac(); - - return err; -} - /* * Restore xstate from user space xsave area. */ diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c index 23f1691670b66..ff6e7a67522d8 100644 --- a/arch/x86/kernel/fpu/signal.c +++ b/arch/x86/kernel/fpu/signal.c @@ -117,23 +117,6 @@ static inline int save_xstate_epilog(void __user *buf, int ia32_frame) return err; } - -static inline int copy_fpregs_to_sigframe(struct xregs_state __user *buf) -{ - int err; - - if (use_xsave()) - err = copy_xregs_to_user(buf); - else if (use_fxsr()) - err = copy_fxregs_to_user((struct fxregs_state __user *) buf); - else - err = copy_fregs_to_user((struct fregs_state __user *) buf); - - if (unlikely(err) && __clear_user(buf, fpu_user_xstate_size)) - err = -EFAULT; - return err; -} - /* * Save the fpu, extended register state to the user signal frame. * @@ -172,27 +155,20 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size) sizeof(struct user_i387_ia32_struct), NULL, (struct _fpstate_32 __user *) buf) ? -1 : 1; - if (fpu->initialized || using_compacted_format()) { - /* Save the live register state to the user directly. */ - if (copy_fpregs_to_sigframe(buf_fx)) - return -1; - /* Update the thread's fxstate to save the fsave header. */ - if (ia32_fxstate) - copy_fxregs_to_kernel(fpu); - } else { - /* - * It is a *bug* if kernel uses compacted-format for xsave - * area and we copy it out directly to a signal frame. It - * should have been handled above by saving the registers - * directly. - */ - if (boot_cpu_has(X86_FEATURE_XSAVES)) { - WARN_ONCE(1, "x86/fpu: saving compacted-format xsave area to a signal frame!\n"); - return -1; - } + /* Update the thread's fxstate to save the fsave header. */ + if (ia32_fxstate) + copy_fxregs_to_kernel(fpu); + else { + copy_fpregs_to_fpstate(fpu); + fpregs_deactivate(fpu); + } + if (using_compacted_format()) { + copy_xstate_to_user(buf_fx, xsave, 0, size); + } else { fpstate_sanitize_xstate(fpu); - if (__copy_to_user(buf_fx, xsave, fpu_user_xstate_size)) + size = fpu_user_xstate_size; + if (__copy_to_user(buf_fx, xsave, size)) return -1; } -- 2.19.0