VirtualBox

Changeset 61341 in vbox


Ignore:
Timestamp:
May 31, 2016 3:30:30 PM (8 years ago)
Author:
vboxsync
Message:

CPUM: words about FPU state.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/CPUM.cpp

    r61128 r61341  
    3030 *
    3131 * @see grp_cpum
     32 *
     33 * @section sec_cpum_fpu        FPU / SSE / AVX / ++ state.
     34 *
     35 * TODO: proper write up, currently just some notes.
     36 *
     37 * The ring-0 FPU handling per OS:
     38 *
     39 *      - 64-bit Windows uses XMM registers in the kernel as part of the calling
     40 *        convention (Visual C++ doesn't seem to have a way to disable
     41 *        generating such code either), so CR0.TS/EM are always zero from what I
     42 *        can tell.  We are also forced to always load/save the guest XMM0-XMM15
     43 *        registers when entering/leaving guest context.  Interrupt handlers
     44 *        using FPU/SSE will offically have call save and restore functions
     45 *        exported by the kernel, if the really really have to use the state.
     46 *
     47 *      - 32-bit windows does lazy FPU handling, I think, probably including
     48 *        lazying saving.  The Windows Internals book states that it's a bad
     49 *        idea to use the FPU in kernel space. However, it looks like it will
     50 *        restore the FPU state of the current thread in case of a kernel \#NM.
     51 *        Interrupt handlers should be same as for 64-bit.
     52 *
     53 *      - Darwin allows taking \#NM in kernel space, restoring current thread's
     54 *        state if I read the code correctly.  It saves the FPU state of the
     55 *        outgoing thread, and uses CR0.TS to lazily load the state of the
     56 *        incoming one.  No idea yet how the FPU is treated by interrupt
     57 *        handlers, i.e. whether they are allowed to disable the state or
     58 *        something.
     59 *
     60 *      - Linux also allows \#NM in kernel space (don't know since when), and
     61 *        uses CR0.TS for lazy loading.  Saves outgoing thread's state, lazy
     62 *        loads the incoming unless configured to agressivly load it.  Interrupt
     63 *        handlers can ask whether they're allowed to use the FPU, and may
     64 *        freely trash the state if Linux thinks it has saved the thread's state
     65 *        already.  This is a problem.
     66 *
     67 *      - Solaris will, from what I can tell, panic if it gets an \#NM in kernel
     68 *        context.  When switching threads, the kernel will save the state of
     69 *        the outgoing thread and lazy load the incoming one using CR0.TS.
     70 *        There are a few routines in seeblk.s which uses the SSE unit in ring-0
     71 *        to do stuff, HAT are among the users.  The routines there will
     72 *        manually clear CR0.TS and save the XMM registers they use only if
     73 *        CR0.TS was zero upon entry.  They will skip it when not, because as
     74 *        mentioned above, the FPU state is saved when switching away from a
     75 *        thread and CR0.TS set to 1, so when CR0.TS is 1 there is nothing to
     76 *        preserve.  This is a problem if we restore CR0.TS to 1 after loading
     77 *        the guest state.
     78 *
     79 *      - FreeBSD - no idea yet.
     80 *
     81 *      - OS/2 does not allow \#NMs in kernel space IIRC.  Does lazy loading,
     82 *        possibly also lazy saving.  Interrupts must preserve the CR0.TS+EM &
     83 *        FPU states.
     84 *
     85 * Up to r107425 (2016-05-24) we would only temporarily modify CR0.TS/EM while
     86 * saving and restoring the host and guest states.  The motivation for this
     87 * change is that we want to be able to emulate SSE instruction in ring-0 (IEM).
     88 *
     89 * Starting with that change, we will leave CR0.TS=EM=0 after saving the host
     90 * state and only restore it once we've restore the host FPU state. This has the
     91 * accidental side effect of triggering Solaris to preserve XMM registers in
     92 * sseblk.s. When CR0 was changed by saving the FPU state, CPUM must now inform
     93 * the VT-x (HMVMX) code about it as it caches the CR0 value in the VMCS.
     94 *
    3295 */
    3396
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette