- Timestamp:
- Feb 7, 2012 8:29:04 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/vm.h
r39034 r40022 156 156 struct IEMCPU s; 157 157 #endif 158 uint8_t padding[ 1024]; /* multiple of 64 */158 uint8_t padding[3072]; /* multiple of 64 */ 159 159 } iem; 160 160 … … 215 215 216 216 /** Align the following members on page boundary. */ 217 uint8_t abAlignment2[ 3072];217 uint8_t abAlignment2[1024]; 218 218 219 219 /** PGM part. */ -
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r40001 r40022 569 569 static VBOXSTRICTRC iemRaiseSelectorInvalidAccess(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess); 570 570 static VBOXSTRICTRC iemRaisePageFault(PIEMCPU pIemCpu, RTGCPTR GCPtrWhere, uint32_t fAccess, int rc); 571 static VBOXSTRICTRC iemRaiseAlignmentCheckException(PIEMCPU pIemCpu); 571 572 static VBOXSTRICTRC iemMemMap(PIEMCPU pIemCpu, void **ppvMem, size_t cbMem, uint8_t iSegReg, RTGCPTR GCPtrMem, uint32_t fAccess); 572 573 static VBOXSTRICTRC iemMemCommitAndUnmap(PIEMCPU pIemCpu, void *pvMem, uint32_t fAccess); … … 2366 2367 2367 2368 2368 /** \#MF( n) - 10. */2369 /** \#MF(0) - 10. */ 2369 2370 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseMathFault(PIEMCPU pIemCpu) 2370 2371 { 2371 2372 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_MF, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0); 2373 } 2374 2375 2376 /** \#AC(0) - 11. */ 2377 DECL_NO_INLINE(static, VBOXSTRICTRC) iemRaiseAlignmentCheckException(PIEMCPU pIemCpu) 2378 { 2379 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_AC, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0); 2372 2380 } 2373 2381 … … 3859 3867 * memory. 3860 3868 * @param cbMem The number of bytes to map. This is usually 1, 3861 * 2, 4, 6, 8, 12, 16 or 32. When used by string3862 * operations it can be up to a page.3869 * 2, 4, 6, 8, 12, 16, 32 or 512. When used by 3870 * string operations it can be up to a page. 3863 3871 * @param iSegReg The index of the segment register to use for 3864 3872 * this access. The base and limits are checked. … … 3877 3885 * Check the input and figure out which mapping entry to use. 3878 3886 */ 3879 Assert(cbMem <= 32 );3887 Assert(cbMem <= 32 || cbMem == 512); 3880 3888 Assert(~(fAccess & ~(IEM_ACCESS_TYPE_MASK | IEM_ACCESS_WHAT_MASK))); 3881 3889 -
trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h
r40017 r40022 3303 3303 * Implements 'FXSAVE'. 3304 3304 * 3305 * @param iEffSeg The effective segment. 3305 3306 * @param GCPtrEff The address of the image. 3306 3307 * @param enmEffOpSize The operand size (only REX.W really matters). 3307 3308 */ 3308 IEM_CIMPL_DEF_ 2(iemCImpl_fxsave, RTGCPTR, GCPtrEff, IEMMODE, enmEffOpSize)3309 IEM_CIMPL_DEF_3(iemCImpl_fxsave, uint8_t, iEffSeg, RTGCPTR, GCPtrEff, IEMMODE, enmEffOpSize) 3309 3310 { 3310 3311 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx); 3311 3312 3313 /* 3314 * Raise exceptions. 3315 */ 3316 if (pCtx->cr0 & X86_CR0_EM) 3317 return iemRaiseUndefinedOpcode(pIemCpu); 3312 3318 if (pCtx->cr0 & (X86_CR0_TS | X86_CR0_EM)) 3313 3319 return iemRaiseDeviceNotAvailable(pIemCpu); 3314 if (GCPtrEff & 15) /** @todo \#AC */ 3320 if (GCPtrEff & 15) 3321 { 3322 /** @todo CPU/VM detection possible! \#AC might not be signal for 3323 * all/any misalignment sizes, intel says its an implementation detail. */ 3324 if ( (pCtx->cr0 & X86_CR0_AM) 3325 && pCtx->eflags.Bits.u1AC 3326 && pIemCpu->uCpl == 3) 3327 return iemRaiseAlignmentCheckException(pIemCpu); 3315 3328 return iemRaiseGeneralProtectionFault0(pIemCpu); 3316 3317 3318 return VERR_IEM_INSTR_NOT_IMPLEMENTED; 3329 } 3330 AssertReturn(iemFRegIsFxSaveFormat(pIemCpu), VERR_IEM_IPE_2); 3331 3332 /* 3333 * Access the memory. 3334 */ 3335 void *pvMem512; 3336 VBOXSTRICTRC rcStrict = iemMemMap(pIemCpu, &pvMem512, 512, iEffSeg, GCPtrEff, IEM_ACCESS_DATA_W); 3337 if (rcStrict != VINF_SUCCESS) 3338 return rcStrict; 3339 PX86FXSTATE pDst = (PX86FXSTATE)pvMem512; 3340 3341 /* 3342 * Store the registers. 3343 */ 3344 /** @todo CPU/VM detection possible! If CR4.OSFXSR=0 MXCSR it's 3345 * implementation specific whether MXCSR and XMM0-XMM7 are saved. */ 3346 3347 /* common for all formats */ 3348 pDst->FCW = pCtx->fpu.FCW; 3349 pDst->FSW = pCtx->fpu.FSW; 3350 pDst->FTW = pCtx->fpu.FTW & UINT16_C(0xff); 3351 pDst->FOP = pCtx->fpu.FOP; 3352 pDst->MXCSR = pCtx->fpu.MXCSR; 3353 pDst->MXCSR_MASK = pCtx->fpu.MXCSR_MASK; 3354 for (uint32_t i = 0; i < RT_ELEMENTS(pDst->aRegs); i++) 3355 { 3356 /** @todo Testcase: What actually happens to the 6 reserved bytes? I'm clearing 3357 * them for now... */ 3358 pDst->aRegs[i].au32[0] = pCtx->fpu.aRegs[i].au32[0]; 3359 pDst->aRegs[i].au32[1] = pCtx->fpu.aRegs[i].au32[1]; 3360 pDst->aRegs[i].au32[2] = pCtx->fpu.aRegs[i].au32[2] & UINT32_C(0xffff); 3361 pDst->aRegs[i].au32[3] = 0; 3362 } 3363 3364 /* FPU IP, CS, DP and DS. */ 3365 /** @todo FPU IP, CS, DP and DS cannot be implemented correctly without extra 3366 * state information. :-/ 3367 * Storing zeros now to prevent any potential leakage of host info. */ 3368 pDst->FPUIP = 0; 3369 pDst->CS = 0; 3370 pDst->Rsrvd1 = 0; 3371 pDst->FPUDP = 0; 3372 pDst->DS = 0; 3373 pDst->Rsrvd2 = 0; 3374 3375 /* XMM registers. */ 3376 if ( !(pCtx->msrEFER & MSR_K6_EFER_FFXSR) 3377 || pIemCpu->enmCpuMode != IEMMODE_64BIT 3378 || pIemCpu->uCpl != 0) 3379 { 3380 uint32_t cXmmRegs = enmEffOpSize == IEMMODE_64BIT ? 16 : 8; 3381 for (uint32_t i = 0; i < cXmmRegs; i++) 3382 pDst->aXMM[i] = pCtx->fpu.aXMM[i]; 3383 /** @todo Testcase: What happens to the reserved XMM registers? Untouched, 3384 * right? */ 3385 } 3386 3387 /* 3388 * Commit the memory. 3389 */ 3390 rcStrict = iemMemCommitAndUnmap(pIemCpu, pvMem512, IEM_ACCESS_DATA_W); 3391 if (rcStrict != VINF_SUCCESS) 3392 return rcStrict; 3393 3394 iemRegAddToRip(pIemCpu, cbInstr); 3395 return VINF_SUCCESS; 3319 3396 } 3320 3397 … … 3326 3403 * @param enmEffOpSize The operand size (only REX.W really matters). 3327 3404 */ 3328 IEM_CIMPL_DEF_ 2(iemCImpl_fxrstor, RTGCPTR, GCPtrEff, IEMMODE, enmEffOpSize)3405 IEM_CIMPL_DEF_3(iemCImpl_fxrstor, uint8_t, iEffSeg, RTGCPTR, GCPtrEff, IEMMODE, enmEffOpSize) 3329 3406 { 3330 3407 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx); 3331 3408 3409 /* 3410 * Raise exceptions. 3411 */ 3412 if (pCtx->cr0 & X86_CR0_EM) 3413 return iemRaiseUndefinedOpcode(pIemCpu); 3332 3414 if (pCtx->cr0 & (X86_CR0_TS | X86_CR0_EM)) 3333 3415 return iemRaiseDeviceNotAvailable(pIemCpu); 3334 if (GCPtrEff & 15) /** @todo \#AC */ 3416 if (GCPtrEff & 15) 3417 { 3418 /** @todo CPU/VM detection possible! \#AC might not be signal for 3419 * all/any misalignment sizes, intel says its an implementation detail. */ 3420 if ( (pCtx->cr0 & X86_CR0_AM) 3421 && pCtx->eflags.Bits.u1AC 3422 && pIemCpu->uCpl == 3) 3423 return iemRaiseAlignmentCheckException(pIemCpu); 3335 3424 return iemRaiseGeneralProtectionFault0(pIemCpu); 3336 3337 3338 return VERR_IEM_INSTR_NOT_IMPLEMENTED; 3425 } 3426 AssertReturn(iemFRegIsFxSaveFormat(pIemCpu), VERR_IEM_IPE_2); 3427 3428 /* 3429 * Access the memory. 3430 */ 3431 void *pvMem512; 3432 VBOXSTRICTRC rcStrict = iemMemMap(pIemCpu, &pvMem512, 512, iEffSeg, GCPtrEff, IEM_ACCESS_DATA_R); 3433 if (rcStrict != VINF_SUCCESS) 3434 return rcStrict; 3435 PCX86FXSTATE pSrc = (PCX86FXSTATE)pvMem512; 3436 3437 /* 3438 * Check the state for stuff which will GP(0). 3439 */ 3440 uint32_t const fMXCSR = pSrc->MXCSR; 3441 uint32_t const fMXCSR_MASK = pCtx->fpu.MXCSR_MASK ? pCtx->fpu.MXCSR_MASK : UINT32_C(0xffbf); 3442 if (fMXCSR & ~fMXCSR_MASK) 3443 { 3444 Log(("fxrstor: MXCSR=%#x (MXCSR_MASK=%#x) -> #GP(0)\n", fMXCSR, fMXCSR_MASK)); 3445 return iemRaiseGeneralProtectionFault0(pIemCpu); 3446 } 3447 3448 /* 3449 * Load the registers. 3450 */ 3451 /** @todo CPU/VM detection possible! If CR4.OSFXSR=0 MXCSR it's 3452 * implementation specific whether MXCSR and XMM0-XMM7 are restored. */ 3453 3454 /* common for all formats */ 3455 pCtx->fpu.FCW = pSrc->FCW; 3456 pCtx->fpu.FSW = pSrc->FSW; 3457 pCtx->fpu.FTW = pSrc->FTW & UINT16_C(0xff); 3458 pCtx->fpu.FOP = pSrc->FOP; 3459 pCtx->fpu.MXCSR = fMXCSR; 3460 /* (MXCSR_MASK is read-only) */ 3461 for (uint32_t i = 0; i < RT_ELEMENTS(pSrc->aRegs); i++) 3462 { 3463 pCtx->fpu.aRegs[i].au32[0] = pSrc->aRegs[i].au32[0]; 3464 pCtx->fpu.aRegs[i].au32[1] = pSrc->aRegs[i].au32[1]; 3465 pCtx->fpu.aRegs[i].au32[2] = pSrc->aRegs[i].au32[2] & UINT32_C(0xffff); 3466 pCtx->fpu.aRegs[i].au32[3] = 0; 3467 } 3468 3469 /* FPU IP, CS, DP and DS. */ 3470 if (pIemCpu->enmCpuMode == IEMMODE_64BIT) 3471 { 3472 pCtx->fpu.FPUIP = pSrc->FPUIP; 3473 pCtx->fpu.CS = pSrc->CS; 3474 pCtx->fpu.Rsrvd1 = pSrc->Rsrvd1; 3475 pCtx->fpu.FPUDP = pSrc->FPUDP; 3476 pCtx->fpu.DS = pSrc->DS; 3477 pCtx->fpu.Rsrvd2 = pSrc->Rsrvd2; 3478 } 3479 else 3480 { 3481 pCtx->fpu.FPUIP = pSrc->FPUIP; 3482 pCtx->fpu.CS = pSrc->CS; 3483 pCtx->fpu.Rsrvd1 = 0; 3484 pCtx->fpu.FPUDP = pSrc->FPUDP; 3485 pCtx->fpu.DS = pSrc->DS; 3486 pCtx->fpu.Rsrvd2 = 0; 3487 } 3488 3489 /* XMM registers. */ 3490 if ( !(pCtx->msrEFER & MSR_K6_EFER_FFXSR) 3491 || pIemCpu->enmCpuMode != IEMMODE_64BIT 3492 || pIemCpu->uCpl != 0) 3493 { 3494 uint32_t cXmmRegs = enmEffOpSize == IEMMODE_64BIT ? 16 : 8; 3495 for (uint32_t i = 0; i < cXmmRegs; i++) 3496 pCtx->fpu.aXMM[i] = pSrc->aXMM[i]; 3497 } 3498 3499 /* 3500 * Commit the memory. 3501 */ 3502 rcStrict = iemMemCommitAndUnmap(pIemCpu, pvMem512, IEM_ACCESS_DATA_R); 3503 if (rcStrict != VINF_SUCCESS) 3504 return rcStrict; 3505 3506 iemRegAddToRip(pIemCpu, cbInstr); 3507 return VINF_SUCCESS; 3339 3508 } 3340 3509 -
trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h
r40017 r40022 3369 3369 return IEMOP_RAISE_INVALID_LOCK_PREFIX(); 3370 3370 3371 IEM_MC_BEGIN(2, 1); 3372 IEM_MC_ARG(RTGCPTR, GCPtrEff, 0); 3373 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize,/*=*/pIemCpu->enmEffOpSize, 1); 3371 IEM_MC_BEGIN(3, 1); 3372 IEM_MC_ARG_CONST(uint8_t, iEffSeg,/*=*/pIemCpu->iEffSeg, 0); 3373 IEM_MC_ARG(RTGCPTR, GCPtrEff, 1); 3374 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize,/*=*/pIemCpu->enmEffOpSize, 2); 3374 3375 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm); 3375 IEM_MC_CALL_CIMPL_ 2(iemCImpl_fxsave, GCPtrEff, enmEffOpSize);3376 IEM_MC_CALL_CIMPL_3(iemCImpl_fxsave, iEffSeg, GCPtrEff, enmEffOpSize); 3376 3377 IEM_MC_END(); 3377 3378 return VINF_SUCCESS; … … 3387 3388 return IEMOP_RAISE_INVALID_LOCK_PREFIX(); 3388 3389 3389 IEM_MC_BEGIN(2, 1); 3390 IEM_MC_ARG(RTGCPTR, GCPtrEff, 0); 3391 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize,/*=*/pIemCpu->enmEffOpSize, 1); 3390 IEM_MC_BEGIN(3, 1); 3391 IEM_MC_ARG_CONST(uint8_t, iEffSeg,/*=*/pIemCpu->iEffSeg, 0); 3392 IEM_MC_ARG(RTGCPTR, GCPtrEff, 1); 3393 IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize,/*=*/pIemCpu->enmEffOpSize, 2); 3392 3394 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm); 3393 IEM_MC_CALL_CIMPL_ 2(iemCImpl_fxrstor, GCPtrEff, enmEffOpSize);3395 IEM_MC_CALL_CIMPL_3(iemCImpl_fxrstor, iEffSeg, GCPtrEff, enmEffOpSize); 3394 3396 IEM_MC_END(); 3395 3397 return VINF_SUCCESS; -
trunk/src/VBox/VMM/include/IEMInternal.h
r39989 r40022 266 266 struct 267 267 { 268 uint8_t ab[ 64];268 uint8_t ab[512]; 269 269 } aBounceBuffers[3]; 270 270
Note:
See TracChangeset
for help on using the changeset viewer.