VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMRZ/CPUMRZ.cpp@ 62890

Last change on this file since 62890 was 61392, checked in by vboxsync, 9 years ago

CPUMRZFpuStatePrepareHostCpuForUse: Must always set VMCPU_FF_CPUM in raw-mode.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.6 KB
Line 
1/* $Id: CPUMRZ.cpp 61392 2016-06-02 00:47:37Z vboxsync $ */
2/** @file
3 * CPUM - Raw-mode and ring-0 context.
4 */
5
6/*
7 * Copyright (C) 2016 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_CPUM
23#include <VBox/vmm/cpum.h>
24#include "CPUMInternal.h"
25#include <VBox/vmm/vm.h>
26#include <VBox/err.h>
27#include <VBox/log.h>
28#include <VBox/vmm/hm.h>
29#include <iprt/assert.h>
30#include <iprt/x86.h>
31
32
33
34
35/**
36 * Prepares the host FPU/SSE/AVX stuff for IEM action.
37 *
38 * This will make sure the FPU/SSE/AVX guest state is _not_ loaded in the CPU.
39 * This will make sure the FPU/SSE/AVX host state is saved.
40 * Finally, it will make sure the FPU/SSE/AVX host features can be safely
41 * accessed.
42 *
43 * @param pVCpu The cross context virtual CPU structure.
44 */
45VMMRZ_INT_DECL(void) CPUMRZFpuStatePrepareHostCpuForUse(PVMCPU pVCpu)
46{
47 pVCpu->cpum.s.fChanged |= CPUM_CHANGED_FPU_REM;
48 switch (pVCpu->cpum.s.fUseFlags & (CPUM_USED_FPU_GUEST | CPUM_USED_FPU_HOST))
49 {
50 case 0:
51#ifdef IN_RC
52 cpumRZSaveHostFPUState(&pVCpu->cpum.s);
53 VMCPU_FF_SET(pVCpu, VMCPU_FF_CPUM); /* Must recalc CR0 before executing more code! */
54#else
55 if (cpumRZSaveHostFPUState(&pVCpu->cpum.s) == VINF_CPUM_HOST_CR0_MODIFIED)
56 HMR0NotifyCpumModifiedHostCr0(pVCpu);
57#endif
58 Log6(("CPUMRZFpuStatePrepareHostCpuForUse: #0 - %#x\n", ASMGetCR0()));
59 break;
60
61 case CPUM_USED_FPU_HOST:
62#ifdef IN_RC
63 VMCPU_FF_SET(pVCpu, VMCPU_FF_CPUM); /* (should be set already) */
64#elif defined(IN_RING0) && ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS)
65 if (pVCpu->cpum.s.fUseFlags | CPUM_SYNC_FPU_STATE)
66 {
67 pVCpu->cpum.s.fUseFlags &= ~CPUM_SYNC_FPU_STATE;
68 HMR0NotifyCpumUnloadedGuestFpuState(pVCpu);
69 }
70#endif
71 Log6(("CPUMRZFpuStatePrepareHostCpuForUse: #1 - %#x\n", ASMGetCR0()));
72 break;
73
74 case CPUM_USED_FPU_GUEST | CPUM_USED_FPU_HOST:
75#if defined(IN_RING0) && ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS)
76 Assert(!(pVCpu->cpum.s.fUseFlags & CPUM_SYNC_FPU_STATE));
77 if (CPUMIsGuestInLongModeEx(&pVCpu->cpum.s.Guest))
78 HMR0SaveFPUState(pVCpu->CTX_SUFF(pVM), pVCpu, &pVCpu->cpum.s.Guest);
79 else
80#endif
81 cpumRZSaveGuestFpuState(&pVCpu->cpum.s, true /*fLeaveFpuAccessible*/);
82#ifdef IN_RING0
83 HMR0NotifyCpumUnloadedGuestFpuState(pVCpu);
84#else
85 VMCPU_FF_SET(pVCpu, VMCPU_FF_CPUM); /* Must recalc CR0 before executing more code! */
86#endif
87 Log6(("CPUMRZFpuStatePrepareHostCpuForUse: #2 - %#x\n", ASMGetCR0()));
88 break;
89
90 default:
91 AssertFailed();
92 }
93
94}
95
96
97/**
98 * Makes sure the FPU/SSE/AVX guest state is saved in CPUMCPU::Guest and will be
99 * reloaded before direct use.
100 *
101 * No promisses about the FPU/SSE/AVX host features are made.
102 *
103 * @param pVCpu The cross context virtual CPU structure.
104 */
105VMMRZ_INT_DECL(void) CPUMRZFpuStateActualizeForChange(PVMCPU pVCpu)
106{
107 CPUMRZFpuStatePrepareHostCpuForUse(pVCpu);
108}
109
110
111/**
112 * Makes sure the FPU/SSE/AVX state in CPUMCPU::Guest is up to date.
113 *
114 * This will not cause CPUM_USED_FPU_GUEST to change.
115 *
116 * @param pVCpu The cross context virtual CPU structure.
117 */
118VMMRZ_INT_DECL(void) CPUMRZFpuStateActualizeForRead(PVMCPU pVCpu)
119{
120 if (pVCpu->cpum.s.fUseFlags & CPUM_USED_FPU_GUEST)
121 {
122#if defined(IN_RING0) && ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS)
123 Assert(!(pVCpu->cpum.s.fUseFlags & CPUM_SYNC_FPU_STATE));
124 if (CPUMIsGuestInLongModeEx(&pVCpu->cpum.s.Guest))
125 HMR0SaveFPUState(pVCpu->CTX_SUFF(pVM), pVCpu, &pVCpu->cpum.s.Guest);
126 else
127#endif
128 cpumRZSaveGuestFpuState(&pVCpu->cpum.s, false /*fLeaveFpuAccessible*/);
129 pVCpu->cpum.s.fUseFlags |= CPUM_USED_FPU_GUEST;
130 Log7(("CPUMRZFpuStateActualizeForRead\n"));
131 }
132}
133
134
135/**
136 * Makes sure the XMM0..XMM15 state in CPUMCPU::Guest is up to date.
137 *
138 * This will not cause CPUM_USED_FPU_GUEST to change.
139 *
140 * @param pVCpu The cross context virtual CPU structure.
141 */
142VMMRZ_INT_DECL(void) CPUMRZFpuStateActualizeSseForRead(PVMCPU pVCpu)
143{
144#if defined(VBOX_WITH_KERNEL_USING_XMM) && HC_ARCH_BITS == 64
145 NOREF(pVCpu);
146#else
147 if (pVCpu->cpum.s.fUseFlags & CPUM_USED_FPU_GUEST)
148 {
149# if defined(IN_RING0) && ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS)
150 if (CPUMIsGuestInLongModeEx(&pVCpu->cpum.s.Guest))
151 {
152 Assert(!(pVCpu->cpum.s.fUseFlags & CPUM_SYNC_FPU_STATE));
153 HMR0SaveFPUState(pVCpu->CTX_SUFF(pVM), pVCpu, &pVCpu->cpum.s.Guest);
154 pVCpu->cpum.s.fUseFlags |= CPUM_USED_FPU_GUEST;
155 }
156 else
157# endif
158 cpumRZSaveGuestSseRegisters(&pVCpu->cpum.s);
159 Log7(("CPUMRZFpuStateActualizeSseForRead\n"));
160 }
161#endif
162}
163
Note: See TracBrowser for help on using the repository browser.

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