Changeset 20343 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Jun 5, 2009 3:41:18 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
r20330 r20343 1705 1705 && pVM->hwaccm.s.fHasIoApic 1706 1706 && !(errCode & X86_TRAP_PF_P) /* not present */ 1707 && CPUMGetGuestCPL(pVCpu, CPUMCTX2CORE(pCtx)) == 0 1707 1708 && !CPUMIsGuestInLongModeEx(pCtx)) 1708 1709 { … … 2334 2335 } 2335 2336 2337 /** 2338 * Emulate simple mov tpr instruction 2339 * 2340 * @returns VBox status code. 2341 * @param pVCpu The VM CPU to operate on. 2342 * @param pDisState Disassembly state 2343 * @param pCtx CPU context 2344 * @param cbOp Opcode size 2345 */ 2346 static int svmR0EmulateTprMov(PVMCPU pVCpu, DISCPUSTATE *pDisState, PCPUMCTX pCtx, unsigned cbOp) 2347 { 2348 int rc; 2349 2350 if (pDisState->param1.flags == USE_DISPLACEMENT32) 2351 { 2352 /* write */ 2353 uint8_t u8Tpr; 2354 2355 /* Fetch the new TPR value */ 2356 if (pDisState->param2.flags == USE_REG_GEN32) 2357 { 2358 uint32_t val; 2359 2360 rc = DISFetchReg32(CPUMCTX2CORE(pCtx), pDisState->param2.base.reg_gen, &val); 2361 AssertRC(rc); 2362 u8Tpr = val >> 4; 2363 } 2364 else 2365 if (pDisState->param2.flags == USE_IMMEDIATE32) 2366 { 2367 u8Tpr = (uint8_t)pDisState->param2.parval >> 4; 2368 } 2369 else 2370 return VERR_EM_INTERPRETER; 2371 2372 rc = PDMApicSetTPR(pVCpu, u8Tpr); 2373 AssertRC(rc); 2374 2375 pCtx->rip += cbOp; 2376 return VINF_SUCCESS; 2377 } 2378 else 2379 if (pDisState->param2.flags == USE_DISPLACEMENT32) 2380 { 2381 /* read */ 2382 bool fPending; 2383 uint8_t u8Tpr; 2384 2385 /* TPR caching in CR8 */ 2386 rc = PDMApicGetTPR(pVCpu, &u8Tpr, &fPending); 2387 AssertRC(rc); 2388 2389 rc = DISWriteReg32(CPUMCTX2CORE(pCtx), pDisState->param1.base.reg_gen, u8Tpr << 4); 2390 AssertRC(rc); 2391 2392 pCtx->rip += cbOp; 2393 return VINF_SUCCESS; 2394 } 2395 return VERR_EM_INTERPRETER; 2396 } 2336 2397 2337 2398 /** … … 2355 2416 && Cpu.pCurInstr->opcode == OP_MOV) 2356 2417 { 2418 rc = svmR0EmulateTprMov(pVCpu, &Cpu, pCtx, cbOp); 2419 if (rc != VINF_SUCCESS) 2420 return rc; 2421 2357 2422 uint8_t szInstr[15]; 2358 2423 if ( cbOp == 10 … … 2369 2434 * 2370 2435 */ 2371 RTGCPTR oldEip = pCtx->eip;2372 2436 uint32_t u32tpr = (uint32_t)Cpu.param2.parval; 2373 2437 … … 2377 2441 * it does, then we can safely use it ourselves. 2378 2442 */ 2379 pCtx->eip += cbOp;2380 2443 rc = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), &Cpu, &cbOp); 2381 pCtx->eip = oldEip;2382 2444 if ( rc == VINF_SUCCESS 2383 2445 && Cpu.pCurInstr->opcode == OP_MOV … … 2410 2472 && cbOp == 6) 2411 2473 { 2412 RTGCPTR oldEip = pCtx->eip;2413 2474 RTGCPTR GCPtrTpr = (uint32_t)Cpu.param1.disp32; 2414 2475 uint32_t uMmioReg = Cpu.param2.base.reg_gen; … … 2419 2480 * mov ecx, dword [fffe0080] (5 bytes) 2420 2481 */ 2421 pCtx->eip += cbOp;2422 2482 rc = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), &Cpu, &cbOp); 2423 pCtx->eip = oldEip;2424 2483 if ( rc == VINF_SUCCESS 2425 2484 && Cpu.pCurInstr->opcode == OP_MOV … … 2453 2512 AssertRC(rc); 2454 2513 2455 Log(("Acceptable write candidate!\n"));2514 Log(("Acceptable read/write candidate!\n")); 2456 2515 return VINF_SUCCESS; 2457 2516 } … … 2461 2520 && cbOp == 5) 2462 2521 { 2463 RTGCPTR oldEip = pCtx->eip;2464 2522 uint32_t uMmioReg = Cpu.param1.base.reg_gen; 2465 2523 … … 2469 2527 * shr eax, 4 2470 2528 */ 2471 pCtx->eip += cbOp;2472 2529 rc = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), &Cpu, &cbOp); 2473 pCtx->eip = oldEip;2474 2530 if ( rc == VINF_SUCCESS 2475 2531 && Cpu.pCurInstr->opcode == OP_SHR … … 2495 2551 } 2496 2552 } 2553 /* Emulated successfully, so continue. */ 2554 return VINF_SUCCESS; 2497 2555 } 2498 2556 return VERR_ACCESS_DENIED;
Note:
See TracChangeset
for help on using the changeset viewer.