/** * Allocates and maps one physically contiguous page. The allocated page is * zero'd out. * * @returns IPRT status code. * @param pMemObj Pointer to the ring-0 memory object. * @param ppVirt Where to store the virtual address of the * allocation. * @param pPhys Where to store the physical address of the * allocation. */ static int gimR0HvPageAllocZ(PRTR0MEMOBJ pMemObj, PRTR0PTR ppVirt, PRTHCPHYS pHCPhys) { AssertPtr(pMemObj); AssertPtr(ppVirt); AssertPtr(pHCPhys); int rc = RTR0MemObjAllocCont(pMemObj, PAGE_SIZE, false /* fExecutable */); if (RT_FAILURE(rc)) return rc; *ppVirt = RTR0MemObjAddress(*pMemObj); *pHCPhys = RTR0MemObjGetPagePhysAddr(*pMemObj, 0 /* iPage */); ASMMemZero32(*ppVirt, PAGE_SIZE); return VINF_SUCCESS; }
/** * OS specific allocation function. */ DECLHIDDEN(int) rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr) { IPRT_DARWIN_SAVE_EFL_AC(); if (RT_UNLIKELY(fFlags & RTMEMHDR_FLAG_ANY_CTX)) return VERR_NOT_SUPPORTED; PRTMEMHDR pHdr; if (fFlags & RTMEMHDR_FLAG_EXEC) { RTR0MEMOBJ hMemObj; int rc = RTR0MemObjAllocPage(&hMemObj, cb + sizeof(RTMEMDARWINHDREX), true /*fExecutable*/); if (RT_FAILURE(rc)) { IPRT_DARWIN_RESTORE_EFL_AC(); return rc; } PRTMEMDARWINHDREX pExHdr = (PRTMEMDARWINHDREX)RTR0MemObjAddress(hMemObj); pExHdr->hMemObj = hMemObj; pHdr = &pExHdr->Hdr; #if 1 /*fExecutable isn't currently honored above. */ rc = RTR0MemObjProtect(hMemObj, 0, RTR0MemObjSize(hMemObj), RTMEM_PROT_READ | RTMEM_PROT_WRITE | RTMEM_PROT_EXEC); AssertRC(rc); #endif } else { pHdr = (PRTMEMHDR)IOMalloc(cb + sizeof(*pHdr)); if (RT_UNLIKELY(!pHdr)) { printf("rtR0MemAllocEx(%#zx, %#x) failed\n", cb + sizeof(*pHdr), fFlags); IPRT_DARWIN_RESTORE_EFL_AC(); return VERR_NO_MEMORY; } } pHdr->u32Magic = RTMEMHDR_MAGIC; pHdr->fFlags = fFlags; pHdr->cb = cb; pHdr->cbReq = cb; *ppHdr = pHdr; IPRT_DARWIN_RESTORE_EFL_AC(); return VINF_SUCCESS; }
/** * Initalizes the triple fault / boot hack. * * Always call vmmR0TripleFaultHackTerm to clean up, even when this call fails. * * @returns VBox status code. */ int vmmR0TripleFaultHackInit(void) { /* * Map the first page. */ int rc = RTR0MemObjEnterPhys(&g_hMemPage0, 0, PAGE_SIZE, RTMEM_CACHE_POLICY_DONT_CARE); AssertRCReturn(rc, rc); rc = RTR0MemObjMapKernel(&g_hMapPage0, g_hMemPage0, (void *)-1, 0, RTMEM_PROT_READ | RTMEM_PROT_WRITE); AssertRCReturn(rc, rc); g_pbPage0 = (uint8_t *)RTR0MemObjAddress(g_hMapPage0); LogRel(("0040:0067 = %04x:%04x\n", RT_MAKE_U16(g_pbPage0[0x467+2], g_pbPage0[0x467+3]), RT_MAKE_U16(g_pbPage0[0x467+0], g_pbPage0[0x467+1]) )); /* * Allocate some "low core" memory. If that fails, just grab some memory. */ //rc = RTR0MemObjAllocPhys(&g_hMemLowCore, PAGE_SIZE, _1M - 1); //__debugbreak(); rc = RTR0MemObjEnterPhys(&g_hMemLowCore, 0x7000, PAGE_SIZE, RTMEM_CACHE_POLICY_DONT_CARE); AssertRCReturn(rc, rc); rc = RTR0MemObjMapKernel(&g_hMapLowCore, g_hMemLowCore, (void *)-1, 0, RTMEM_PROT_READ | RTMEM_PROT_WRITE); AssertRCReturn(rc, rc); g_pbLowCore = (uint8_t *)RTR0MemObjAddress(g_hMapLowCore); g_HCPhysLowCore = RTR0MemObjGetPagePhysAddr(g_hMapLowCore, 0); LogRel(("Low core at %RHp mapped at %p\n", g_HCPhysLowCore, g_pbLowCore)); /* * Save memory we'll be overwriting. */ g_pvSavedLowCore = RTMemAlloc(PAGE_SIZE); AssertReturn(g_pvSavedLowCore, VERR_NO_MEMORY); memcpy(g_pvSavedLowCore, g_pbLowCore, PAGE_SIZE); g_u32SavedVector = RT_MAKE_U32_FROM_U8(g_pbPage0[0x467], g_pbPage0[0x467+1], g_pbPage0[0x467+2], g_pbPage0[0x467+3]); g_u16SavedCadIndicator = RT_MAKE_U16(g_pbPage0[0x472], g_pbPage0[0x472+1]); /* * Install the code. */ size_t cbCode = (uintptr_t)&vmmR0TripleFaultHackEnd - (uintptr_t)&vmmR0TripleFaultHackStart; AssertLogRelReturn(cbCode <= PAGE_SIZE, VERR_OUT_OF_RANGE); memcpy(g_pbLowCore, &vmmR0TripleFaultHackStart, cbCode); g_pbPage0[0x467+0] = 0x00; g_pbPage0[0x467+1] = 0x70; g_pbPage0[0x467+2] = 0x00; g_pbPage0[0x467+3] = 0x00; g_pbPage0[0x472+0] = 0x34; g_pbPage0[0x472+1] = 0x12; /* * Configure the status port and cmos shutdown command. */ uint32_t fSaved = ASMIntDisableFlags(); ASMOutU8(0x70, 0x0f); ASMOutU8(0x71, 0x0a); ASMOutU8(0x70, 0x05); ASMInU8(0x71); ASMReloadCR3(); ASMWriteBackAndInvalidateCaches(); ASMSetFlags(fSaved); #if 1 /* For testing & debugging. */ vmmR0TripleFaultHackTripleFault(); #endif return VINF_SUCCESS; }