Changeset 61341 in vbox
- Timestamp:
- May 31, 2016 3:30:30 PM (8 years ago)
- File:
-
- 1 edited
-
trunk/src/VBox/VMM/VMMR3/CPUM.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/CPUM.cpp
r61128 r61341 30 30 * 31 31 * @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 * 32 95 */ 33 96
Note:
See TracChangeset
for help on using the changeset viewer.

