From: Dave Hansen <dave.hansen@linux.intel.com>
To: Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
linux-kernel@vger.kernel.org
Cc: x86@kernel.org, "Andy Lutomirski" <luto@kernel.org>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Radim Krčmář" <rkrcmar@redhat.com>,
kvm@vger.kernel.org, "Jason A. Donenfeld" <Jason@zx2c4.com>,
"Rik van Riel" <riel@surriel.com>
Subject: Re: [PATCH 04/11] x86/fpu: eager switch PKRU state
Date: Fri, 12 Oct 2018 10:51:34 -0700 [thread overview]
Message-ID: <76caafd5-c85d-61bb-62ec-8056cd6d95ac@linux.intel.com> (raw)
In-Reply-To: <20181004140547.13014-5-bigeasy@linutronix.de>
On 10/04/2018 07:05 AM, Sebastian Andrzej Siewior wrote:
> From: Rik van Riel <riel@surriel.com>
>
> While most of a task's FPU state is only needed in user space,
> the protection keys need to be in place immediately after a
> context switch.
>
> The reason is that any accesses to userspace memory while running
> in kernel mode also need to abide by the memory permissions
> specified in the protection keys.
>
> The "eager switch" is a preparation for loading the FPU state on return
> to userland. Instead of decoupling PKRU state from xstate I update PKRU
> within xstate on write operations by the kernel.
>
> Signed-off-by: Rik van Riel <riel@surriel.com>
> [bigeasy: save pkru to xstate, no cache]
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> ---
> arch/x86/include/asm/fpu/internal.h | 20 +++++++++++++++----
> arch/x86/include/asm/fpu/xstate.h | 2 ++
> arch/x86/include/asm/pgtable.h | 6 +-----
> arch/x86/include/asm/pkeys.h | 2 +-
> arch/x86/kernel/fpu/core.c | 2 +-
> arch/x86/mm/pkeys.c | 31 ++++++++++++++++++++++-------
> include/linux/pkeys.h | 2 +-
> 7 files changed, 46 insertions(+), 19 deletions(-)
>
> diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h
> index 16c4077ffc945..956d967ca824a 100644
> --- a/arch/x86/include/asm/fpu/internal.h
> +++ b/arch/x86/include/asm/fpu/internal.h
> @@ -570,11 +570,23 @@ switch_fpu_prepare(struct fpu *old_fpu, int cpu)
> */
> static inline void switch_fpu_finish(struct fpu *new_fpu, int cpu)
> {
> - bool preload = static_cpu_has(X86_FEATURE_FPU) &&
> - new_fpu->initialized;
> + bool load_fpu;
>
> - if (preload)
> - __fpregs_load_activate(new_fpu, cpu);
> + load_fpu = static_cpu_has(X86_FEATURE_FPU) && new_fpu->initialized;
> + if (!load_fpu)
> + return;
Needs comments, please. Especially around what an uninitialized new_fpu
means.
> + __fpregs_load_activate(new_fpu, cpu);
> +
> +#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
> + if (static_cpu_has(X86_FEATURE_OSPKE)) {
FWIW, you should be able to use cpu_feature_enabled() instead of an
explicit #ifdef here.
> + struct pkru_state *pk;
> +
> + pk = __raw_xsave_addr(&new_fpu->state.xsave, XFEATURE_PKRU);
> + if (pk->pkru != __read_pkru())
> + __write_pkru(pk->pkru);
> + }
> +#endif
> }
Comments here as well, please.
I think the goal is to keep the PKRU state in the 'init state' when
possible and also to save the cost of WRPKRU. But, it would be really
nice to be explicit.
> -static inline void write_pkru(u32 pkru)
> -{
> - if (boot_cpu_has(X86_FEATURE_OSPKE))
> - __write_pkru(pkru);
> -}
> +void write_pkru(u32 pkru);
One reason I inlined this was because it enables the the PK code to be
optimized away entirely. Putting the checks behind a function call
makes this optimization impossible.
Could you elaborate on why you chose to do this and what you think the
impact is or is not?
> diff --git a/arch/x86/include/asm/pkeys.h b/arch/x86/include/asm/pkeys.h
> index 19b137f1b3beb..b184f916319e5 100644
> --- a/arch/x86/include/asm/pkeys.h
> +++ b/arch/x86/include/asm/pkeys.h
> @@ -119,7 +119,7 @@ extern int arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
> unsigned long init_val);
> extern int __arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
> unsigned long init_val);
> -extern void copy_init_pkru_to_fpregs(void);
> +extern void pkru_set_init_value(void);
Could you elaborate on why the name is being changed?
> +void write_pkru(u32 pkru)
> +{
> + struct pkru_state *pk;
> +
> + if (!boot_cpu_has(X86_FEATURE_OSPKE))
> + return;
> +
> + pk = __raw_xsave_addr(¤t->thread.fpu.state.xsave, XFEATURE_PKRU);
> + /*
> + * Update the PKRU value in cstate and then in the CPU. A context
"cstate"? Did you mean xstate?
> + * switch between those two operation would load the new value from the
> + * updated xstate and then we would write (the same value) to the CPU.
> + */
> + pk->pkru = pkru;
> + __write_pkru(pkru);
> +
> +}
There's an unnecessary line there.
This also needs a lot more high-level context about why it is necessary.
I think you had that in the changelog, but we also need the function
commented.
> -void copy_init_pkru_to_fpregs(void)
> +void pkru_set_init_value(void)
> {
> u32 init_pkru_value_snapshot = READ_ONCE(init_pkru_value);
> +
> /*
> * Any write to PKRU takes it out of the XSAVE 'init
> * state' which increases context switch cost. Avoid
> - * writing 0 when PKRU was already 0.
> + * writing then same value which is already written.
> */
s/then/the/
> - if (!init_pkru_value_snapshot && !read_pkru())
> + if (init_pkru_value_snapshot == read_pkru())
> return;
> - /*
> - * Override the PKRU state that came from 'init_fpstate'
> - * with the baseline from the process.
> - */
> +
> write_pkru(init_pkru_value_snapshot);
> }
Isn't this doing some of the same work (including rdpkru()) as write_pkru()?
next prev parent reply other threads:[~2018-10-12 17:51 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-10-04 14:05 [PATCH 00/11 v3] x86: load FPU registers on return to userland Sebastian Andrzej Siewior
2018-10-04 14:05 ` [PATCH 01/11] x86/entry: remove _TIF_ALLWORK_MASK Sebastian Andrzej Siewior
2018-10-11 16:27 ` Borislav Petkov
2018-10-04 14:05 ` [PATCH 02/11] x86/fpu: add (__)make_fpregs_active helpers Sebastian Andrzej Siewior
2018-10-04 14:05 ` [PATCH 03/11] x86/fpu: make __raw_xsave_addr() use feature number instead of mask Sebastian Andrzej Siewior
2018-10-11 17:30 ` Christophe de Dinechin
2018-10-18 11:19 ` Sebastian Andrzej Siewior
2018-10-12 15:52 ` Dave Hansen
2018-10-18 11:17 ` Sebastian Andrzej Siewior
2018-10-18 11:21 ` Sebastian Andrzej Siewior
2018-10-17 10:01 ` Borislav Petkov
2018-10-18 11:48 ` Sebastian Andrzej Siewior
2018-10-04 14:05 ` [PATCH 04/11] x86/fpu: eager switch PKRU state Sebastian Andrzej Siewior
2018-10-12 17:51 ` Dave Hansen [this message]
2018-10-12 18:09 ` Andy Lutomirski
2018-10-12 19:44 ` Dave Hansen
2018-10-18 16:13 ` Sebastian Andrzej Siewior
2018-10-18 17:50 ` Dave Hansen
2018-10-04 14:05 ` [PATCH 05/11] x86/fpu: set PKRU state for kernel threads Sebastian Andrzej Siewior
2018-10-12 17:54 ` Dave Hansen
2018-10-12 18:02 ` Andy Lutomirski
2018-10-18 16:26 ` Sebastian Andrzej Siewior
2018-10-18 16:48 ` Andy Lutomirski
2018-10-18 17:47 ` Dave Hansen
2018-10-18 18:25 ` Sebastian Andrzej Siewior
2018-10-18 20:46 ` Andy Lutomirski
2018-10-18 20:56 ` Dave Hansen
2018-10-18 21:24 ` Sebastian Andrzej Siewior
2018-10-18 21:58 ` Andy Lutomirski
2018-10-19 7:44 ` Paolo Bonzini
2018-10-19 16:59 ` Andy Lutomirski
2018-10-19 17:01 ` Dave Hansen
2018-10-19 17:37 ` Andy Lutomirski
2018-10-19 18:26 ` Dave Hansen
2018-10-04 14:05 ` [PATCH 06/11] x86/pkeys: make init_pkru_value static Sebastian Andrzej Siewior
2018-10-12 17:55 ` Dave Hansen
2018-10-04 14:05 ` [PATCH 07/11] x86/pkeys: Drop the preempt-disable section Sebastian Andrzej Siewior
2018-10-12 17:58 ` Dave Hansen
2018-10-12 18:07 ` Andy Lutomirski
2018-10-12 20:26 ` Sebastian Andrzej Siewior
2018-10-04 14:05 ` [PATCH 08/11] x86/fpu: Always store the registers in copy_fpstate_to_sigframe() Sebastian Andrzej Siewior
2018-10-11 17:50 ` Christophe de Dinechin
2018-10-11 21:18 ` Andy Lutomirski
2018-10-12 18:15 ` Dave Hansen
2018-11-02 14:42 ` Sebastian Andrzej Siewior
2018-10-04 14:05 ` [PATCH 09/11] x86/entry: add TIF_LOAD_FPU Sebastian Andrzej Siewior
2018-10-04 14:05 ` [PATCH 10/11] x86/fpu: prepare copy_fpstate_to_sigframe for TIF_LOAD_FPU Sebastian Andrzej Siewior
2018-10-12 19:40 ` Dave Hansen
2018-10-15 15:24 ` Borislav Petkov
2018-11-02 15:44 ` Sebastian Andrzej Siewior
2018-11-02 22:55 ` Sebastian Andrzej Siewior
2018-10-04 14:05 ` [PATCH 11/11] x86/fpu: defer FPU state load until return to userspace Sebastian Andrzej Siewior
2018-10-04 16:14 ` Andy Lutomirski
2018-10-12 20:25 ` Sebastian Andrzej Siewior
2018-10-04 16:45 ` [PATCH 00/11 v3] x86: load FPU registers on return to userland Rik van Riel
2018-10-04 16:50 ` Andy Lutomirski
2018-10-05 11:55 ` Sebastian Andrzej Siewior
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=76caafd5-c85d-61bb-62ec-8056cd6d95ac@linux.intel.com \
--to=dave.hansen@linux.intel.com \
--cc=Jason@zx2c4.com \
--cc=bigeasy@linutronix.de \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=pbonzini@redhat.com \
--cc=riel@surriel.com \
--cc=rkrcmar@redhat.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox