From f543f28bf086e73fa8db32ae6f58ad44a1562e08 Mon Sep 17 00:00:00 2001 From: "Chloe M." Date: Sun, 12 Jul 2026 19:20:15 +0000 Subject: [PATCH] ptos: mm: Add virtual address descriptor allocation Signed-off-by: Chloe M. --- service/ptos/head/mm/vad.h | 11 ++++++++ service/ptos/mm/vad.c | 54 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/service/ptos/head/mm/vad.h b/service/ptos/head/mm/vad.h index e069397..c0d71d5 100644 --- a/service/ptos/head/mm/vad.h +++ b/service/ptos/head/mm/vad.h @@ -54,4 +54,15 @@ VOID MmVadTreeInit(MM_VAD_TREE *Tree); */ PT_STATUS MmVadTreeInsert(MM_VAD_TREE *Tree, MM_VAD *Vad); +/* + * Allocate a number of virtual address descriptors from a + * VAD tree. + * + * @Tree: VAD tree to allocate from + * @PageCount: Page count + * + * Returns NULL on failure / out of memory + */ +MM_VAD *MmVadTreeAllocate(MM_VAD_TREE *Tree, USIZE PageCount); + #endif /* !_MM_VAD_H_ */ diff --git a/service/ptos/mm/vad.c b/service/ptos/mm/vad.c index 5470f96..af03b4a 100644 --- a/service/ptos/mm/vad.c +++ b/service/ptos/mm/vad.c @@ -7,6 +7,7 @@ */ #include +#include /* Prototypes */ static LONG VadCmp(MM_VAD *V0, MM_VAD *V1); @@ -49,3 +50,56 @@ MmVadTreeInsert(MM_VAD_TREE *Tree, MM_VAD *Vad) RB_INSERT(VadTree, &Tree->Head, Vad); return STATUS_SUCCESS; } + +MM_VAD * +MmVadTreeAllocate(MM_VAD_TREE *Tree, USIZE PageCount) +{ + MM_VAD *VadBase, *VadIter; + MM_VAD *VadTmp, *VadNext; + MM_RANGE *RangeIter; + UPTR RangeStart, RangeEnd; + USIZE PagesFound = 0; + USIZE RangeDelta; + + if (Tree == NULL || PageCount == 0) { + return NULL; + } + + VadBase = NULL; + RB_FOREACH(VadIter, VadTree, &Tree->Head) { + RangeIter = &VadIter->Range; + RangeStart = RangeIter->VirtualBase; + RangeEnd = RangeIter->VirtualBase + RangeIter->Length; + RangeDelta = RangeEnd - RangeStart; + + /* + * Do we have exactly a page here? Track that if so, otherwise + * reset what we've already tracked. + */ + if (RangeDelta == PAGESIZE) { + if (VadBase == NULL) + VadBase = (MM_VAD *)RangeIter->VirtualBase; + ++PagesFound; + } else { + VadBase = NULL; + --PagesFound; + } + + /* + * If we have found what we requested, remove the entire + * range and return the base. + */ + if (PagesFound >= PageCount) { + VadTmp = VadBase; + while (VadTmp != VadIter) { + VadNext = RB_NEXT(VadTree, &Tree->Head, VadTmp); + RB_REMOVE(VadTree, &Tree->Head, VadTmp); + VadTmp = VadNext; + } + RB_REMOVE(VadTree, &Tree->Head, VadTmp); + return VadBase; + } + } + + return NULL; +}