- Timestamp:
- Sep 26, 2018 6:46:28 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/hm_vmx.h
r74468 r74469 2441 2441 * instructions. 2442 2442 * @{ */ 2443 typedef uint8_t VMXINSTRID; 2444 #define VMXINSTRID_VALID RT_BIT(7) 2445 #define VMXINSTRID_IS_VALID(a) (((a) >> 7) & 1) 2446 #define VMXINSTRID_GET_ID(a) ((a) & ~VMXINSTRID_VALID) 2443 typedef uint32_t VMXINSTRID; 2444 /** Whether the instruction ID field is valid. */ 2445 #define VMXINSTRID_VALID RT_BIT_32(31) 2446 /** Whether the instruction's primary operand in the Mod R/M byte (bits 0:3) is a 2447 * read or write. */ 2448 #define VMXINSTRID_MODRM_PRIMARY_OP_W RT_BIT_32(30) 2449 /** Gets whether the instruction ID is valid or not. */ 2450 #define VMXINSTRID_IS_VALID(a) (((a) >> 31) & 1) 2451 #define VMXINSTRID_IS_MODRM_PRIMARY_OP_W(a) (((a) >> 30) & 1) 2452 /** Gets the instruction ID. */ 2453 #define VMXINSTRID_GET_ID(a) ((a) & ~(VMXINSTRID_VALID | VMXINSTRID_MODRM_PRIMARY_OP_W)) 2454 /** No instruction ID info. */ 2447 2455 #define VMXINSTRID_NONE 0 2456 2448 2457 /** The OR'd rvalues are from the VT-x spec (valid bit is VBox specific): */ 2449 #define VMXINSTRID_SGDT ((VMXINSTRID_VALID) | 0) 2450 #define VMXINSTRID_SIDT ((VMXINSTRID_VALID) | 1) 2451 #define VMXINSTRID_LGDT ((VMXINSTRID_VALID) | 2) 2452 #define VMXINSTRID_LIDT ((VMXINSTRID_VALID) | 3) 2453 2454 #define VMXINSTRID_SLDT ((VMXINSTRID_VALID) | 0) 2455 #define VMXINSTRID_STR ((VMXINSTRID_VALID) | 1) 2456 #define VMXINSTRID_LLDT ((VMXINSTRID_VALID) | 2) 2457 #define VMXINSTRID_LTR ((VMXINSTRID_VALID) | 3) 2458 2459 /** The following are used internally and are not based on the VT-x spec: */ 2460 #define VMXINSTRID_VMLAUNCH ((VMXINSTRID_VALID) | 50) 2461 #define VMXINSTRID_VMRESUME ((VMXINSTRID_VALID) | 51) 2458 #define VMXINSTRID_SGDT (0x0 | VMXINSTRID_VALID | VMXINSTRID_MODRM_PRIMARY_OP_W) 2459 #define VMXINSTRID_SIDT (0x1 | VMXINSTRID_VALID | VMXINSTRID_MODRM_PRIMARY_OP_W) 2460 #define VMXINSTRID_LGDT (0x2 | VMXINSTRID_VALID) 2461 #define VMXINSTRID_LIDT (0x3 | VMXINSTRID_VALID) 2462 2463 #define VMXINSTRID_SLDT (0x0 | VMXINSTRID_VALID | VMXINSTRID_MODRM_PRIMARY_OP_W) 2464 #define VMXINSTRID_STR (0x1 | VMXINSTRID_VALID | VMXINSTRID_MODRM_PRIMARY_OP_W) 2465 #define VMXINSTRID_LLDT (0x2 | VMXINSTRID_VALID) 2466 #define VMXINSTRID_LTR (0x3 | VMXINSTRID_VALID) 2467 2468 /** The following IDs are used internally (some for logging, others for conveying 2469 * the ModR/M primary operand write bit): */ 2470 #define VMXINSTRID_VMLAUNCH (0x10 | VMXINSTRID_VALID) 2471 #define VMXINSTRID_VMRESUME (0x12 | VMXINSTRID_VALID) 2472 #define VMXINSTRID_VMWRITE (0x13 | VMXINSTRID_VALID | VMXINSTRID_MODRM_PRIMARY_OP_W) 2462 2473 /** @} */ 2463 2474 … … 3034 3045 /** The VM-exit instruction information. */ 3035 3046 VMXEXITINSTRINFO InstrInfo; 3036 /** Padding. */3037 uint32_t u32Padding0;3047 /** The VM-exit instruction ID. */ 3048 VMXINSTRID uInstrId; 3038 3049 3039 3050 /** The VM-exit qualification field. */ … … 3044 3055 * instruction VM-exit. */ 3045 3056 RTGCPTR GCPtrEffAddr; 3046 3047 /** The VM-exit instruction ID. */3048 VMXINSTRID uInstrId;3049 3057 } VMXVEXITINFO; 3050 3058 /** Pointer to the VMXVEXITINFO struct. */ … … 3052 3060 /** Pointer to a const VMXVEXITINFO struct. */ 3053 3061 typedef const VMXVEXITINFO *PCVMXVEXITINFO; 3062 AssertCompileMemberAlignment(VMXVEXITINFO, u64Qual, 8); 3054 3063 3055 3064 /** … … 3063 3072 * Intel but for our own requirements) as we use it to offset into guest memory. 3064 3073 * 3074 * Although the guest is supposed to access the VMCS only through the execution of 3075 * VMX instructions (VMREAD, VMWRITE etc.), since the VMCS may reside in guest 3076 * memory (e.g, active but not current VMCS), for saved-states compatibility, and 3077 * for teleportation purposes, any newly added fields should be added to the 3078 * appropriate reserved sections or at the end of the structure. 3079 * 3065 3080 * We always treat natural-width fields as 64-bit in our implementation since 3066 3081 * it's easier, allows for teleporation in the future and does not affect guest 3067 3082 * software. 3068 *3069 * Although the guest is supposed to access the VMCS only through the execution of3070 * VMX instructions (VMREAD, VMWRITE etc.), since the VMCS may reside in guest3071 * memory (e.g, active but not current VMCS), for saved-states compatibility, and3072 * for teleportation (when implemented) any newly added fields should be added to3073 * the appropriate reserved sections or at the end of the structure.3074 3083 */ 3075 3084 #pragma pack(1) -
trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h
r74468 r74469 877 877 * @param pVCpu The cross context virtual CPU structure. 878 878 * @param uExitReason The VM-exit reason. 879 * @param uInstrId The VM-exit instruction identity (VMXINSTRID_XXX) if 880 * any. Pass VMXINSTRID_NONE otherwise. 881 * @param fPrimaryOpRead If the primary operand of the ModR/M byte (bits 0:3) is 882 * a read or write. 879 * @param uInstrId The VM-exit instruction identity (VMXINSTRID_XXX). 883 880 * @param pGCPtrDisp Where to store the displacement field. Optional, can be 884 881 * NULL. 885 882 */ 886 IEM_STATIC uint32_t iemVmxGetExitInstrInfo(PVMCPU pVCpu, uint32_t uExitReason, VMXINSTRID uInstrId, bool fPrimaryOpRead, 887 PRTGCPTR pGCPtrDisp) 883 IEM_STATIC uint32_t iemVmxGetExitInstrInfo(PVMCPU pVCpu, uint32_t uExitReason, VMXINSTRID uInstrId, PRTGCPTR pGCPtrDisp) 888 884 { 889 885 RTGCPTR GCPtrDisp; … … 907 903 uint8_t idxReg1; 908 904 uint8_t idxReg2; 909 if ( fPrimaryOpRead)905 if (!VMXINSTRID_IS_MODRM_PRIMARY_OP_W(uInstrId)) 910 906 { 911 907 idxReg1 = ((bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK) | pVCpu->iem.s.uRexReg; … … 1153 1149 */ 1154 1150 uint8_t idxReg2; 1155 if ( fPrimaryOpRead)1151 if (!VMXINSTRID_IS_MODRM_PRIMARY_OP_W(uInstrId)) 1156 1152 { 1157 1153 idxReg2 = bRm & X86_MODRM_RM_MASK; … … 1187 1183 { 1188 1184 Assert(VMXINSTRID_IS_VALID(uInstrId)); 1185 Assert(VMXINSTRID_GET_ID(uInstrId) == (uInstrId & 0x3)); 1189 1186 ExitInstrInfo.GdtIdt.u2InstrId = VMXINSTRID_GET_ID(uInstrId); 1190 1187 ExitInstrInfo.GdtIdt.u2Undef0 = 0; … … 1195 1192 { 1196 1193 Assert(VMXINSTRID_IS_VALID(uInstrId)); 1194 Assert(VMXINSTRID_GET_ID(uInstrId) == (uInstrId & 0x3)); 1197 1195 ExitInstrInfo.LdtTr.u2InstrId = VMXINSTRID_GET_ID(uInstrId); 1198 1196 ExitInstrInfo.LdtTr.u2Undef0 = 0; … … 1211 1209 if (pGCPtrDisp) 1212 1210 *pGCPtrDisp = GCPtrDisp; 1211 1213 1212 return ExitInstrInfo.u; 1214 1213 } … … 3369 3368 3370 3369 /** 3370 * VMX VM-exit handler for VM-exits due to instruction execution. 3371 * 3372 * @param pVCpu The cross context virtual CPU structure. 3373 * @param uExitReason The VM-exit reason. 3374 * @param uInstrid The instruction identity (VMXINSTRID_XXX). 3375 * @param cbInstr The instruction length (in bytes). 3376 */ 3377 IEM_STATIC VBOXSTRICTRC iemVmxVmexitInstr(PVMCPU pVCpu, uint32_t uExitReason, VMXINSTRID uInstrId, uint8_t cbInstr) 3378 { 3379 /* Construct the VM-exit instruction information. */ 3380 RTGCPTR GCPtrDisp; 3381 uint32_t const uExitInstrInfo = iemVmxGetExitInstrInfo(pVCpu, uExitReason, uInstrId, &GCPtrDisp); 3382 3383 /* Update the VM-exit instruction information. */ 3384 iemVmxVmcsSetExitInstrInfo(pVCpu, uExitInstrInfo); 3385 3386 /* 3387 * Update the VM-exit qualification field with displacement bytes. 3388 * See Intel spec. 27.2.1 "Basic VM-Exit Information". 3389 */ 3390 switch (uExitReason) 3391 { 3392 case VMX_EXIT_INVEPT: 3393 case VMX_EXIT_INVPCID: 3394 case VMX_EXIT_LDTR_TR_ACCESS: 3395 case VMX_EXIT_GDTR_IDTR_ACCESS: 3396 case VMX_EXIT_VMCLEAR: 3397 case VMX_EXIT_VMPTRLD: 3398 case VMX_EXIT_VMPTRST: 3399 case VMX_EXIT_VMREAD: 3400 case VMX_EXIT_VMWRITE: 3401 case VMX_EXIT_VMXON: 3402 case VMX_EXIT_XRSTORS: 3403 case VMX_EXIT_XSAVES: 3404 case VMX_EXIT_RDRAND: 3405 case VMX_EXIT_RDSEED: 3406 iemVmxVmcsSetExitQual(pVCpu, GCPtrDisp); 3407 break; 3408 3409 default: 3410 AssertMsgFailedReturn(("Use instruction-specific handler\n"), VERR_IEM_IPE_5); 3411 } 3412 3413 /* Update the VM-exit instruction length field. */ 3414 Assert(cbInstr <= 15); 3415 iemVmxVmcsSetExitInstrLen(pVCpu, cbInstr); 3416 3417 /* Perform the VM-exit. */ 3418 return iemVmxVmexit(pVCpu, uExitReason); 3419 } 3420 3421 3422 /** 3371 3423 * Checks guest control registers, debug registers and MSRs as part of VM-entry. 3372 3424 * 3373 * @param pVCpu 3374 * @param pszInstr 3425 * @param pVCpu The cross context virtual CPU structure. 3426 * @param pszInstr The VMX instruction name (for logging purposes). 3375 3427 */ 3376 3428 IEM_STATIC int iemVmxVmentryCheckGuestControlRegsMsrs(PVMCPU pVCpu, const char *pszInstr) … … 3479 3531 IEM_VMX_VMENTRY_FAILED_RET(pVCpu, pszInstr, pszFailure, kVmxVDiag_Vmentry_GuestEferMsrRsvd); 3480 3532 3481 bool const fGstLma 3482 bool const fGstLme 3533 bool const fGstLma = RT_BOOL(pVmcs->u64HostEferMsr.u & MSR_K6_EFER_BIT_LMA); 3534 bool const fGstLme = RT_BOOL(pVmcs->u64HostEferMsr.u & MSR_K6_EFER_BIT_LME); 3483 3535 if ( fGstInLongMode == fGstLma 3484 3536 && ( !(pVmcs->u64GuestCr0.u & X86_CR0_PG)
Note:
See TracChangeset
for help on using the changeset viewer.