Changeset 347 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Jan 26, 2007 9:36:22 AM (18 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/EM.cpp
r318 r347 2058 2058 break; 2059 2059 } 2060 uint8_t u8Interrupt; 2061 2062 Assert(TRPMHasTrap(pVM)); 2063 Assert(!PATMIsPatchGCAddr(pVM, (RTGCPTR)pCtx->eip)); 2064 2065 if (TRPMHasTrap(pVM)) 2066 { 2067 u8Interrupt = TRPMGetTrapNo(pVM); 2068 2069 /* If the guest gate is marked unpatched, then we will check again if we can patch it. */ 2070 if (TRPMR3GetGuestTrapHandler(pVM, u8Interrupt) == TRPM_INVALID_HANDLER) 2071 { 2072 CSAMR3CheckGates(pVM, u8Interrupt, 1); 2073 Log(("emR3RawHandleRC: recheck gate %x -> valid=%d\n", u8Interrupt, TRPMR3GetGuestTrapHandler(pVM, u8Interrupt) != TRPM_INVALID_HANDLER)); 2074 /** @note If it was successful, then we could go back to raw mode, but let's keep things simple for now. */ 2075 } 2076 } 2060 2077 rc = emR3RawGuestTrap(pVM); 2061 2078 break; … … 2135 2152 */ 2136 2153 case VINF_EM_RAW_INTERRUPT_PENDING: 2154 case VINF_EM_RAW_RING_SWITCH_INT: 2137 2155 { 2138 2156 uint8_t u8Interrupt; … … 2145 2163 u8Interrupt = TRPMGetTrapNo(pVM); 2146 2164 2147 /* If the guest gate is marked dirty, then we will check again if we can patch it. */2148 if (TRPMR3 IsGuestTrapHandlerDirty(pVM, u8Interrupt))2165 /* If the guest gate is marked unpatched, then we will check again if we can patch it. */ 2166 if (TRPMR3GetGuestTrapHandler(pVM, u8Interrupt) == TRPM_INVALID_HANDLER) 2149 2167 { 2150 Assert(TRPMR3GetGuestTrapHandler(pVM, u8Interrupt) == TRPM_INVALID_HANDLER);2151 2168 CSAMR3CheckGates(pVM, u8Interrupt, 1); 2152 2169 Log(("emR3RawHandleRC: recheck gate %x -> valid=%d\n", u8Interrupt, TRPMR3GetGuestTrapHandler(pVM, u8Interrupt) != TRPM_INVALID_HANDLER)); … … 2157 2174 break; 2158 2175 } 2159 2160 case VINF_EM_RAW_RING_SWITCH_INT:2161 rc = VINF_EM_RESCHEDULE_REM;2162 break;2163 2176 2164 2177 /* -
trunk/src/VBox/VMM/PATM/CSAM.cpp
r209 r347 216 216 pVM->csam.s.fScanningStarted = false; 217 217 218 memset(&pVM->csam.s.aIDT[0], 0, sizeof(pVM->csam.s.aIDT));219 220 218 VM_FF_CLEAR(pVM, VM_FF_CSAM_FLUSH_DIRTY_PAGE); 221 219 pVM->csam.s.cDirtyPages = 0; … … 454 452 memcpy(pVM->csam.s.pvDirtyBasePage, csamInfo.pvDirtyBasePage, sizeof(pVM->csam.s.pvDirtyBasePage)); 455 453 memcpy(pVM->csam.s.pvDirtyFaultPage, csamInfo.pvDirtyFaultPage, sizeof(pVM->csam.s.pvDirtyFaultPage)); 456 457 /* Restore IDT gate info. */458 memcpy(&pVM->csam.s.aIDT[0], &csamInfo.aIDT[0], sizeof(pVM->csam.s.aIDT));459 454 460 455 /* Restore pgdir bitmap (we'll change the pointers next). */ … … 2161 2156 } 2162 2157 2158 /* We only check all gates once during a session */ 2159 if ( !pVM->csam.s.fGatesChecked 2160 && cGates != 256) 2161 return VINF_SUCCESS; /* too early */ 2162 2163 /* We only check all gates once during a session */ 2164 if ( pVM->csam.s.fGatesChecked 2165 && cGates != 1) 2166 return VINF_SUCCESS; /* ignored */ 2167 2168 if (cGates != 1) 2169 pVM->csam.s.fGatesChecked = true; 2170 2163 2171 Assert(GCPtrIDT && cGates <= 256); 2164 2172 if (!GCPtrIDT || cGates > 256) … … 2208 2216 for (/*iGate*/; iGate<iGateEnd; iGate++, pGuestIdte++) 2209 2217 { 2210 if ( pVM->csam.s.fGatesChecked 2211 && cGates != 1 /* applies only when we check the entire IDT */ 2212 && pGuestIdte->au64 != pVM->csam.s.aIDT[iGate].au64) 2213 { 2214 /* We can't check the contents here, as it might only have been partially modified at this point. 2215 * TRPMR3InjectEvent will recheck if necessary. 2216 */ 2217 #ifdef DEBUG 2218 RTGCPTR pHandler = (pGuestIdte->Gen.u16OffsetHigh << 16) | pGuestIdte->Gen.u16OffsetLow; 2219 2220 Log2(("IDT entry %x with handler %VGv refused (1)\n", iGate, pHandler)); 2221 #endif 2222 TRPMR3SetGuestTrapHandler(pVM, iGate, TRPM_INVALID_HANDLER); 2223 TRPMR3SetGuestTrapHandlerDirty(pVM, iGate, true); 2224 continue; 2225 } 2226 2227 TRPMR3SetGuestTrapHandlerDirty(pVM, iGate, false); 2218 Assert(TRPMR3GetGuestTrapHandler(pVM, iGate) == TRPM_INVALID_HANDLER); 2228 2219 2229 2220 if ( pGuestIdte->Gen.u1Present 2230 2221 && (pGuestIdte->Gen.u5Type2 == VBOX_IDTE_TYPE2_TRAP_32 || pGuestIdte->Gen.u5Type2 == VBOX_IDTE_TYPE2_INT_32) 2231 2222 && (pGuestIdte->Gen.u2DPL == 3 || pGuestIdte->Gen.u2DPL == 0) 2232 && pGuestIdte->au64 != pVM->csam.s.aIDT[iGate].au642233 2223 ) 2234 2224 { … … 2236 2226 CSAMP2GLOOKUPREC cacheRec = {0}; /* Cache record for PATMGCVirtToHCVirt. */ 2237 2227 PCSAMPAGE pPage = NULL; 2238 2239 /* Save a copy */2240 pVM->csam.s.aIDT[iGate].au64 = pGuestIdte->au64;2241 2242 /*2243 * Assume it's not safe.2244 */2245 TRPMR3SetGuestTrapHandler(pVM, iGate, TRPM_INVALID_HANDLER);2246 2228 2247 2229 pHandler = (pGuestIdte->Gen.u16OffsetHigh << 16) | pGuestIdte->Gen.u16OffsetLow; … … 2263 2245 { 2264 2246 Log(("CSAMCheckGates: csamAnalyseCodeStream failed with %d\n", rc)); 2247 continue; 2265 2248 } 2249 if (iGate >= 0x20) 2250 { 2251 /* OpenBSD guest specific patch test (3.7 & 3.8) */ 2252 rc = PATMR3InstallPatch(pVM, pHandler - 3, PATMFL_CODE32 | PATMFL_GUEST_SPECIFIC); 2253 if (VBOX_FAILURE(rc)) 2254 /* OpenBSD guest specific patch test (3.9 & 4.0) */ 2255 rc = PATMR3InstallPatch(pVM, pHandler - 0x2B, PATMFL_CODE32 | PATMFL_GUEST_SPECIFIC); 2256 if (VBOX_SUCCESS(rc)) 2257 Log(("Installed OpenBSD interrupt handler prefix instruction (push cs) patch\n")); 2258 } 2259 2260 /* Trap gates and certain interrupt gates. */ 2261 uint32_t fPatchFlags = PATMFL_CODE32 | PATMFL_IDTHANDLER; 2262 2263 if (pGuestIdte->Gen.u5Type2 == VBOX_IDTE_TYPE2_TRAP_32) 2264 fPatchFlags |= PATMFL_TRAPHANDLER; 2266 2265 else 2266 fPatchFlags |= PATMFL_INTHANDLER; 2267 2268 switch (iGate) { 2269 case 8: 2270 case 10: 2271 case 11: 2272 case 12: 2273 case 13: 2274 case 14: 2275 case 17: 2276 fPatchFlags |= PATMFL_TRAPHANDLER_WITH_ERRORCODE; 2277 break; 2278 default: 2279 /* No error code. */ 2280 break; 2281 } 2282 2283 Log(("Installing %s gate handler for 0x%X at %VGv\n", (pGuestIdte->Gen.u5Type2 == VBOX_IDTE_TYPE2_TRAP_32) ? "trap" : "intr", iGate, pHandler)); 2284 2285 rc = PATMR3InstallPatch(pVM, pHandler, fPatchFlags); 2286 if (VBOX_SUCCESS(rc) || rc == VERR_PATM_ALREADY_PATCHED) 2267 2287 { 2268 if (iGate >= 0x20) 2288 Log(("Gate handler 0x%X is SAFE!\n", iGate)); 2289 2290 RTGCPTR pNewHandlerGC = PATMR3QueryPatchGCPtr(pVM, pHandler); 2291 if (pNewHandlerGC) 2269 2292 { 2270 /* OpenBSD guest specific patch test (3.7 & 3.8) */ 2271 rc = PATMR3InstallPatch(pVM, pHandler - 3, PATMFL_CODE32 | PATMFL_GUEST_SPECIFIC); 2293 rc = TRPMR3SetGuestTrapHandler(pVM, iGate, pNewHandlerGC); 2272 2294 if (VBOX_FAILURE(rc)) 2273 /* OpenBSD guest specific patch test (3.9 & 4.0) */ 2274 rc = PATMR3InstallPatch(pVM, pHandler - 0x2B, PATMFL_CODE32 | PATMFL_GUEST_SPECIFIC); 2275 if (VBOX_SUCCESS(rc)) 2276 Log(("Installed OpenBSD interrupt handler prefix instruction (push cs) patch\n")); 2277 } 2278 2279 /* Trap gates and certain interrupt gates. */ 2280 uint32_t fPatchFlags = PATMFL_CODE32 | PATMFL_IDTHANDLER; 2281 2282 if (pGuestIdte->Gen.u5Type2 == VBOX_IDTE_TYPE2_TRAP_32) 2283 fPatchFlags |= PATMFL_TRAPHANDLER; 2284 else 2285 fPatchFlags |= PATMFL_INTHANDLER; 2286 2287 switch (iGate) { 2288 case 8: 2289 case 10: 2290 case 11: 2291 case 12: 2292 case 13: 2293 case 14: 2294 case 17: 2295 fPatchFlags |= PATMFL_TRAPHANDLER_WITH_ERRORCODE; 2296 break; 2297 default: 2298 /* No error code. */ 2299 break; 2300 } 2301 2302 Log(("Installing %s gate handler for 0x%X at %VGv\n", (pGuestIdte->Gen.u5Type2 == VBOX_IDTE_TYPE2_TRAP_32) ? "trap" : "intr", iGate, pHandler)); 2303 2304 rc = PATMR3InstallPatch(pVM, pHandler, fPatchFlags); 2305 if (VBOX_SUCCESS(rc) || rc == VERR_PATM_ALREADY_PATCHED) 2306 { 2307 RTGCPTR pNewHandlerGC; 2308 2309 Log(("Gate handler 0x%X is SAFE!\n", iGate)); 2310 2311 pNewHandlerGC = PATMR3QueryPatchGCPtr(pVM, pHandler); 2312 if (pNewHandlerGC) 2313 { 2314 rc = TRPMR3SetGuestTrapHandler(pVM, iGate, pNewHandlerGC); 2315 if (VBOX_FAILURE(rc)) 2316 Log(("TRPMR3SetGuestTrapHandler %d failed with %Vrc\n", iGate, rc)); 2317 } 2318 else 2319 Assert(0); 2295 Log(("TRPMR3SetGuestTrapHandler %d failed with %Vrc\n", iGate, rc)); 2320 2296 } 2321 2297 } 2322 2298 } 2323 else 2324 if (pGuestIdte->au64 != pVM->csam.s.aIDT[iGate].au64) 2325 { 2326 /* Save a copy */ 2327 pVM->csam.s.aIDT[iGate].au64 = pGuestIdte->au64; 2328 2329 #ifdef DEBUG 2330 RTGCPTR pHandler = (pGuestIdte->Gen.u16OffsetHigh << 16) | pGuestIdte->Gen.u16OffsetLow; 2331 2332 Log2(("IDT entry %x with handler %VGv refused (2)\n", iGate, pHandler)); 2333 #endif 2334 2335 /* 2336 * Everything is dangerous unless checked 2337 */ 2338 TRPMR3SetGuestTrapHandler(pVM, iGate, TRPM_INVALID_HANDLER); 2339 } 2340 #ifdef DEBUG 2341 else 2342 if (TRPMR3GetGuestTrapHandler(pVM, iGate) == TRPM_INVALID_HANDLER) 2343 { 2344 RTGCPTR pHandler = (pGuestIdte->Gen.u16OffsetHigh << 16) | pGuestIdte->Gen.u16OffsetLow; 2345 2346 Log2(("IDT entry %x with handler %VGv refused (3)\n", iGate, pHandler)); 2347 } 2348 #endif 2349 } 2299 } /* for */ 2350 2300 STAM_PROFILE_STOP(&pVM->csam.s.StatCheckGates, a); 2351 2352 pVM->csam.s.fGatesChecked = true;2353 2301 return VINF_SUCCESS; 2354 2302 } -
trunk/src/VBox/VMM/PATM/CSAMInternal.h
r23 r347 45 45 /** @} */ 46 46 47 #define CSAM_SSM_VERSION 1 247 #define CSAM_SSM_VERSION 13 48 48 49 49 #define CSAM_PGDIRBMP_CHUNKS 1024 … … 158 158 HCPTRTYPE(uint8_t **) pPDBitmapHC; 159 159 HCPTRTYPE(RTGCPTR *) pPDGCBitmapHC; 160 161 /* Saved IDT entries. */162 VBOXIDTE aIDT[256];163 160 164 161 /* Temporary storage during load/save state */ -
trunk/src/VBox/VMM/PATM/PATM.cpp
r302 r347 1594 1594 if (pCpu->pCurInstr->opcode == OP_CALL) 1595 1595 { 1596 if (PATMIsPatchGCAddr(pVM, pTargetGC)) 1597 { 1598 pTargetGC = PATMR3QueryPatchGCPtr(pVM, pTargetGC); 1599 if (pTargetGC == 0) 1600 return VERR_PATCHING_REFUSED; 1601 } 1602 1596 Assert(!PATMIsPatchGCAddr(pVM, pTargetGC)); 1603 1597 rc = patmPatchGenCall(pVM, pPatch, pCpu, pCurInstrGC, pTargetGC, false); 1604 1598 if (VBOX_FAILURE(rc)) … … 4863 4857 iGate = TRPMR3QueryGateByHandler(pVM, PATCHCODE_PTR_GC(pPatch)); 4864 4858 if (iGate != (uint32_t)~0) 4865 {4866 4859 TRPMR3SetGuestTrapHandler(pVM, iGate, TRPM_INVALID_HANDLER); 4867 TRPMR3SetGuestTrapHandlerDirty(pVM, iGate, false);4868 }4869 4860 } 4870 4861 … … 5542 5533 // Find the patch record 5543 5534 pPatchRec = (PPATMPATCHREC)RTAvloGCPtrGet(&pVM->patm.s.PatchLookupTreeHC->PatchTree, pAddrGC); 5544 if (pPatchRec)5545 {5535 /** @todo we should only use patches that are enabled! always did this, but it's incorrect! */ 5536 if (pPatchRec && (pPatchRec->patch.uState == PATCH_ENABLED || pPatchRec->patch.uState == PATCH_DIRTY)) 5546 5537 return PATCHCODE_PTR_GC(&pPatchRec->patch); 5547 } 5538 5548 5539 return 0; 5549 }5550 5551 /**5552 * Handle traps in patch code.5553 *5554 * The current guest trap has an EIP inside patch code space.5555 *5556 * @returns On success VINF_SUCCESS or between VINF_EM_FIRST and VINF_EM_LAST.5557 * @returns On failure appropriate status code.5558 * @param pVM VM Handle.5559 * @param rc The GC return code.5560 */5561 PATMR3DECL(int) PATMR3Trap(PVM pVM, int rc)5562 {5563 /** @todo Implement PATMR3Trap! */5564 return VERR_NOT_IMPLEMENTED;5565 5540 } 5566 5541 -
trunk/src/VBox/VMM/SELM.cpp
r106 r347 1478 1478 1479 1479 /** @todo handle these dependencies better! */ 1480 TRPMR3 ClearHandler(pVM, 0x2E);1481 TRPMR3 ClearHandler(pVM, 0x80);1480 TRPMR3SetGuestTrapHandler(pVM, 0x2E, TRPM_INVALID_HANDLER); 1481 TRPMR3SetGuestTrapHandler(pVM, 0x80, TRPM_INVALID_HANDLER); 1482 1482 pVM->selm.s.fSyncTSSRing0Stack = true; 1483 1483 } -
trunk/src/VBox/VMM/TRPM.cpp
r308 r347 441 441 AssertRelease(sizeof(pVM->trpm.s) <= sizeof(pVM->trpm.padding)); 442 442 AssertRelease(ELEMENTS(pVM->trpm.s.aGuestTrapHandler) == sizeof(pVM->trpm.s.au32IdtPatched)*8); 443 AssertRelease(ELEMENTS(pVM->trpm.s.aGuestTrapHandler) == sizeof(pVM->trpm.s.au32IdtDirty)*8);444 443 445 444 /* … … 723 722 SSMR3PutUInt(pSSM, VM_FF_ISSET(pVM, VM_FF_TRPM_SYNC_IDT)); 724 723 SSMR3PutMem(pSSM, &pTrpm->au32IdtPatched[0], sizeof(pTrpm->au32IdtPatched)); 725 SSMR3PutMem(pSSM, &pTrpm->au32IdtDirty[0], sizeof(pTrpm->au32IdtDirty));726 724 SSMR3PutU32(pSSM, ~0); /* separator. */ 727 725 … … 798 796 799 797 SSMR3GetMem(pSSM, &pTrpm->au32IdtPatched[0], sizeof(pTrpm->au32IdtPatched)); 800 SSMR3GetMem(pSSM, &pTrpm->au32IdtDirty[0], sizeof(pTrpm->au32IdtDirty));801 798 802 799 /* check the separator */ … … 866 863 if (fRawRing0 && CSAMIsEnabled(pVM)) 867 864 { 868 rc = CSAMR3CheckGates(pVM, 0, 256); /* check all gates */ 869 AssertRCReturn(rc, rc); 865 /* Clear all handlers */ 866 /** @todo inefficient, but simple */ 867 for (unsigned iGate=0;iGate<256;iGate++) 868 TRPMR3SetGuestTrapHandler(pVM, iGate, TRPM_INVALID_HANDLER); 869 870 /* Scan them all (only the first time) */ 871 CSAMR3CheckGates(pVM, 0, 256); 870 872 } 871 873 … … 994 996 995 997 996 #if 0 /* obsolete */ 997 /** 998 * Activate guest trap gate handler 999 * Used for setting up trap gates used for kernel calls. 998 /** 999 * Clear passthrough interrupt gate handler (reset to default handler) 1000 1000 * 1001 1001 * @returns VBox status code. 1002 1002 * @param pVM The VM to operate on. 1003 * @param iTrap Interrupt/trap number. 1004 */ 1005 TRPMR3DECL(int) TRPMR3EnableGuestTrapHandler(PVM pVM, unsigned iTrap) 1006 { 1007 /* 1008 * Validate. 1009 */ 1010 if (!EMIsRawRing0Enabled(pVM)) 1011 { 1012 AssertMsgFailed(("Enabling interrupt gates only works when raw ring 0 is enabled\n")); 1013 return VINF_SUCCESS; 1014 } 1015 if (iTrap < TRPM_HANDLER_INT_BASE || iTrap >= ELEMENTS(pVM->trpm.s.aIdt)) 1016 { 1017 AssertMsg(iTrap < TRPM_HANDLER_INT_BASE, ("Illegal gate number %d!\n", iTrap)); 1003 * @param iTrap Trap/interrupt gate number. 1004 */ 1005 TRPMR3DECL(int) trpmR3ClearPassThroughHandler(PVM pVM, unsigned iTrap) 1006 { 1007 /** @todo cleanup trpmR3ClearPassThroughHandler()! */ 1008 RTGCPTR aGCPtrs[TRPM_HANDLER_MAX]; 1009 int rc; 1010 1011 memset(aGCPtrs, 0, sizeof(aGCPtrs)); 1012 1013 rc = PDMR3GetSymbolGC(pVM, VMMGC_MAIN_MODULE_NAME, "TRPMGCHandlerInterupt", &aGCPtrs[TRPM_HANDLER_INT]); 1014 AssertReleaseMsgRC(rc, ("Couldn't find TRPMGCHandlerInterupt in VMMGC.gc!\n")); 1015 1016 if ( iTrap < TRPM_HANDLER_INT_BASE 1017 || iTrap >= ELEMENTS(pVM->trpm.s.aIdt)) 1018 { 1019 AssertMsg(iTrap < TRPM_HANDLER_INT_BASE, ("Illegal gate number %#x!\n", iTrap)); 1018 1020 return VERR_INVALID_PARAMETER; 1019 1021 } 1020 1021 uint16_t cbIDT; 1022 RTGCPTR GCPtrIDT = CPUMGetGuestIDTR(pVM, &cbIDT);1023 if (iTrap * sizeof(VBOXIDTE) >= cbIDT)1024 return VERR_INVALID_PARAMETER; /* Silently ignore out of range requests. */ 1025 1026 /*1027 * Read the guest IDT entry.1028 */1029 VBOXIDTE GuestIdte;1030 int rc = PGMPhysReadGCPtr(pVM, &GuestIdte, GCPtrIDT + iTrap * sizeof(GuestIdte), sizeof(GuestIdte));1031 if (VBOX_FAILURE(rc))1032 {1033 AssertMsgRC(rc, ("Failed to read IDTE! rc=%Vrc\n", rc)); 1034 return rc;1035 }1036 1037 if ( GuestIdte.Gen.u1Present1038 && GuestIdte.Gen.u5Type2 == VBOX_IDTE_TYPE2_TRAP_321039 && GuestIdte.Gen.u2DPL == 3)1040 {1041 LogFlow(("TRPMR3SetHandler: %X %04X:%04X%04X gate=%d dpl=%d present=%d\n", iTrap, 1042 GuestIdte.Gen.u16SegSel, GuestIdte.Gen.u16OffsetHigh, GuestIdte.Gen.u16OffsetLow,1043 GuestIdte.Gen.u5Type2, GuestIdte.Gen.u2DPL, GuestIdte.Gen.u1Present));1044 1045 PVBOXIDTE pIdte = &pVM->trpm.s.aIdt[iTrap];1046 GuestIdte.Gen.u16SegSel |= 1; // ring 11047 *pIdte = GuestIdte;1022 memcpy(&pVM->trpm.s.aIdt[iTrap], &g_aIdt[iTrap], sizeof(pVM->trpm.s.aIdt[0])); 1023 1024 /* Unmark it for relocation purposes. */ 1025 ASMBitClear(&pVM->trpm.s.au32IdtPatched[0], iTrap); 1026 1027 RTSEL SelCS = CPUMGetHyperCS(pVM); 1028 PVBOXIDTE pIdte = &pVM->trpm.s.aIdt[iTrap]; 1029 PVBOXIDTE_GENERIC pIdteTemplate = &g_aIdt[iTrap]; 1030 if (pIdte->Gen.u1Present) 1031 { 1032 Assert(pIdteTemplate->u16OffsetLow == TRPM_HANDLER_INT); 1033 Assert(sizeof(RTGCPTR) <= sizeof(aGCPtrs[0])); 1034 RTGCPTR Offset = (RTGCPTR)aGCPtrs[pIdteTemplate->u16OffsetLow]; 1035 1036 /* 1037 * Generic handlers have different entrypoints for each possible 1038 * vector number. These entrypoints make a sort of an array with 1039 * 8 byte entries where the vector number is the index. 1040 * See TRPMGCHandlersA.asm for details. 1041 */ 1042 Offset += iTrap * 8; 1043 1044 if (pIdte->Gen.u5Type2 != VBOX_IDTE_TYPE2_TASK) 1045 { 1046 pIdte->Gen.u16OffsetLow = Offset & 0xffff; 1047 pIdte->Gen.u16OffsetHigh = Offset >> 16; 1048 pIdte->Gen.u16SegSel = SelCS; 1049 } 1048 1050 } 1049 1051 1050 1052 return VINF_SUCCESS; 1051 1053 } 1052 #endif1053 1054 1054 1055 … … 1083 1084 1084 1085 /** 1085 * Marks IDT entry as dirty1086 *1087 * @returns Guest trap handler address or TRPM_INVALID_HANDLER if none installed1088 * @param pVM The VM to operate on.1089 * @param iTrap Interrupt/trap number.1090 * @param fSetDirty Set or clear1091 */1092 TRPMR3DECL(int) TRPMR3SetGuestTrapHandlerDirty(PVM pVM, unsigned iGate, bool fSetDirty)1093 {1094 AssertReturn(iGate < ELEMENTS(pVM->trpm.s.aIdt), VERR_INVALID_PARAMETER);1095 1096 if (fSetDirty)1097 ASMBitSet(&pVM->trpm.s.au32IdtDirty[0], iGate);1098 else1099 ASMBitClear(&pVM->trpm.s.au32IdtDirty[0], iGate);1100 1101 return VINF_SUCCESS;1102 }1103 1104 1105 /**1106 * Checks if IDT entry is dirty1107 *1108 * @returns dirty status1109 * @param pVM The VM to operate on.1110 * @param iTrap Interrupt/trap number.1111 */1112 TRPMR3DECL(bool) TRPMR3IsGuestTrapHandlerDirty(PVM pVM, unsigned iGate)1113 {1114 return ASMBitTest(&pVM->trpm.s.au32IdtDirty[0], iGate);1115 }1116 1117 1118 /**1119 1086 * Get guest trap/interrupt gate handler 1120 1087 * … … 1162 1129 /* clear trap handler */ 1163 1130 Log(("TRPMR3SetGuestTrapHandler: clear handler %x\n", iTrap)); 1131 1132 if (ASMBitTest(&pVM->trpm.s.au32IdtPatched[0], iTrap)) 1133 trpmR3ClearPassThroughHandler(pVM, iTrap); 1134 1164 1135 pVM->trpm.s.aGuestTrapHandler[iTrap] = TRPM_INVALID_HANDLER; 1165 1136 return VINF_SUCCESS; … … 1229 1200 } 1230 1201 return VERR_INVALID_PARAMETER; 1231 }1232 1233 1234 /**1235 * Clear interrupt gate handler (reset to default handler)1236 *1237 * @returns VBox status code.1238 * @param pVM The VM to operate on.1239 * @param iTrap Trap/interrupt gate number.1240 */1241 TRPMR3DECL(int) TRPMR3ClearHandler(PVM pVM, unsigned iTrap)1242 {1243 /** @todo cleanup TRPMR3ClearHandler()! */1244 RTGCPTR aGCPtrs[TRPM_HANDLER_MAX];1245 int rc;1246 1247 memset(aGCPtrs, 0, sizeof(aGCPtrs));1248 1249 rc = PDMR3GetSymbolGC(pVM, VMMGC_MAIN_MODULE_NAME, "TRPMGCHandlerInterupt", &aGCPtrs[TRPM_HANDLER_INT]);1250 AssertReleaseMsgRC(rc, ("Couldn't find TRPMGCHandlerInterupt in VMMGC.gc!\n"));1251 1252 if ( iTrap < TRPM_HANDLER_INT_BASE1253 || iTrap >= ELEMENTS(pVM->trpm.s.aIdt))1254 {1255 AssertMsg(iTrap < TRPM_HANDLER_INT_BASE, ("Illegal gate number %#x!\n", iTrap));1256 return VERR_INVALID_PARAMETER;1257 }1258 memcpy(&pVM->trpm.s.aIdt[iTrap], &g_aIdt[iTrap], sizeof(pVM->trpm.s.aIdt[0]));1259 1260 /* Unmark it for relocation purposes. */1261 ASMBitClear(&pVM->trpm.s.au32IdtPatched[0], iTrap);1262 1263 RTSEL SelCS = CPUMGetHyperCS(pVM);1264 PVBOXIDTE pIdte = &pVM->trpm.s.aIdt[iTrap];1265 PVBOXIDTE_GENERIC pIdteTemplate = &g_aIdt[iTrap];1266 if (pIdte->Gen.u1Present)1267 {1268 Assert(pIdteTemplate->u16OffsetLow == TRPM_HANDLER_INT);1269 Assert(sizeof(RTGCPTR) <= sizeof(aGCPtrs[0]));1270 RTGCPTR Offset = (RTGCPTR)aGCPtrs[pIdteTemplate->u16OffsetLow];1271 1272 /*1273 * Generic handlers have different entrypoints for each possible1274 * vector number. These entrypoints make a sort of an array with1275 * 8 byte entries where the vector number is the index.1276 * See TRPMGCHandlersA.asm for details.1277 */1278 Offset += iTrap * 8;1279 1280 if (pIdte->Gen.u5Type2 != VBOX_IDTE_TYPE2_TASK)1281 {1282 pIdte->Gen.u16OffsetLow = Offset & 0xffff;1283 pIdte->Gen.u16OffsetHigh = Offset >> 16;1284 pIdte->Gen.u16SegSel = SelCS;1285 }1286 }1287 1288 return VINF_SUCCESS;1289 1202 } 1290 1203 … … 1401 1314 return VINF_EM_RESCHEDULE_HWACC; 1402 1315 } 1403 /* If the guest gate is marked dirty, then we will check againif we can patch it. */1404 if ( TRPMR3IsGuestTrapHandlerDirty(pVM, u8Interrupt))1316 /* If the guest gate is not patched, then we will check (again) if we can patch it. */ 1317 if (pVM->trpm.s.aGuestTrapHandler[u8Interrupt] == TRPM_INVALID_HANDLER) 1405 1318 { 1406 Assert(TRPMR3GetGuestTrapHandler(pVM, u8Interrupt) == TRPM_INVALID_HANDLER);1407 1319 CSAMR3CheckGates(pVM, u8Interrupt, 1); 1408 1320 Log(("TRPMR3InjectEvent: recheck gate %x -> valid=%d\n", u8Interrupt, TRPMR3GetGuestTrapHandler(pVM, u8Interrupt) != TRPM_INVALID_HANDLER)); -
trunk/src/VBox/VMM/TRPMInternal.h
r23 r347 130 130 uint32_t au32IdtPatched[8]; 131 131 132 /** Bitmap for IDTEs that were changed. */133 uint32_t au32IdtDirty[8];134 135 132 /** Temporary Hypervisor trap handlers. 136 133 * NULL means default action. */ -
trunk/src/VBox/VMM/TRPMInternal.mac
r19 r347 47 47 .aIdt resd 512 48 48 .au32IdtPatched resd 8 49 .au32IdtDirty resd 850 49 .aTmpTrapHandlers resd 256 51 50
Note:
See TracChangeset
for help on using the changeset viewer.