DeAllocateSystemMemory

This commit is contained in:
ergo720 2018-03-02 17:32:38 +01:00
parent ce367788ad
commit 8766aa57bf
7 changed files with 87 additions and 80 deletions

View File

@ -86,7 +86,7 @@ XBSYSAPI EXPORTNUM(171) VOID NTAPI MmFreeContiguousMemory
// ******************************************************************
// * MmFreeSystemMemory
// ******************************************************************
XBSYSAPI EXPORTNUM(172) NTSTATUS NTAPI MmFreeSystemMemory
XBSYSAPI EXPORTNUM(172) ULONG NTAPI MmFreeSystemMemory
(
PVOID BaseAddress,
ULONG NumberOfBytes

View File

@ -157,7 +157,7 @@ extern "C" {
#define HIGHEST_USER_ADDRESS 0x7FFEFFFF
#define HIGHEST_VAD_ADDRESS HIGHEST_USER_ADDRESS - X64KB // for NtAllocateVirtualMemory
#define PAGE_DIRECTORY_BASE 0xC0300000
#define PAGE_DIRECTORY_BASE 0xC0300000
#define PAGE_TABLES_BASE 0xC0000000
#define PAGE_TABLES_SIZE 4 * ONE_MB
#define PAGE_TABLES_END PAGE_TABLES_BASE + PAGE_TABLES_SIZE - 1

View File

@ -220,7 +220,7 @@ XBSYSAPI EXPORTNUM(170) xboxkrnl::VOID NTAPI xboxkrnl::MmDeleteKernelStack
VAddr StackBottom = (VAddr)StackBase - ActualSize;
g_VMManager.DeallocateStack(StackBottom);
g_VMManager.DeAllocateSystemMemory(StackBottom, ActualSize);
}
// ******************************************************************
@ -247,7 +247,7 @@ XBSYSAPI EXPORTNUM(171) xboxkrnl::VOID NTAPI xboxkrnl::MmFreeContiguousMemory
// ******************************************************************
// * 0x00AC - MmFreeSystemMemory()
// ******************************************************************
XBSYSAPI EXPORTNUM(172) xboxkrnl::NTSTATUS NTAPI xboxkrnl::MmFreeSystemMemory
XBSYSAPI EXPORTNUM(172) xboxkrnl::ULONG NTAPI xboxkrnl::MmFreeSystemMemory
(
PVOID BaseAddress,
ULONG NumberOfBytes
@ -258,9 +258,9 @@ XBSYSAPI EXPORTNUM(172) xboxkrnl::NTSTATUS NTAPI xboxkrnl::MmFreeSystemMemory
LOG_FUNC_ARG(NumberOfBytes)
LOG_FUNC_END;
g_VMManager.Deallocate((VAddr)BaseAddress);
ULONG FreedPagesNumber = g_VMManager.DeAllocateSystemMemory((VAddr)BaseAddress, NumberOfBytes);
RETURN(STATUS_SUCCESS);
RETURN(FreedPagesNumber);
}
// ******************************************************************

View File

@ -53,11 +53,6 @@ void FillMemoryUlong(void* Destination, size_t Length, ULONG Long)
}
}
PMEMORY_STATUS PhysicalMemory::GetError() const
{
return m_Status;
}
void PhysicalMemory::InitializePageDirectory()
{
PMMPTE pPde;
@ -121,10 +116,26 @@ void PhysicalMemory::InitializePageDirectory()
// correctly implemented. So, for now, we keep on ignoring this allocation
}
void PhysicalMemory::WritePfn(PFN pfn_start, PFN pfn_end, PMMPTE pPte, PageType BusyType, bool bContiguous)
void PhysicalMemory::WritePfn(PFN pfn_start, PFN pfn_end, PMMPTE pPte, PageType BusyType, bool bContiguous, bool bZero)
{
XBOX_PFN TempPF;
if (bZero)
{
TempPF.Default = 0;
while (pfn_start <= pfn_end)
{
if (g_bIsRetail || g_bIsDebug) {
*XBOX_PFN_ELEMENT(pfn_start) = TempPF;
}
else { *CHIHIRO_PFN_ELEMENT(pfn_start) = TempPF; }
m_PagesByUsage[BusyType]--;
pfn_start++;
}
return;
}
if (bContiguous)
{
// In the contiguous region we construct the pfn as a pte
@ -166,8 +177,18 @@ void PhysicalMemory::WritePfn(PFN pfn_start, PFN pfn_end, PMMPTE pPte, PageType
}
}
void PhysicalMemory::WritePte(PMMPTE pPteStart, PMMPTE pPteEnd, MMPTE Pte, PFN pfn)
void PhysicalMemory::WritePte(PMMPTE pPteStart, PMMPTE pPteEnd, MMPTE Pte, PFN pfn, bool bZero)
{
if (bZero)
{
while (pPteStart <= pPteEnd)
{
WRITE_ZERO_PTE(pPteStart);
pPteStart++;
}
return;
}
while (pPteStart <= pPteEnd)
{
Pte.Hardware.PFN = pfn;
@ -489,7 +510,7 @@ PFN PhysicalMemory::RemoveAndZeroAnyFreePage(PageType BusyType, PMMPTE pPte)
assert(pPte);
// NOTE: for now this doesn't require a check for success but if called from other callers it will...
RemoveFree(1, &pfn, 0, m_HighestPage);
RemoveFree(1, &pfn, 0, 0, m_HighestPage);
// Fill the page with zeros
FillMemoryUlong((void*)CONVERT_PFN_TO_CONTIGUOUS_PHYSICAL(pfn), PAGE_SIZE, 0);
@ -500,48 +521,3 @@ PFN PhysicalMemory::RemoveAndZeroAnyFreePage(PageType BusyType, PMMPTE pPte)
return pfn;
}
void PhysicalMemory::ShrinkPhysicalAllocation(PAddr addr, size_t offset, bool bFragmentedMap, bool bStart)
{
if (!offset) { return; } // nothing to do
if (bFragmentedMap)
{
auto it = std::prev(m_Fragmented_mem_map.upper_bound(addr));
PAddr old_base = it->first;
size_t old_size = it->second;
m_Fragmented_mem_map.erase(old_base);
if (old_size - offset)
{
if (bStart) { m_Fragmented_mem_map.emplace(old_base + offset, old_size - offset); }
else { m_Fragmented_mem_map.emplace(old_base, old_size - offset); }
}
m_PhysicalMemoryInUse -= offset;
}
else
{
auto it = m_Mem_map.lower_bound(addr);
PAddr old_base = it->first;
size_t old_size = it->second;
m_Mem_map.erase(old_base);
if (old_size - offset)
{
if (bStart) { m_Mem_map.emplace(old_base + offset, old_size - offset); }
else { m_Mem_map.emplace(old_base, old_size - offset); }
}
m_PhysicalMemoryInUse -= offset;
}
}
void PhysicalMemory::SetError(PMEMORY_STATUS err)
{
m_Status = err;
}
void PhysicalMemory::ClearError()
{
m_Status = PMEMORY_SUCCESS;
}

View File

@ -238,8 +238,6 @@ class PhysicalMemory
protected:
// doubly linked list tracking the free physical pages
xboxkrnl::LIST_ENTRY FreeList = { &FreeList , &FreeList };
// current error status code of the PhysicalMemory class
PMEMORY_STATUS m_Status = PMEMORY_SUCCESS;
// highest pfn available for contiguous allocations
PAddr m_MaxContiguousPfn = XBOX_CONTIGUOUS_MEMORY_LIMIT;
// the size of memory occupied by the PFN/NV2A instance memory
@ -265,9 +263,9 @@ class PhysicalMemory
// set up the page directory
void InitializePageDirectory();
// write a contiguous range of pfn's
void WritePfn(PFN pfn_start, PFN pfn_end, PMMPTE pPte, PageType BusyType, bool bContiguous);
void WritePfn(PFN pfn_start, PFN pfn_end, PMMPTE pPte, PageType BusyType, bool bContiguous, bool bZero = false);
// write a contiguous range of pte's
void WritePte(PMMPTE pPteStart, PMMPTE pPteEnd, MMPTE Pte, PFN pfn);
void WritePte(PMMPTE pPteStart, PMMPTE pPteEnd, MMPTE Pte, PFN pfn, bool bZero = false);
// commit a contiguous number of pages
bool RemoveFree(PFN_COUNT NumberOfPages, PFN* result, PFN_COUNT PfnAlignment, PFN start, PFN end);
// release a contiguous number of pages
@ -278,14 +276,6 @@ class PhysicalMemory
bool AllocatePT(PFN_COUNT PteNumber, VAddr addr);
// commit whatever free page is available and zero it
PFN RemoveAndZeroAnyFreePage(PageType BusyType, PMMPTE pte);
// shrinks the size af an allocation
void ShrinkPhysicalAllocation(PAddr addr, size_t offset, bool bFragmentedMap, bool bStart);
// retrieves the current error code of the PhysicalMemory class
PMEMORY_STATUS GetError() const;
// sets the error code of the PhysicalMemory class
void SetError(PMEMORY_STATUS err);
// clears the error code of the PhysicalMemory class
void ClearError();
};
#endif

View File

@ -619,14 +619,57 @@ void VMManager::Deallocate(VAddr addr)
Unlock();
}
void VMManager::DeallocateStack(VAddr addr)
PFN_COUNT VMManager::DeAllocateSystemMemory(VAddr addr, size_t Size /*MemoryRegionType Type*/)
{
LOG_FUNC_ONE_ARG(addr);
LOG_FUNC_BEGIN
LOG_FUNC_ARG(addr);
LOG_FUNC_ARG(Size);
LOG_FUNC_END;
MMPTE TempPte;
PMMPTE StartingPte;
PMMPTE EndingPte;
PFN pfn;
PFN EndingPfn;
PFN_COUNT PteNumber;
assert(CHECK_ALIGNMENT(addr, PAGE_SIZE)); // all starting addresses from the system region are page aligned
Lock();
ReprotectVMARange(addr, PAGE_SIZE, PAGE_EXECUTE_READWRITE);
UnmapRange(addr);
StartingPte = GetPteAddress(addr);
if (Size != 0)
{
EndingPte = StartingPte + (ROUND_UP_4K(Size) >> PAGE_SHIFT) - 1;
}
else
{
VMAIter it = GetVMAIterator(addr, MemoryRegionType::System);
if (it->second.type != VMAType::Free && it->first <= addr && it->first + it->second.size > addr)
{
Size = it->second.size;
EndingPte = StartingPte + (ROUND_UP_4K(Size) >> PAGE_SHIFT) - 1;
}
else
{
DbgPrintf("Failed to locate the requested system allocation\n");
Unlock();
RETURN(NULL);
}
}
pfn = StartingPte->Hardware.PFN;
EndingPfn = pfn + (EndingPte - StartingPte);
InsertFree(pfn, EndingPfn);
WritePte(StartingPte, EndingPte, TempPte, 0, true);
WritePfn(pfn, EndingPfn, StartingPte, PageType::SystemMemory, false, true);
PteNumber = EndingPte - StartingPte + 1;
Unlock();
RETURN(PteNumber);
}
void VMManager::Protect(VAddr target, size_t size, DWORD new_perms)

View File

@ -55,12 +55,10 @@ enum VMAType
{
// vma represents an unmapped region of the address space
Free,
// memory reserved by XbAllocateVirtualMemory
// memory reserved by XbAllocateVirtualMemory or by MmMapIoSpace
Reserved,
// vma represents allocated memory
Allocated,
// mark this vma as non-mergeable
Lock,
};
@ -139,10 +137,10 @@ class VMManager : public PhysicalMemory
VAddr AllocateContiguous(size_t Size, PAddr LowerAddress, PAddr HigherAddress, ULONG Alignment, DWORD Perms);
// maps device memory in the system memory region
VAddr MapDeviceMemory(PAddr Paddr, size_t Size, DWORD Perms);
// deallocates memory in the system region
PFN_COUNT DeAllocateSystemMemory(VAddr addr, size_t Size /*MemoryRegionType Type*/);
// deallocate a block of memory
void Deallocate(VAddr addr);
// deallocate stack memory
void DeallocateStack(VAddr addr);
// changes the protections of a memory region
void Protect(VAddr target, size_t size, DWORD new_perms);
// query if a VAddr is valid