Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1316109 > unrolled thread
| Started by | Andy Lutomirski <luto@kernel.org> |
|---|---|
| First post | 2016-01-24 23:40 +0100 |
| Last post | 2016-01-25 18:30 +0100 |
| Articles | 4 — 3 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[PATCH v2 2/5] x86/fpu: Fix FNSAVE usage in eagerfpu mode Andy Lutomirski <luto@kernel.org> - 2016-01-24 23:40 +0100
Re: [PATCH v2 2/5] x86/fpu: Fix FNSAVE usage in eagerfpu mode Dave Hansen <dave.hansen@linux.intel.com> - 2016-01-25 16:50 +0100
Re: [PATCH v2 2/5] x86/fpu: Fix FNSAVE usage in eagerfpu mode Andy Lutomirski <luto@amacapital.net> - 2016-01-25 18:30 +0100
Re: [PATCH v2 2/5] x86/fpu: Fix FNSAVE usage in eagerfpu mode Dave Hansen <dave.hansen@linux.intel.com> - 2016-01-25 18:30 +0100
| From | Andy Lutomirski <luto@kernel.org> |
|---|---|
| Date | 2016-01-24 23:40 +0100 |
| Subject | [PATCH v2 2/5] x86/fpu: Fix FNSAVE usage in eagerfpu mode |
| Message-ID | <qUBub-2ZJ-43@gated-at.bofh.it> |
In eager fpu mode, having deactivated fpu without immediately
reloading some other context is illegal. Therefore, to recover from
FNSAVE, we can't just deactivate the state -- we need to reload it
if we're not actively context switching.
We had this wrong in fpu__save and fpu__copy. Fix both.
__kernel_fpu_begin was fine -- add a comment.
This fixes a warning triggerable with nofxsr eagerfpu=on.
Signed-off-by: Andy Lutomirski <luto@kernel.org>
---
arch/x86/kernel/fpu/core.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
index 08e1e11a05ca..7a9244df33e2 100644
--- a/arch/x86/kernel/fpu/core.c
+++ b/arch/x86/kernel/fpu/core.c
@@ -114,6 +114,10 @@ void __kernel_fpu_begin(void)
kernel_fpu_disable();
if (fpu->fpregs_active) {
+ /*
+ * Ignore return value -- we don't care if reg state
+ * is clobbered.
+ */
copy_fpregs_to_fpstate(fpu);
} else {
this_cpu_write(fpu_fpregs_owner_ctx, NULL);
@@ -189,8 +193,12 @@ void fpu__save(struct fpu *fpu)
preempt_disable();
if (fpu->fpregs_active) {
- if (!copy_fpregs_to_fpstate(fpu))
- fpregs_deactivate(fpu);
+ if (!copy_fpregs_to_fpstate(fpu)) {
+ if (use_eager_fpu())
+ copy_kernel_to_fpregs(&fpu->state);
+ else
+ fpregs_deactivate(fpu);
+ }
}
preempt_enable();
}
@@ -259,7 +267,11 @@ static void fpu_copy(struct fpu *dst_fpu, struct fpu *src_fpu)
preempt_disable();
if (!copy_fpregs_to_fpstate(dst_fpu)) {
memcpy(&src_fpu->state, &dst_fpu->state, xstate_size);
- fpregs_deactivate(src_fpu);
+
+ if (use_eager_fpu())
+ copy_kernel_to_fpregs(&src_fpu->state);
+ else
+ fpregs_deactivate(src_fpu);
}
preempt_enable();
}
--
2.5.0
[toc] | [next] | [standalone]
| From | Dave Hansen <dave.hansen@linux.intel.com> |
|---|---|
| Date | 2016-01-25 16:50 +0100 |
| Message-ID | <qURyW-64A-15@gated-at.bofh.it> |
| In reply to | #1316109 |
On 01/24/2016 02:38 PM, Andy Lutomirski wrote:
> if (fpu->fpregs_active) {
> + /*
> + * Ignore return value -- we don't care if reg state
> + * is clobbered.
> + */
> copy_fpregs_to_fpstate(fpu);
> } else {
> this_cpu_write(fpu_fpregs_owner_ctx, NULL);
> @@ -189,8 +193,12 @@ void fpu__save(struct fpu *fpu)
>
> preempt_disable();
> if (fpu->fpregs_active) {
> - if (!copy_fpregs_to_fpstate(fpu))
> - fpregs_deactivate(fpu);
> + if (!copy_fpregs_to_fpstate(fpu)) {
> + if (use_eager_fpu())
> + copy_kernel_to_fpregs(&fpu->state);
> + else
> + fpregs_deactivate(fpu);
> + }
> }
> preempt_enable();
I wonder if we should just make the
> + if (use_eager_fpu())
> + copy_kernel_to_fpregs(&fpu->state);
> + else
> + fpregs_deactivate(fpu);
behavior the default _inside_ copy_fpregs_to_fpstate(fpu). We evidently
got it wrong in 2/3 of the call sites that needed it. It ends up being
an optimization for FNSAVE (because it allows us to avoid an FRSTOR),
but we only take advantage of that in cases of kernel_fpu_begin/end().
FXSAVE has been around since at _least_ 1999, and I'd expect it to get
used in place of FNSAVE everywhere that it is available.
If we don't want to do that, maybe we should add a "clobber" argument to
copy_fpregs_to_fpstate() for when it's allowed to clobber the register
state.
I just hate putting this logic at all the call sites.
[toc] | [prev] | [next] | [standalone]
| From | Andy Lutomirski <luto@amacapital.net> |
|---|---|
| Date | 2016-01-25 18:30 +0100 |
| Message-ID | <qUT7I-7lX-17@gated-at.bofh.it> |
| In reply to | #1316842 |
On Jan 25, 2016 7:41 AM, "Dave Hansen" <dave.hansen@linux.intel.com> wrote:
>
> On 01/24/2016 02:38 PM, Andy Lutomirski wrote:
> > if (fpu->fpregs_active) {
> > + /*
> > + * Ignore return value -- we don't care if reg state
> > + * is clobbered.
> > + */
> > copy_fpregs_to_fpstate(fpu);
> > } else {
> > this_cpu_write(fpu_fpregs_owner_ctx, NULL);
> > @@ -189,8 +193,12 @@ void fpu__save(struct fpu *fpu)
> >
> > preempt_disable();
> > if (fpu->fpregs_active) {
> > - if (!copy_fpregs_to_fpstate(fpu))
> > - fpregs_deactivate(fpu);
> > + if (!copy_fpregs_to_fpstate(fpu)) {
> > + if (use_eager_fpu())
> > + copy_kernel_to_fpregs(&fpu->state);
> > + else
> > + fpregs_deactivate(fpu);
> > + }
> > }
> > preempt_enable();
>
> I wonder if we should just make the
>
> > + if (use_eager_fpu())
> > + copy_kernel_to_fpregs(&fpu->state);
> > + else
> > + fpregs_deactivate(fpu);
>
> behavior the default _inside_ copy_fpregs_to_fpstate(fpu). We evidently
> got it wrong in 2/3 of the call sites that needed it. It ends up being
> an optimization for FNSAVE (because it allows us to avoid an FRSTOR),
> but we only take advantage of that in cases of kernel_fpu_begin/end().
>
> FXSAVE has been around since at _least_ 1999, and I'd expect it to get
> used in place of FNSAVE everywhere that it is available.
>
> If we don't want to do that, maybe we should add a "clobber" argument to
> copy_fpregs_to_fpstate() for when it's allowed to clobber the register
> state.
>
> I just hate putting this logic at all the call sites.
Me too. I was thinking about having a clobber and a non-clobber variant.
The tricky part is that we have to think about preemption, too. In
theory, copying fpregs to somewhere other then the normal spot can be
okay with preemption on except in the FNSAVE case, but all the callers
probably need preemption off anyway.
Even if we do the cleanup, I think I'd rather fix the bug in place
first so the diff is clearer and then clean it up on top of that.
Does that seem reasonable?
--Andy
[toc] | [prev] | [next] | [standalone]
| From | Dave Hansen <dave.hansen@linux.intel.com> |
|---|---|
| Date | 2016-01-25 18:30 +0100 |
| Message-ID | <qUT7K-7lX-39@gated-at.bofh.it> |
| In reply to | #1317101 |
On 01/25/2016 09:25 AM, Andy Lutomirski wrote: > Even if we do the cleanup, I think I'd rather fix the bug in place > first so the diff is clearer and then clean it up on top of that. > > Does that seem reasonable? Yup, sounds fine to me.
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web