On 2018-10-12 10:51:34 [-0700], Dave Hansen wrote: > > 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. that ->initialized field is gone. > > + __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. okay. > > + 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. added: /* * Writting PKRU is expensive. Only write the PKRU value if it is * different from the current one. */ > > -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? One thing let to another. It gets to an include mess once I tried to do more than just reading / writting the value. I kept now write_pkru() and added __write_pkru_if_new() which does the extra pieces. If you don't like the new version we would need to look on how to make it simpler :) > > 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? The function name read like init_pkru value is copied to fpregs save area which is not the case. I could revert it if you prefer. > > +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? indeed. > > + * 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. What is necessary? The manual update of "pk->pkru? > > - 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()? Well, yes. Since my write_pkru() checks if the new value the same as the current I dropped most of the code here. Sebastian