From: Avi Kivity <avi@redhat.com>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: "H. Peter Anvin" <hpa@zytor.com>, Josh Boyer <jwboyer@gmail.com>,
Jongman Heo <jongman.heo@samsung.com>,
Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>,
x86@kernel.org,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
KVM list <kvm@vger.kernel.org>
Subject: Re: [PATCH 2/2] i387: split up <asm/i387.h> into exported and internal interfaces
Date: Tue, 28 Feb 2012 19:21:28 +0200 [thread overview]
Message-ID: <4F4D0D18.4060409@redhat.com> (raw)
In-Reply-To: <CA+55aFwKJspohPdmbzXZzN4xtNU1Sz0RMA9AfTLnoRWgpPGzHg@mail.gmail.com>
On 02/28/2012 06:05 PM, Linus Torvalds wrote:
> On Tue, Feb 28, 2012 at 3:21 AM, Avi Kivity <avi@redhat.com> wrote:
> >
> > Can you elaborate on what you don't like in the kvm code (apart from "it
> > does virtualiztion")?
>
> It doesn't fit any of the patterns of the x87 save/restore code, and I
> don't know what it does.
It tries to do two things: first, keep the guest fpu loaded while
running kernel code, and second, allow the instruction emulator to
access the guest fpu.
> It does clts on its own, in random places without actually restoring
> the FPU state. Why is that ok? I don't know.
The way we use vmx, it does an implicit stts() after an exit from a
guest (it's not required, but it's expensive to play with the value of
the host cr0, so we set it to a safe value and clear it when needed).
So sometimes we need these random clts()s.
> And I don't think it is,
> but I didn't change any of it. Why doesn't that thing corrupt the lazy
> state save of some other process, for example?
>
> Doing a "clts()" without restoring the FPU state immediately
> afterwards is fundamentally *wrong*. It's crazy. Insane. You can now
> use the FPU, but with whatever random state that is in it that caused
> TS to be set to begin with.
There are two cases. In one of them, we do restore the guest fpu
immediately afterwards. In the other, we're just clearing a CR0.TS that
was set spuriously.
> And if you don't have any FPU state to restore, because you want to
> use your own kernel state, you should use the
> "kernel_fpu_begin()/end()" things that we have had forever.
We do have state - the guest state.
> Here's an example of the kind of UTTER AND ABSOLUTE SHIT that kvm FPU
> state restore is:
>
> static void emulator_get_fpu(struct x86_emulate_ctxt *ctxt)
> {
> preempt_disable();
> kvm_load_guest_fpu(emul_to_vcpu(ctxt));
> /*
> * CR0.TS may reference the host fpu state, not the guest fpu state,
> * so it may be clear at this point.
> */
> clts();
> }
>
> that whole "comment" says nothing at all. And clearing CR0.TS *after*
> loading the FPU state is a f*cking joke, since you need it clear to
> load the FPU state to begin with. So as far as I can tell,
> kvm_load_guest_fpu() will have cleared the FPU state already, but *it*
> did it by:
>
> unlazy_fpu(current);
> fpu_restore_checking(&vcpu->arch.guest_fpu);
>
> where "unlazy_fpu()" will have *set* TS if it wasn't set before, so
> fpu_restore_checking() will now TAKE A FAULT, and in that fault
> handler it will clear TS so that it can reload the state we just saved
> (yes, really), only to then return to fpu_restore_checking() and
> reload yet *another* state.
>
> The code is crap. It's insane. It may work, but if it does, it does so
> by pure chance and happenstance. The code is CLEARLY INSANE.
What you described is the slow path. The fast path is
void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
{
if (vcpu->guest_fpu_loaded)
return;
If we're emulating an fpu instruction, it's very likely that we have the
guest fpu loaded into the cpu. If we do take that path, we have the
right fpu state loaded, but CR0.TS is set by the recent exit, so we need
to clear it (the comment is in fact correct, except that it misspelled
"set").
> I wasn't going to touch it. It had been written by a
> random-code-generator that had strung the various FPU accessor
> functions up in random order until it compiled.
The tried and tested way, yes.
--
error compiling committee.c: too many arguments to function
next prev parent reply other threads:[~2012-02-28 17:21 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <alpine.LFD.2.02.1202191412060.3898@i5.linux-foundation.org>
[not found] ` <alpine.LFD.2.02.1202201145130.4237@i5.linux-foundation.org>
[not found] ` <alpine.LFD.2.02.1202201146450.4237@i5.linux-foundation.org>
[not found] ` <alpine.LFD.2.02.1202201147350.4237@i5.linux-foundation.org>
[not found] ` <alpine.LFD.2.02.1202201148100.4237@i5.linux-foundation.org>
[not found] ` <CA+5PVA5Zkka6Q2kcvWbvA3xr9=5TZ+VWWsWzYcRQ1GpccpJHew@mail.gmail.com>
[not found] ` <CA+55aFyqz-2ejsRpbRdYx7UHDBg3q=9nvmtrj2nLeuZonrkz1A@mail.gmail.com>
[not found] ` <4F42FE08.5020309@zytor.com>
[not found] ` <CA+55aFxKLvHXRkx-x+zOkHJk__uTJc90Z0i+00W-hqDaQb_HCQ@mail.gmail.com>
[not found] ` <4F43DB69.9060509@zytor.com>
[not found] ` <CA+55aFxap0zAAJOCcz0f+DKBuG6VQa7kq1j2JD1S4ysgmb62aA@mail.gmail.com>
[not found] ` <4F440945.1020904@zytor.com>
[not found] ` <alpine.LFD.2.02.1202211338420.5354@i5.linux-foundation.org>
[not found] ` <alpine.LFD.2.02.1202211339590.5354@i5.linux-foundation.org >
[not found] ` <alpine.LFD.2.02.1202211340330.5354@i5.linux-foundation.org>
2012-02-28 11:21 ` [PATCH 2/2] i387: split up <asm/i387.h> into exported and internal interfaces Avi Kivity
2012-02-28 16:05 ` Linus Torvalds
2012-02-28 17:21 ` Avi Kivity [this message]
2012-02-28 17:37 ` Linus Torvalds
2012-02-28 18:08 ` Linus Torvalds
2012-02-28 18:29 ` Avi Kivity
2012-02-28 18:09 ` Avi Kivity
2012-02-28 18:34 ` Linus Torvalds
2012-02-28 19:06 ` Avi Kivity
2012-02-28 19:26 ` Linus Torvalds
2012-02-28 19:45 ` Avi Kivity
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=4F4D0D18.4060409@redhat.com \
--to=avi@redhat.com \
--cc=hpa@zytor.com \
--cc=jongman.heo@samsung.com \
--cc=jwboyer@gmail.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
--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