Changeset 68227 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Aug 2, 2017 9:03:02 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllCImplSvmInstr.cpp.h
r68150 r68227 120 120 * Save the nested-guest state into the VMCB state-save area. 121 121 */ 122 SVMVMCBSTATESAVE VmcbNstGst; 123 HMSVM_SEG_REG_COPY_TO_VMCB(pCtx, &VmcbNstGst, ES, es); 124 HMSVM_SEG_REG_COPY_TO_VMCB(pCtx, &VmcbNstGst, CS, cs); 125 HMSVM_SEG_REG_COPY_TO_VMCB(pCtx, &VmcbNstGst, SS, ss); 126 HMSVM_SEG_REG_COPY_TO_VMCB(pCtx, &VmcbNstGst, DS, ds); 127 VmcbNstGst.GDTR.u32Limit = pCtx->gdtr.cbGdt; 128 VmcbNstGst.GDTR.u64Base = pCtx->gdtr.pGdt; 129 VmcbNstGst.IDTR.u32Limit = pCtx->idtr.cbIdt; 130 VmcbNstGst.IDTR.u64Base = pCtx->idtr.pIdt; 131 VmcbNstGst.u64EFER = pCtx->msrEFER; 132 VmcbNstGst.u64CR4 = pCtx->cr4; 133 VmcbNstGst.u64CR3 = pCtx->cr3; 134 VmcbNstGst.u64CR2 = pCtx->cr2; 135 VmcbNstGst.u64CR0 = pCtx->cr0; 122 PSVMVMCB pVmcbNstGst = pCtx->hwvirt.svm.CTX_SUFF(pVmcb); 123 PSVMVMCBCTRL pVmcbNstGstCtrl = &pVmcbNstGst->ctrl; 124 PSVMVMCBSTATESAVE pVmcbNstGstState = &pVmcbNstGst->guest; 125 126 HMSVM_SEG_REG_COPY_TO_VMCB(pCtx, pVmcbNstGstState, ES, es); 127 HMSVM_SEG_REG_COPY_TO_VMCB(pCtx, pVmcbNstGstState, CS, cs); 128 HMSVM_SEG_REG_COPY_TO_VMCB(pCtx, pVmcbNstGstState, SS, ss); 129 HMSVM_SEG_REG_COPY_TO_VMCB(pCtx, pVmcbNstGstState, DS, ds); 130 pVmcbNstGstState->GDTR.u32Limit = pCtx->gdtr.cbGdt; 131 pVmcbNstGstState->GDTR.u64Base = pCtx->gdtr.pGdt; 132 pVmcbNstGstState->IDTR.u32Limit = pCtx->idtr.cbIdt; 133 pVmcbNstGstState->IDTR.u64Base = pCtx->idtr.pIdt; 134 pVmcbNstGstState->u64EFER = pCtx->msrEFER; 135 pVmcbNstGstState->u64CR4 = pCtx->cr4; 136 pVmcbNstGstState->u64CR3 = pCtx->cr3; 137 pVmcbNstGstState->u64CR2 = pCtx->cr2; 138 pVmcbNstGstState->u64CR0 = pCtx->cr0; 136 139 /** @todo Nested paging. */ 137 VmcbNstGst.u64RFlags = pCtx->rflags.u64;138 VmcbNstGst.u64RIP = pCtx->rip;139 VmcbNstGst.u64RSP = pCtx->rsp;140 VmcbNstGst.u64RAX = pCtx->rax;141 VmcbNstGst.u64DR7 = pCtx->dr[6];142 VmcbNstGst.u64DR6 = pCtx->dr[7];143 VmcbNstGst.u8CPL = pCtx->ss.Attr.n.u2Dpl; /* See comment in CPUMGetGuestCPL(). */140 pVmcbNstGstState->u64RFlags = pCtx->rflags.u64; 141 pVmcbNstGstState->u64RIP = pCtx->rip; 142 pVmcbNstGstState->u64RSP = pCtx->rsp; 143 pVmcbNstGstState->u64RAX = pCtx->rax; 144 pVmcbNstGstState->u64DR7 = pCtx->dr[6]; 145 pVmcbNstGstState->u64DR6 = pCtx->dr[7]; 146 pVmcbNstGstState->u8CPL = pCtx->ss.Attr.n.u2Dpl; /* See comment in CPUMGetGuestCPL(). */ 144 147 Assert(CPUMGetGuestCPL(pVCpu) == pCtx->ss.Attr.n.u2Dpl); 145 148 … … 201 204 202 205 /* 203 * Write back the VMCB controls to the guest VMCB in guest physical memory. 204 */ 205 VBOXSTRICTRC rcStrict = PGMPhysSimpleWriteGCPhys(pVCpu->CTX_SUFF(pVM), pCtx->hwvirt.svm.GCPhysVmcb, pVmcbCtrl, 206 sizeof(*pVmcbCtrl)); 206 * Notify HM in case the VMRUN was executed using SVM R0, HM would have modified some VMCB 207 * state that we need to restore on #VMEXIT before writing it back to guest memory. 208 */ 209 HMSvmNstGstVmExitNotify(pVCpu, pVmcbNstGst); 210 211 /* 212 * Write back the nested-guest's VMCB to its guest physical memory location. 213 */ 214 VBOXSTRICTRC rcStrict = PGMPhysSimpleWriteGCPhys(pVCpu->CTX_SUFF(pVM), pCtx->hwvirt.svm.GCPhysVmcb, pVmcbNstGst, 215 sizeof(*pVmcbNstGst)); 207 216 /* 208 217 * Prepare for guest's "host mode" by clearing internal processor state bits. 209 218 * 210 * Some of these like TSC offset can then be used unconditionally in our TM code211 * but the offset in the guest's VMCB will remain as it should as we've written212 * back the VMCB controls above.213 */ 214 memset(pVmcb Ctrl, 0, sizeof(*pVmcbCtrl));219 * We don't need to zero out the state-save area, just the controls should be 220 * sufficient because it has the critical bit of indicating whether we're inside 221 * the nested-guest or not. 222 */ 223 memset(pVmcbNstGstCtrl, 0, sizeof(*pVmcbNstGstCtrl)); 215 224 Assert(!CPUMIsGuestInSvmNestedHwVirtMode(pCtx)); 216 225 217 226 if (RT_SUCCESS(rcStrict)) 218 227 { 219 rcStrict = PGMPhysSimpleWriteGCPhys(pVCpu->CTX_SUFF(pVM), pCtx->hwvirt.svm.GCPhysVmcb + RT_OFFSETOF(SVMVMCB, guest), 220 &VmcbNstGst, sizeof(VmcbNstGst)); 228 /** @todo Nested paging. */ 229 /** @todo ASID. */ 230 231 /* 232 * Reload the guest's "host state". 233 */ 234 CPUMSvmVmExitRestoreHostState(pCtx); 235 236 /* 237 * Update PGM, IEM and others of a world-switch. 238 */ 239 rcStrict = iemSvmWorldSwitch(pVCpu, pCtx); 240 if (rcStrict == VINF_SUCCESS) 241 return VINF_SVM_VMEXIT; 242 221 243 if (RT_SUCCESS(rcStrict)) 222 244 { 223 /** @todo Nested paging. */ 224 /** @todo ASID. */ 225 226 /* 227 * Reload the guest's "host state". 228 */ 229 PSVMHOSTSTATE pHostState = &pCtx->hwvirt.svm.HostState; 230 pCtx->es = pHostState->es; 231 pCtx->cs = pHostState->cs; 232 pCtx->ss = pHostState->ss; 233 pCtx->ds = pHostState->ds; 234 pCtx->gdtr = pHostState->gdtr; 235 pCtx->idtr = pHostState->idtr; 236 pCtx->msrEFER = pHostState->uEferMsr; 237 pCtx->cr0 = pHostState->uCr0 | X86_CR0_PE; 238 pCtx->cr3 = pHostState->uCr3; 239 pCtx->cr4 = pHostState->uCr4; 240 pCtx->rflags = pHostState->rflags; 241 pCtx->rflags.Bits.u1VM = 0; 242 pCtx->rip = pHostState->uRip; 243 pCtx->rsp = pHostState->uRsp; 244 pCtx->rax = pHostState->uRax; 245 pCtx->dr[7] &= ~(X86_DR7_ENABLED_MASK | X86_DR7_RAZ_MASK | X86_DR7_MBZ_MASK); 246 pCtx->dr[7] |= X86_DR7_RA1_MASK; 247 248 /** @todo if RIP is not canonical or outside the CS segment limit, we need to 249 * raise \#GP(0) in the guest. */ 250 251 /** @todo check the loaded host-state for consistency. Figure out what 252 * exactly this involves? */ 253 254 /* Restore guest's force-flags. */ 255 if (pCtx->hwvirt.fLocalForcedActions) 256 { 257 VMCPU_FF_SET(pVCpu, pCtx->hwvirt.fLocalForcedActions); 258 pCtx->hwvirt.fLocalForcedActions = 0; 259 } 260 261 /* 262 * Update PGM, IEM and others of a world-switch. 263 */ 264 rcStrict = iemSvmWorldSwitch(pVCpu, pCtx); 265 if (rcStrict == VINF_SUCCESS) 266 return VINF_SVM_VMEXIT; 267 268 if (RT_SUCCESS(rcStrict)) 269 { 270 LogFlow(("iemSvmVmexit: Setting passup status from iemSvmWorldSwitch %Rrc\n", rcStrict)); 271 iemSetPassUpStatus(pVCpu, rcStrict); 272 return VINF_SVM_VMEXIT; 273 } 274 275 LogFlow(("iemSvmVmexit: iemSvmWorldSwitch unexpected failure. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 245 LogFlow(("iemSvmVmexit: Setting passup status from iemSvmWorldSwitch %Rrc\n", rcStrict)); 246 iemSetPassUpStatus(pVCpu, rcStrict); 247 return VINF_SVM_VMEXIT; 276 248 } 277 else 278 LogFlow(("iemSvmVmexit: Writing VMCB guest-state at %#RGp failed. rc=%Rrc\n", pCtx->hwvirt.svm.GCPhysVmcb, 279 VBOXSTRICTRC_VAL(rcStrict))); 249 250 LogFlow(("iemSvmVmexit: iemSvmWorldSwitch unexpected failure. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 280 251 } 281 252 else 282 LogFlow(("iemSvmVmexit: Writing VMCB guest-controlsat %#RGp failed. rc=%Rrc\n", pCtx->hwvirt.svm.GCPhysVmcb,253 LogFlow(("iemSvmVmexit: Writing VMCB at %#RGp failed. rc=%Rrc\n", pCtx->hwvirt.svm.GCPhysVmcb, 283 254 VBOXSTRICTRC_VAL(rcStrict))); 284 255 … … 326 297 * Save the host state. 327 298 */ 328 PSVMHOSTSTATE pHostState = &pCtx->hwvirt.svm.HostState; 329 pHostState->es = pCtx->es; 330 pHostState->cs = pCtx->cs; 331 pHostState->ss = pCtx->ss; 332 pHostState->ds = pCtx->ds; 333 pHostState->gdtr = pCtx->gdtr; 334 pHostState->idtr = pCtx->idtr; 335 pHostState->uEferMsr = pCtx->msrEFER; 336 pHostState->uCr0 = pCtx->cr0; 337 pHostState->uCr3 = pCtx->cr3; 338 pHostState->uCr4 = pCtx->cr4; 339 pHostState->rflags = pCtx->rflags; 340 pHostState->uRip = pCtx->rip + cbInstr; 341 pHostState->uRsp = pCtx->rsp; 342 pHostState->uRax = pCtx->rax; 299 CPUMSvmVmRunSaveHostState(pCtx, cbInstr); 343 300 344 301 /* … … 977 934 Log3(("iemSvmHandleIOIntercept: u16Port=%#x (%u)\n", u16Port, u16Port)); 978 935 936 #if 1 937 SVMIOIOEXITINFO IoExitInfo; 938 PCPUMCTX pCtx = IEM_GET_CTX(pVCpu); 939 void *pvIoBitmap = pCtx->hwvirt.svm.CTX_SUFF(pvIoBitmap); 940 bool const fIntercept = HMSvmIsIOInterceptActive(pvIoBitmap, u16Port, enmIoType, cbReg, cAddrSizeBits, iEffSeg, fRep, fStrIo, 941 &IoExitInfo); 942 if (fIntercept) 943 { 944 Log3(("iemSvmHandleIOIntercept: u16Port=%#x (%u) -> #VMEXIT\n", u16Port, u16Port)); 945 return iemSvmVmexit(pVCpu, pCtx, SVM_EXIT_IOIO, IoExitInfo.u, pCtx->rip + cbInstr); 946 } 947 #else 979 948 /* 980 949 * The IOPM layout: … … 1011 980 IoExitInfo.u = s_auIoOpSize[cbReg & 7]; 1012 981 IoExitInfo.u |= s_auIoAddrSize[(cAddrSizeBits >> 4) & 7]; 1013 IoExitInfo.n.u1STR = fStrIo;982 IoExitInfo.n.u1STR = iemSvmVmexitfStrIo; 1014 983 IoExitInfo.n.u1REP = fRep; 1015 984 IoExitInfo.n.u3SEG = iEffSeg & 7; … … 1021 990 return iemSvmVmexit(pVCpu, pCtx, SVM_EXIT_IOIO, IoExitInfo.u, pCtx->rip + cbInstr); 1022 991 } 992 #endif 1023 993 1024 994 /** @todo remove later (for debugging as VirtualBox always traps all IO
Note:
See TracChangeset
for help on using the changeset viewer.