VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMAll/GIMAll.cpp@ 59710

Last change on this file since 59710 was 58390, checked in by vboxsync, 9 years ago

VMM/GIM: Implement Hyper-V debug receive thread optimization. Added a few statistics to GIM.
Fixed a bug in Windows guests' debug DHCP handling.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.7 KB
Line 
1/* $Id: GIMAll.cpp 58390 2015-10-23 12:35:35Z vboxsync $ */
2/** @file
3 * GIM - Guest Interface Manager - All Contexts.
4 */
5
6/*
7 * Copyright (C) 2014-2015 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_GIM
23#include "GIMInternal.h"
24#include <VBox/err.h>
25#include <VBox/vmm/vm.h>
26
27/* Include all the providers. */
28#include "GIMHvInternal.h"
29#include "GIMMinimalInternal.h"
30
31
32/**
33 * Checks whether GIM is being used by this VM.
34 *
35 * @retval true if used.
36 * @retval false if no GIM provider ("none") is used.
37 *
38 * @param pVM The cross context VM structure.
39 */
40VMMDECL(bool) GIMIsEnabled(PVM pVM)
41{
42 return pVM->gim.s.enmProviderId != GIMPROVIDERID_NONE;
43}
44
45
46/**
47 * Gets the GIM provider configured for this VM.
48 *
49 * @returns The GIM provider Id.
50 * @param pVM The cross context VM structure.
51 */
52VMMDECL(GIMPROVIDERID) GIMGetProvider(PVM pVM)
53{
54 return pVM->gim.s.enmProviderId;
55}
56
57
58/**
59 * Returns whether the guest has configured and enabled calls to the hypervisor.
60 *
61 * @returns true if hypercalls are enabled and usable, false otherwise.
62 * @param pVCpu The cross context virtual CPU structure.
63 */
64VMM_INT_DECL(bool) GIMAreHypercallsEnabled(PVMCPU pVCpu)
65{
66 PVM pVM = pVCpu->CTX_SUFF(pVM);
67 if (!GIMIsEnabled(pVM))
68 return false;
69
70 switch (pVM->gim.s.enmProviderId)
71 {
72 case GIMPROVIDERID_HYPERV:
73 return gimHvAreHypercallsEnabled(pVCpu);
74
75 case GIMPROVIDERID_KVM:
76 return gimKvmAreHypercallsEnabled(pVCpu);
77
78 default:
79 return false;
80 }
81}
82
83
84/**
85 * Implements a GIM hypercall with the provider configured for the VM.
86 *
87 * @returns VBox status code.
88 * @param pVCpu The cross context virtual CPU structure.
89 * @param pCtx Pointer to the guest-CPU context.
90 *
91 * @thread EMT.
92 */
93VMM_INT_DECL(int) GIMHypercall(PVMCPU pVCpu, PCPUMCTX pCtx)
94{
95 PVM pVM = pVCpu->CTX_SUFF(pVM);
96 VMCPU_ASSERT_EMT(pVCpu);
97
98 if (RT_UNLIKELY(!GIMIsEnabled(pVM)))
99 return VERR_GIM_NOT_ENABLED;
100
101 STAM_COUNTER_INC(&pVM->gim.s.StatHypercalls);
102 switch (pVM->gim.s.enmProviderId)
103 {
104 case GIMPROVIDERID_HYPERV:
105 return gimHvHypercall(pVCpu, pCtx);
106
107 case GIMPROVIDERID_KVM:
108 return gimKvmHypercall(pVCpu, pCtx);
109
110 default:
111 AssertMsgFailed(("GIMHypercall: for provider %u not available/implemented\n", pVM->gim.s.enmProviderId));
112 return VERR_GIM_HYPERCALLS_NOT_AVAILABLE;
113 }
114}
115
116
117/**
118 * Returns whether the guest has configured and setup the use of paravirtualized
119 * TSC.
120 *
121 * Paravirtualized TSCs are per-VM and the rest of the execution engine logic
122 * relies on that.
123 *
124 * @returns true if enabled and usable, false otherwise.
125 * @param pVM The cross context VM structure.
126 */
127VMM_INT_DECL(bool) GIMIsParavirtTscEnabled(PVM pVM)
128{
129 switch (pVM->gim.s.enmProviderId)
130 {
131 case GIMPROVIDERID_HYPERV:
132 return gimHvIsParavirtTscEnabled(pVM);
133
134 case GIMPROVIDERID_KVM:
135 return gimKvmIsParavirtTscEnabled(pVM);
136
137 default:
138 break;
139 }
140 return false;
141}
142
143
144/**
145 * Whether \#UD exceptions in the guest needs to be intercepted by the GIM
146 * provider.
147 *
148 * At the moment, the reason why this isn't a more generic interface wrt to
149 * exceptions is because of performance (each VM-exit would have to manually
150 * check whether or not GIM needs to be notified). Left as a todo for later if
151 * really required.
152 *
153 * @returns true if needed, false otherwise.
154 * @param pVCpu The cross context virtual CPU structure.
155 */
156VMM_INT_DECL(bool) GIMShouldTrapXcptUD(PVMCPU pVCpu)
157{
158 PVM pVM = pVCpu->CTX_SUFF(pVM);
159 if (!GIMIsEnabled(pVM))
160 return false;
161
162 switch (pVM->gim.s.enmProviderId)
163 {
164 case GIMPROVIDERID_KVM:
165 return gimKvmShouldTrapXcptUD(pVCpu);
166
167 case GIMPROVIDERID_HYPERV:
168 return gimHvShouldTrapXcptUD(pVCpu);
169
170 default:
171 return false;
172 }
173}
174
175
176/**
177 * Exception handler for \#UD when requested by the GIM provider.
178 *
179 * @param pVCpu The cross context virtual CPU structure.
180 * @param pCtx Pointer to the guest-CPU context.
181 * @param pDis Pointer to the disassembled instruction state at RIP.
182 * Optional, can be NULL.
183 */
184VMM_INT_DECL(int) GIMXcptUD(PVMCPU pVCpu, PCPUMCTX pCtx, PDISCPUSTATE pDis)
185{
186 PVM pVM = pVCpu->CTX_SUFF(pVM);
187 Assert(GIMIsEnabled(pVM));
188
189 switch (pVM->gim.s.enmProviderId)
190 {
191 case GIMPROVIDERID_KVM:
192 return gimKvmXcptUD(pVCpu, pCtx, pDis);
193
194 case GIMPROVIDERID_HYPERV:
195 return gimHvXcptUD(pVCpu, pCtx, pDis);
196
197 default:
198 return VERR_GIM_OPERATION_FAILED;
199 }
200}
201
202
203/**
204 * Invokes the read-MSR handler for the GIM provider configured for the VM.
205 *
206 * @returns Strict VBox status code like CPUMQueryGuestMsr.
207 * @retval VINF_CPUM_R3_MSR_READ
208 * @retval VERR_CPUM_RAISE_GP_0
209 *
210 * @param pVCpu The cross context virtual CPU structure.
211 * @param idMsr The MSR to read.
212 * @param pRange The range this MSR belongs to.
213 * @param puValue Where to store the MSR value read.
214 */
215VMM_INT_DECL(VBOXSTRICTRC) GIMReadMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
216{
217 Assert(pVCpu);
218 PVM pVM = pVCpu->CTX_SUFF(pVM);
219 Assert(GIMIsEnabled(pVM));
220 VMCPU_ASSERT_EMT(pVCpu);
221
222 switch (pVM->gim.s.enmProviderId)
223 {
224 case GIMPROVIDERID_HYPERV:
225 return gimHvReadMsr(pVCpu, idMsr, pRange, puValue);
226
227 case GIMPROVIDERID_KVM:
228 return gimKvmReadMsr(pVCpu, idMsr, pRange, puValue);
229
230 default:
231 AssertMsgFailed(("GIMReadMsr: for unknown provider %u idMsr=%#RX32 -> #GP(0)", pVM->gim.s.enmProviderId, idMsr));
232 return VERR_CPUM_RAISE_GP_0;
233 }
234}
235
236
237/**
238 * Invokes the write-MSR handler for the GIM provider configured for the VM.
239 *
240 * @returns Strict VBox status code like CPUMSetGuestMsr.
241 * @retval VINF_CPUM_R3_MSR_WRITE
242 * @retval VERR_CPUM_RAISE_GP_0
243 *
244 * @param pVCpu The cross context virtual CPU structure.
245 * @param idMsr The MSR to write.
246 * @param pRange The range this MSR belongs to.
247 * @param uValue The value to set, ignored bits masked.
248 * @param uRawValue The raw value with the ignored bits not masked.
249 */
250VMM_INT_DECL(VBOXSTRICTRC) GIMWriteMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t uValue, uint64_t uRawValue)
251{
252 AssertPtr(pVCpu);
253 NOREF(uValue);
254
255 PVM pVM = pVCpu->CTX_SUFF(pVM);
256 Assert(GIMIsEnabled(pVM));
257 VMCPU_ASSERT_EMT(pVCpu);
258
259 switch (pVM->gim.s.enmProviderId)
260 {
261 case GIMPROVIDERID_HYPERV:
262 return gimHvWriteMsr(pVCpu, idMsr, pRange, uRawValue);
263
264 case GIMPROVIDERID_KVM:
265 return gimKvmWriteMsr(pVCpu, idMsr, pRange, uRawValue);
266
267 default:
268 AssertMsgFailed(("GIMWriteMsr: for unknown provider %u idMsr=%#RX32 -> #GP(0)", pVM->gim.s.enmProviderId, idMsr));
269 return VERR_CPUM_RAISE_GP_0;
270 }
271}
272
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