/* * PROJECT: ReactOS kernel-mode tests * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory * PURPOSE: Kernel-Mode Test Suite Reserved Mapping test * PROGRAMMER: Thomas Faber */ #include #ifdef _M_IX86 #define PTE_BASE 0xC0000000 #define MiAddressToPte(x) \ ((PMMPTE)(((((ULONG)(x)) >> 12) << 2) + PTE_BASE)) #define MiPteToAddress(_Pte) ((PVOID)((ULONG)(_Pte) << 10)) #elif defined(_M_AMD64) #define PTI_SHIFT 12L #define PTE_BASE 0xFFFFF68000000000ULL PMMPTE FORCEINLINE _MiAddressToPte(PVOID Address) { ULONG64 Offset = (ULONG64)Address >> (PTI_SHIFT - 3); Offset &= 0xFFFFFFFFFULL << 3; return (PMMPTE)(PTE_BASE + Offset); } #define MiAddressToPte(x) _MiAddressToPte((PVOID)(x)) #endif static BOOLEAN ValidateMapping( _In_ PVOID BaseAddress, _In_ ULONG TotalPtes, _In_ ULONG ValidPtes, _In_ PPFN_NUMBER Pfns) { BOOLEAN Valid = TRUE; #if defined(_M_IX86) || defined(_M_AMD64) PMMPTE PointerPte; ULONG i; PointerPte = MiAddressToPte(BaseAddress); for (i = 0; i < ValidPtes; i++) { Valid = Valid && ok(PointerPte[i].u.Hard.Valid == 1, "[%lu] PTE %p is not valid\n", i, &PointerPte[i]); Valid = Valid && ok(PointerPte[i].u.Hard.PageFrameNumber == Pfns[i], "[%lu] PTE %p has PFN %Ix, expected %Ix\n", i, &PointerPte[i], PointerPte[i].u.Hard.PageFrameNumber, Pfns[i]); } for (; i < TotalPtes; i++) { Valid = Valid && ok_eq_hex(PointerPte[i].u.Long, 0UL); } Valid = Valid && ok_eq_tag(PointerPte[-1].u.Long, 'MRmK' & ~1); Valid = Valid && ok_eq_ulong(PointerPte[-2].u.Long, (TotalPtes + 2) * 2); #endif return Valid; } static VOID TestMap( _In_ PVOID Mapping) { PMDL Mdl; PHYSICAL_ADDRESS ZeroPhysical; PHYSICAL_ADDRESS MaxPhysical; PVOID BaseAddress; PPFN_NUMBER MdlPages; ULONG i; ZeroPhysical.QuadPart = 0; MaxPhysical.QuadPart = 0xffffffffffffffffLL; /* Create a one-page MDL and map it */ Mdl = MmAllocatePagesForMdlEx(ZeroPhysical, MaxPhysical, ZeroPhysical, PAGE_SIZE, MmCached, 0); if (skip(Mdl != NULL, "No MDL\n")) { return; } MdlPages = (PVOID)(Mdl + 1); BaseAddress = MmMapLockedPagesWithReservedMapping(Mapping, 'MRmK', Mdl, MmCached); if (BaseAddress) { ok_eq_pointer(BaseAddress, Mapping); ok_bool_true(ValidateMapping(BaseAddress, 10, 1, MdlPages), "ValidateMapping returned"); KmtStartSeh() *(volatile ULONG *)BaseAddress = 0x01234567; KmtEndSeh(STATUS_SUCCESS); MmUnmapReservedMapping(BaseAddress, 'MRmK', Mdl); ok_bool_true(ValidateMapping(Mapping, 10, 0, NULL), "ValidateMapping returned"); } MmFreePagesFromMdl(Mdl); /* Map all pages */ Mdl = MmAllocatePagesForMdlEx(ZeroPhysical, MaxPhysical, ZeroPhysical, 10 * PAGE_SIZE, MmCached, 0); if (skip(Mdl != NULL, "No MDL\n")) { return; } MdlPages = (PVOID)(Mdl + 1); BaseAddress = MmMapLockedPagesWithReservedMapping(Mapping, 'MRmK', Mdl, MmCached); if (BaseAddress) { ok_eq_pointer(BaseAddress, Mapping); ok_bool_true(ValidateMapping(BaseAddress, 10, 10, MdlPages), "ValidateMapping returned"); for (i = 0; i < 10; i++) { KmtStartSeh() *((volatile ULONG *)BaseAddress + i * PAGE_SIZE / sizeof(ULONG)) = 0x01234567; KmtEndSeh(STATUS_SUCCESS); } MmUnmapReservedMapping(BaseAddress, 'MRmK', Mdl); ok_bool_true(ValidateMapping(Mapping, 10, 0, NULL), "ValidateMapping returned"); } MmFreePagesFromMdl(Mdl); /* Try to map more pages than we reserved */ Mdl = MmAllocatePagesForMdlEx(ZeroPhysical, MaxPhysical, ZeroPhysical, 11 * PAGE_SIZE, MmCached, 0); if (skip(Mdl != NULL, "No MDL\n")) { return; } BaseAddress = MmMapLockedPagesWithReservedMapping(Mapping, 'MRmK', Mdl, MmCached); ok_eq_pointer(BaseAddress, NULL); if (BaseAddress) { MmUnmapReservedMapping(BaseAddress, 'MRmK', Mdl); } MmFreePagesFromMdl(Mdl); } START_TEST(MmReservedMapping) { PVOID Mapping; /* one byte - single page */ Mapping = MmAllocateMappingAddress(1, 'MRmK'); ok(Mapping != NULL, "MmAllocateMappingAddress failed\n"); if (!skip(Mapping != NULL, "No mapping\n")) { ok_bool_true(ValidateMapping(Mapping, 1, 0, NULL), "ValidateMapping returned"); MmFreeMappingAddress(Mapping, 'MRmK'); } /* 10 pages */ Mapping = MmAllocateMappingAddress(10 * PAGE_SIZE, 'MRmK' & ~1); ok(Mapping != NULL, "MmAllocateMappingAddress failed\n"); if (!skip(Mapping != NULL, "No mapping\n")) { ok_bool_true(ValidateMapping(Mapping, 10, 0, NULL), "ValidateMapping returned"); /* PAGE_FAULT_IN_NONPAGED_AREA can't be caught with SEH */ if (0) { (void)*(volatile UCHAR *)Mapping; } TestMap(Mapping); MmFreeMappingAddress(Mapping, 'MRmK'); } }