Changeset 68226 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Aug 2, 2017 9:02:00 AM (7 years ago)
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
r67924 r68226 2624 2624 } 2625 2625 2626 2627 /** 2628 * Restores the host-state from the host-state save area as part of a \#VMEXIT. 2629 * 2630 * @param pVCpu The cross context virtual CPU structure of the calling EMT. 2631 * @param pCtx The guest-CPU context. 2632 */ 2633 VMM_INT_DECL(void) CPUMSvmVmExitRestoreHostState(PCPUMCTX pCtx) 2634 { 2635 /* 2636 * Reload the guest's "host state". 2637 */ 2638 PSVMHOSTSTATE pHostState = &pCtx->hwvirt.svm.HostState; 2639 pCtx->es = pHostState->es; 2640 pCtx->cs = pHostState->cs; 2641 pCtx->ss = pHostState->ss; 2642 pCtx->ds = pHostState->ds; 2643 pCtx->gdtr = pHostState->gdtr; 2644 pCtx->idtr = pHostState->idtr; 2645 pCtx->msrEFER = pHostState->uEferMsr; 2646 pCtx->cr0 = pHostState->uCr0 | X86_CR0_PE; 2647 pCtx->cr3 = pHostState->uCr3; 2648 pCtx->cr4 = pHostState->uCr4; 2649 pCtx->rflags = pHostState->rflags; 2650 pCtx->rflags.Bits.u1VM = 0; 2651 pCtx->rip = pHostState->uRip; 2652 pCtx->rsp = pHostState->uRsp; 2653 pCtx->rax = pHostState->uRax; 2654 pCtx->dr[7] &= ~(X86_DR7_ENABLED_MASK | X86_DR7_RAZ_MASK | X86_DR7_MBZ_MASK); 2655 pCtx->dr[7] |= X86_DR7_RA1_MASK; 2656 2657 /** @todo if RIP is not canonical or outside the CS segment limit, we need to 2658 * raise \#GP(0) in the guest. */ 2659 2660 /** @todo check the loaded host-state for consistency. Figure out what 2661 * exactly this involves? */ 2662 } 2663 2664 2665 /** 2666 * Saves the host-state to the host-state save area as part of a VMRUN. 2667 * 2668 * @param pVCpu The cross context virtual CPU structure of the calling EMT. 2669 * @param pCtx The guest-CPU context. 2670 * @param cbInstr The length of the VMRUN instruction in bytes. 2671 */ 2672 VMM_INT_DECL(void) CPUMSvmVmRunSaveHostState(PCPUMCTX pCtx, uint8_t cbInstr) 2673 { 2674 PSVMHOSTSTATE pHostState = &pCtx->hwvirt.svm.HostState; 2675 pHostState->es = pCtx->es; 2676 pHostState->cs = pCtx->cs; 2677 pHostState->ss = pCtx->ss; 2678 pHostState->ds = pCtx->ds; 2679 pHostState->gdtr = pCtx->gdtr; 2680 pHostState->idtr = pCtx->idtr; 2681 pHostState->uEferMsr = pCtx->msrEFER; 2682 pHostState->uCr0 = pCtx->cr0; 2683 pHostState->uCr3 = pCtx->cr3; 2684 pHostState->uCr4 = pCtx->cr4; 2685 pHostState->rflags = pCtx->rflags; 2686 pHostState->uRip = pCtx->rip + cbInstr; 2687 pHostState->uRsp = pCtx->rsp; 2688 pHostState->uRax = pCtx->rax; 2689 } 2690 -
trunk/src/VBox/VMM/VMMAll/HMSVMAll.cpp
r67529 r68226 258 258 } 259 259 260 261 /** 262 * Determines whether an IOIO intercept is active for the nested-guest or not. 263 * 264 * @param pvIoBitmap Pointer to the nested-guest IO bitmap. 265 * @param u16Port The IO port being accessed. 266 * @param enmIoType The type of IO access. 267 * @param cbReg The IO operand size in bytes. 268 * @param cAddrSizeBits The address size bits (for 16, 32 or 64). 269 * @param iEffSeg The effective segment number. 270 * @param fRep Whether this is a repeating IO instruction (REP prefix). 271 * @param fStrIo Whether this is a string IO instruction. 272 * @param pIoExitInfo Pointer to the SVMIOIOEXITINFO struct to be filled. 273 * Optional, can be NULL. 274 */ 275 VMM_INT_DECL(bool) HMSvmIsIOInterceptActive(void *pvIoBitmap, uint16_t u16Port, SVMIOIOTYPE enmIoType, uint8_t cbReg, 276 uint8_t cAddrSizeBits, uint8_t iEffSeg, bool fRep, bool fStrIo, 277 PSVMIOIOEXITINFO pIoExitInfo) 278 { 279 Assert(cAddrSizeBits == 0 || cAddrSizeBits == 16 || cAddrSizeBits == 32 || cAddrSizeBits == 64); 280 Assert(cbReg == 1 || cbReg == 2 || cbReg == 4 || cbReg == 8); 281 282 /* 283 * The IOPM layout: 284 * Each bit represents one 8-bit port. That makes a total of 0..65535 bits or 285 * two 4K pages. 286 * 287 * For IO instructions that access more than a single byte, the permission bits 288 * for all bytes are checked; if any bit is set to 1, the IO access is intercepted. 289 * 290 * Since it's possible to do a 32-bit IO access at port 65534 (accessing 4 bytes), 291 * we need 3 extra bits beyond the second 4K page. 292 */ 293 static const uint16_t s_auSizeMasks[] = { 0, 1, 3, 0, 0xf, 0, 0, 0 }; 294 295 uint16_t const offIopm = u16Port >> 3; 296 uint16_t const fSizeMask = s_auSizeMasks[(cAddrSizeBits >> SVM_IOIO_OP_SIZE_SHIFT) & 7]; 297 uint8_t const cShift = u16Port - (offIopm << 3); 298 uint16_t const fIopmMask = (1 << cShift) | (fSizeMask << cShift); 299 300 uint8_t const *pbIopm = (uint8_t *)pvIoBitmap; 301 Assert(pbIopm); 302 pbIopm += offIopm; 303 uint16_t const u16Iopm = *(uint16_t *)pbIopm; 304 if (u16Iopm & fIopmMask) 305 { 306 if (pIoExitInfo) 307 { 308 static const uint32_t s_auIoOpSize[] = 309 { SVM_IOIO_32_BIT_OP, SVM_IOIO_8_BIT_OP, SVM_IOIO_16_BIT_OP, 0, SVM_IOIO_32_BIT_OP, 0, 0, 0 }; 310 311 static const uint32_t s_auIoAddrSize[] = 312 { 0, SVM_IOIO_16_BIT_ADDR, SVM_IOIO_32_BIT_ADDR, 0, SVM_IOIO_64_BIT_ADDR, 0, 0, 0 }; 313 314 pIoExitInfo->u = s_auIoOpSize[cbReg & 7]; 315 pIoExitInfo->u |= s_auIoAddrSize[(cAddrSizeBits >> 4) & 7]; 316 pIoExitInfo->n.u1STR = fStrIo; 317 pIoExitInfo->n.u1REP = fRep; 318 pIoExitInfo->n.u3SEG = iEffSeg & 7; 319 pIoExitInfo->n.u1Type = enmIoType; 320 pIoExitInfo->n.u16Port = u16Port; 321 } 322 return true; 323 } 324 325 /** @todo remove later (for debugging as VirtualBox always traps all IO 326 * intercepts). */ 327 AssertMsgFailed(("iemSvmHandleIOIntercept: We expect an IO intercept here!\n")); 328 return false; 329 } 330 331 332 /** 333 * Notification callback for when a \#VMEXIT happens outside SVM R0 code (e.g. 334 * in IEM). 335 * 336 * @param pVCpu The cross context virtual CPU structure. 337 * @param pVmcbNstGst Pointer to the nested-guest VM control block. 338 * 339 * @sa hmR0SvmVmRunCacheVmcb. 340 */ 341 VMM_INT_DECL(void) HMSvmNstGstVmExitNotify(PVMCPU pVCpu, PSVMVMCB pVmcbNstGst) 342 { 343 PSVMVMCBCTRL pVmcbCtrl = &pVmcbNstGst->ctrl; 344 PSVMNESTEDVMCBCACHE pNstGstVmcbCache = &pVCpu->hm.s.svm.NstGstVmcbCache; 345 346 /* 347 * Restore the nested-guest VMCB fields which have been modified for executing 348 * the nested-guest under SVM R0. 349 */ 350 if (pNstGstVmcbCache->fValid) 351 { 352 pVmcbCtrl->u16InterceptRdCRx = pNstGstVmcbCache->u16InterceptRdCRx; 353 pVmcbCtrl->u16InterceptWrCRx = pNstGstVmcbCache->u16InterceptWrCRx; 354 pVmcbCtrl->u16InterceptRdCRx = pNstGstVmcbCache->u16InterceptRdCRx; 355 pVmcbCtrl->u16InterceptWrDRx = pNstGstVmcbCache->u16InterceptWrDRx; 356 pVmcbCtrl->u32InterceptXcpt = pNstGstVmcbCache->u32InterceptXcpt; 357 pVmcbCtrl->u64InterceptCtrl = pNstGstVmcbCache->u64InterceptCtrl; 358 pVmcbCtrl->u64VmcbCleanBits = pNstGstVmcbCache->u64VmcbCleanBits; 359 pVmcbCtrl->u64IOPMPhysAddr = pNstGstVmcbCache->u64IOPMPhysAddr; 360 pVmcbCtrl->u64MSRPMPhysAddr = pNstGstVmcbCache->u64MSRPMPhysAddr; 361 pVmcbCtrl->IntCtrl.n.u1VIntrMasking = pNstGstVmcbCache->fVIntrMasking; 362 pNstGstVmcbCache->fValid = false; 363 } 364 pNstGstVmcbCache->fVmrunEmulatedInR0 = false; 365 } 366
Note:
See TracChangeset
for help on using the changeset viewer.