Changeset 46165 in vbox for trunk/src/VBox/VMM/VMMR3/CPUM.cpp
- Timestamp:
- May 19, 2013 7:07:50 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 85865
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/CPUM.cpp
r46142 r46165 4194 4194 } 4195 4195 4196 #ifdef VBOX_WITH_RAW_MODE4197 4198 /**4199 * Transforms the guest CPU state to raw-ring mode.4200 *4201 * This function will change the any of the cs and ss register with DPL=0 to DPL=1.4202 *4203 * @returns VBox status. (recompiler failure)4204 * @param pVCpu Pointer to the VMCPU.4205 * @param pCtxCore The context core (for trap usage).4206 * @see @ref pg_raw4207 */4208 VMMR3DECL(int) CPUMR3RawEnter(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore)4209 {4210 PVM pVM = pVCpu->CTX_SUFF(pVM);4211 4212 Assert(!pVCpu->cpum.s.fRawEntered);4213 Assert(!pVCpu->cpum.s.fRemEntered);4214 if (!pCtxCore)4215 pCtxCore = CPUMCTX2CORE(&pVCpu->cpum.s.Guest);4216 4217 /*4218 * Are we in Ring-0?4219 */4220 if ( pCtxCore->ss.Sel4221 && (pCtxCore->ss.Sel & X86_SEL_RPL) == 04222 && !pCtxCore->eflags.Bits.u1VM)4223 {4224 /*4225 * Enter execution mode.4226 */4227 PATMRawEnter(pVM, pCtxCore);4228 4229 /*4230 * Set CPL to Ring-1.4231 */4232 pCtxCore->ss.Sel |= 1;4233 if ( pCtxCore->cs.Sel4234 && (pCtxCore->cs.Sel & X86_SEL_RPL) == 0)4235 pCtxCore->cs.Sel |= 1;4236 }4237 else4238 {4239 #ifdef VBOX_WITH_RAW_RING14240 if ( EMIsRawRing1Enabled(pVM)4241 && !pCtxCore->eflags.Bits.u1VM4242 && (pCtxCore->ss.Sel & X86_SEL_RPL) == 1)4243 {4244 /* Set CPL to Ring-2. */4245 pCtxCore->ss.Sel = (pCtxCore->ss.Sel & ~X86_SEL_RPL) | 2;4246 if (pCtxCore->cs.Sel && (pCtxCore->cs.Sel & X86_SEL_RPL) == 1)4247 pCtxCore->cs.Sel = (pCtxCore->cs.Sel & ~X86_SEL_RPL) | 2;4248 }4249 #else4250 AssertMsg((pCtxCore->ss.Sel & X86_SEL_RPL) >= 2 || pCtxCore->eflags.Bits.u1VM,4251 ("ring-1 code not supported\n"));4252 #endif4253 /*4254 * PATM takes care of IOPL and IF flags for Ring-3 and Ring-2 code as well.4255 */4256 PATMRawEnter(pVM, pCtxCore);4257 }4258 4259 /*4260 * Assert sanity.4261 */4262 AssertMsg((pCtxCore->eflags.u32 & X86_EFL_IF), ("X86_EFL_IF is clear\n"));4263 AssertReleaseMsg(pCtxCore->eflags.Bits.u2IOPL == 0,4264 ("X86_EFL_IOPL=%d CPL=%d\n", pCtxCore->eflags.Bits.u2IOPL, pCtxCore->ss.Sel & X86_SEL_RPL));4265 Assert((pVCpu->cpum.s.Guest.cr0 & (X86_CR0_PG | X86_CR0_WP | X86_CR0_PE)) == (X86_CR0_PG | X86_CR0_PE | X86_CR0_WP));4266 4267 pCtxCore->eflags.u32 |= X86_EFL_IF; /* paranoia */4268 4269 pVCpu->cpum.s.fRawEntered = true;4270 return VINF_SUCCESS;4271 }4272 4273 4274 /**4275 * Transforms the guest CPU state from raw-ring mode to correct values.4276 *4277 * This function will change any selector registers with DPL=1 to DPL=0.4278 *4279 * @returns Adjusted rc.4280 * @param pVCpu Pointer to the VMCPU.4281 * @param rc Raw mode return code4282 * @param pCtxCore The context core (for trap usage).4283 * @see @ref pg_raw4284 */4285 VMMR3DECL(int) CPUMR3RawLeave(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, int rc)4286 {4287 PVM pVM = pVCpu->CTX_SUFF(pVM);4288 4289 /*4290 * Don't leave if we've already left (in GC).4291 */4292 Assert(pVCpu->cpum.s.fRawEntered);4293 Assert(!pVCpu->cpum.s.fRemEntered);4294 if (!pVCpu->cpum.s.fRawEntered)4295 return rc;4296 pVCpu->cpum.s.fRawEntered = false;4297 4298 PCPUMCTX pCtx = &pVCpu->cpum.s.Guest;4299 if (!pCtxCore)4300 pCtxCore = CPUMCTX2CORE(pCtx);4301 Assert(pCtxCore->eflags.Bits.u1VM || (pCtxCore->ss.Sel & X86_SEL_RPL));4302 AssertMsg(pCtxCore->eflags.Bits.u1VM || pCtxCore->eflags.Bits.u2IOPL < (unsigned)(pCtxCore->ss.Sel & X86_SEL_RPL),4303 ("X86_EFL_IOPL=%d CPL=%d\n", pCtxCore->eflags.Bits.u2IOPL, pCtxCore->ss.Sel & X86_SEL_RPL));4304 4305 /*4306 * Are we executing in raw ring-1?4307 */4308 if ( (pCtxCore->ss.Sel & X86_SEL_RPL) == 14309 && !pCtxCore->eflags.Bits.u1VM)4310 {4311 /*4312 * Leave execution mode.4313 */4314 PATMRawLeave(pVM, pCtxCore, rc);4315 /* Not quite sure if this is really required, but shouldn't harm (too much anyways). */4316 /** @todo See what happens if we remove this. */4317 if ((pCtxCore->ds.Sel & X86_SEL_RPL) == 1)4318 pCtxCore->ds.Sel &= ~X86_SEL_RPL;4319 if ((pCtxCore->es.Sel & X86_SEL_RPL) == 1)4320 pCtxCore->es.Sel &= ~X86_SEL_RPL;4321 if ((pCtxCore->fs.Sel & X86_SEL_RPL) == 1)4322 pCtxCore->fs.Sel &= ~X86_SEL_RPL;4323 if ((pCtxCore->gs.Sel & X86_SEL_RPL) == 1)4324 pCtxCore->gs.Sel &= ~X86_SEL_RPL;4325 4326 /*4327 * Ring-1 selector => Ring-0.4328 */4329 pCtxCore->ss.Sel &= ~X86_SEL_RPL;4330 if ((pCtxCore->cs.Sel & X86_SEL_RPL) == 1)4331 pCtxCore->cs.Sel &= ~X86_SEL_RPL;4332 }4333 else4334 {4335 /*4336 * PATM is taking care of the IOPL and IF flags for us.4337 */4338 PATMRawLeave(pVM, pCtxCore, rc);4339 if (!pCtxCore->eflags.Bits.u1VM)4340 {4341 # ifdef VBOX_WITH_RAW_RING14342 if ( EMIsRawRing1Enabled(pVM)4343 && (pCtxCore->ss.Sel & X86_SEL_RPL) == 2)4344 {4345 /* Not quite sure if this is really required, but shouldn't harm (too much anyways). */4346 /** @todo See what happens if we remove this. */4347 if ((pCtxCore->ds.Sel & X86_SEL_RPL) == 2)4348 pCtxCore->ds.Sel = (pCtxCore->ds.Sel & ~X86_SEL_RPL) | 1;4349 if ((pCtxCore->es.Sel & X86_SEL_RPL) == 2)4350 pCtxCore->es.Sel = (pCtxCore->es.Sel & ~X86_SEL_RPL) | 1;4351 if ((pCtxCore->fs.Sel & X86_SEL_RPL) == 2)4352 pCtxCore->fs.Sel = (pCtxCore->fs.Sel & ~X86_SEL_RPL) | 1;4353 if ((pCtxCore->gs.Sel & X86_SEL_RPL) == 2)4354 pCtxCore->gs.Sel = (pCtxCore->gs.Sel & ~X86_SEL_RPL) | 1;4355 4356 /*4357 * Ring-2 selector => Ring-1.4358 */4359 pCtxCore->ss.Sel = (pCtxCore->ss.Sel & ~X86_SEL_RPL) | 1;4360 if ((pCtxCore->cs.Sel & X86_SEL_RPL) == 2)4361 pCtxCore->cs.Sel = (pCtxCore->cs.Sel & ~X86_SEL_RPL) | 1;4362 }4363 else4364 {4365 # endif4366 /** @todo See what happens if we remove this. */4367 if ((pCtxCore->ds.Sel & X86_SEL_RPL) == 1)4368 pCtxCore->ds.Sel &= ~X86_SEL_RPL;4369 if ((pCtxCore->es.Sel & X86_SEL_RPL) == 1)4370 pCtxCore->es.Sel &= ~X86_SEL_RPL;4371 if ((pCtxCore->fs.Sel & X86_SEL_RPL) == 1)4372 pCtxCore->fs.Sel &= ~X86_SEL_RPL;4373 if ((pCtxCore->gs.Sel & X86_SEL_RPL) == 1)4374 pCtxCore->gs.Sel &= ~X86_SEL_RPL;4375 # ifdef VBOX_WITH_RAW_RING14376 }4377 # endif4378 }4379 }4380 4381 return rc;4382 }4383 4384 #endif /* VBOX_WITH_RAW_MODE */4385 4386 4196 4387 4197 /**
Note:
See TracChangeset
for help on using the changeset viewer.