/** * Try undo the harm done by the init function. * * This may leave the system in an unstable state since we might have been * hijacking memory below 1MB that is in use by the kernel. */ void vmmR0TripleFaultHackTerm(void) { /* * Restore overwritten memory. */ if ( g_pvSavedLowCore && g_pbLowCore) memcpy(g_pbLowCore, g_pvSavedLowCore, PAGE_SIZE); if (g_pbPage0) { g_pbPage0[0x467+0] = RT_BYTE1(g_u32SavedVector); g_pbPage0[0x467+1] = RT_BYTE2(g_u32SavedVector); g_pbPage0[0x467+2] = RT_BYTE3(g_u32SavedVector); g_pbPage0[0x467+3] = RT_BYTE4(g_u32SavedVector); g_pbPage0[0x472+0] = RT_BYTE1(g_u16SavedCadIndicator); g_pbPage0[0x472+1] = RT_BYTE2(g_u16SavedCadIndicator); } /* * Fix the CMOS. */ if (g_pvSavedLowCore) { uint32_t fSaved = ASMIntDisableFlags(); ASMOutU8(0x70, 0x0f); ASMOutU8(0x71, 0x0a); ASMOutU8(0x70, 0x00); ASMInU8(0x71); ASMReloadCR3(); ASMWriteBackAndInvalidateCaches(); ASMSetFlags(fSaved); } /* * Release resources. */ RTMemFree(g_pvSavedLowCore); g_pvSavedLowCore = NULL; RTR0MemObjFree(g_hMemLowCore, true /*fFreeMappings*/); g_hMemLowCore = NIL_RTR0MEMOBJ; g_hMapLowCore = NIL_RTR0MEMOBJ; g_pbLowCore = NULL; g_HCPhysLowCore = NIL_RTHCPHYS; RTR0MemObjFree(g_hMemPage0, true /*fFreeMappings*/); g_hMemPage0 = NIL_RTR0MEMOBJ; g_hMapPage0 = NIL_RTR0MEMOBJ; g_pbPage0 = NULL; }
/** * Frees and unmaps an allocated physical page. * * @param pMemObj Pointer to the ring-0 memory object. * @param ppVirt Where to re-initialize the virtual address of * allocation as 0. * @param pHCPhys Where to re-initialize the physical address of the * allocation as 0. */ static void gimR0HvPageFree(PRTR0MEMOBJ pMemObj, PRTR0PTR ppVirt, PRTHCPHYS pHCPhys) { AssertPtr(pMemObj); AssertPtr(ppVirt); AssertPtr(pHCPhys); if (*pMemObj != NIL_RTR0MEMOBJ) { int rc = RTR0MemObjFree(*pMemObj, true /* fFreeMappings */); AssertRC(rc); *pMemObj = NIL_RTR0MEMOBJ; *ppVirt = 0; *pHCPhys = 0; } }
/** * OS specific free function. */ DECLHIDDEN(void) rtR0MemFree(PRTMEMHDR pHdr) { IPRT_DARWIN_SAVE_EFL_AC(); pHdr->u32Magic += 1; if (pHdr->fFlags & RTMEMHDR_FLAG_EXEC) { PRTMEMDARWINHDREX pExHdr = RT_FROM_MEMBER(pHdr, RTMEMDARWINHDREX, Hdr); int rc = RTR0MemObjFree(pExHdr->hMemObj, false /*fFreeMappings*/); AssertRC(rc); } else IOFree(pHdr, pHdr->cb + sizeof(*pHdr)); IPRT_DARWIN_RESTORE_EFL_AC(); }
void VBOXCALL supdrvOSLdrUnload(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage) { if (pImage->pvNtSectionObj) { if (pImage->hMemLock != NIL_RTR0MEMOBJ) { RTR0MemObjFree(pImage->hMemLock, false /*fFreeMappings*/); pImage->hMemLock = NIL_RTR0MEMOBJ; } NTSTATUS rcNt = ZwSetSystemInformation(MY_SystemUnloadGdiDriverInformation, &pImage->pvNtSectionObj, sizeof(pImage->pvNtSectionObj)); if (rcNt != STATUS_SUCCESS) SUPR0Printf("VBoxDrv: failed to unload '%s', rcNt=%#x\n", pImage->szName, rcNt); pImage->pvNtSectionObj = NULL; } NOREF(pDevExt); }
void vbglUnlockLinear (void *pvCtx, void *pv, uint32_t u32Size) { #ifdef RT_OS_WINDOWS PMDL pMdl = (PMDL)pvCtx; Assert(pMdl); if (pMdl != NULL) { MmUnlockPages (pMdl); IoFreeMdl (pMdl); } #else RTR0MEMOBJ MemObj = (RTR0MEMOBJ)pvCtx; int rc = RTR0MemObjFree(MemObj, false); AssertRC(rc); #endif NOREF(pv); NOREF(u32Size); }
DECLHIDDEN(int) rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable) { AssertMsgReturn(cb <= _1G, ("%#x\n", cb), VERR_OUT_OF_RANGE); /* for safe size_t -> ULONG */ /* * Try see if we get lucky first... * (We could probably just assume we're lucky on NT4.) */ int rc = rtR0MemObjNativeAllocPage(ppMem, cb, fExecutable); if (RT_SUCCESS(rc)) { size_t iPage = cb >> PAGE_SHIFT; while (iPage-- > 0) if (rtR0MemObjNativeGetPagePhysAddr(*ppMem, iPage) >= _4G) { rc = VERR_NO_LOW_MEMORY; break; } if (RT_SUCCESS(rc)) return rc; /* The following ASSUMES that rtR0MemObjNativeAllocPage returns a completed object. */ RTR0MemObjFree(*ppMem, false); *ppMem = NULL; } #ifndef IPRT_TARGET_NT4 /* * Use MmAllocatePagesForMdl to specify the range of physical addresses we wish to use. */ PHYSICAL_ADDRESS Zero; Zero.QuadPart = 0; PHYSICAL_ADDRESS HighAddr; HighAddr.QuadPart = _4G - 1; PMDL pMdl = MmAllocatePagesForMdl(Zero, HighAddr, Zero, cb); if (pMdl) { if (MmGetMdlByteCount(pMdl) >= cb) { __try { void *pv = MmMapLockedPagesSpecifyCache(pMdl, KernelMode, MmCached, NULL /* no base address */, FALSE /* no bug check on failure */, NormalPagePriority); if (pv) { PRTR0MEMOBJNT pMemNt = (PRTR0MEMOBJNT)rtR0MemObjNew(sizeof(*pMemNt), RTR0MEMOBJTYPE_LOW, pv, cb); if (pMemNt) { pMemNt->fAllocatedPagesForMdl = true; pMemNt->cMdls = 1; pMemNt->apMdls[0] = pMdl; *ppMem = &pMemNt->Core; return VINF_SUCCESS; } MmUnmapLockedPages(pv, pMdl); } } __except(EXCEPTION_EXECUTE_HANDLER) { NTSTATUS rcNt = GetExceptionCode(); Log(("rtR0MemObjNativeAllocLow: Exception Code %#x\n", rcNt)); /* nothing */ } } MmFreePagesFromMdl(pMdl); ExFreePool(pMdl); }