ptos: pool: Propagate page information and prepend header
Signed-off-by: Chloe M <chloe@mensia.org>
This commit is contained in:
+40
-7
@@ -13,6 +13,20 @@
|
|||||||
#include <ptapi/status.h>
|
#include <ptapi/status.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used for storing in the header so that memory
|
||||||
|
* can be freed.
|
||||||
|
*
|
||||||
|
* @BitBase: Allocation bit base
|
||||||
|
* @Gran: Granularity of page bitmap
|
||||||
|
* @Page: Page we reside in
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
USHORT BitBase : 6;
|
||||||
|
USHORT Gran;
|
||||||
|
POOL_PAGE *Page;
|
||||||
|
} PAGE_INFO;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compute the segment level index from the number of
|
* Compute the segment level index from the number of
|
||||||
* bytes requested to be allocated. We use the following
|
* bytes requested to be allocated. We use the following
|
||||||
@@ -105,15 +119,16 @@ PoolSegmentInit(POOL_SEGMENT *Segment, UCHAR Level)
|
|||||||
* @Gran: Granularity in bytes of level
|
* @Gran: Granularity in bytes of level
|
||||||
* @Page: Page to allocate from
|
* @Page: Page to allocate from
|
||||||
* @ByteCount: Number of bytes to allocate
|
* @ByteCount: Number of bytes to allocate
|
||||||
|
* @Info: Page information result
|
||||||
*/
|
*/
|
||||||
static VOID *
|
static VOID *
|
||||||
PoolAllocateFromPage(USIZE Gran, POOL_PAGE *Page, USIZE ByteCount)
|
PoolAllocateFromPage(USIZE Gran, POOL_PAGE *Page, USIZE ByteCount, PAGE_INFO *Info)
|
||||||
{
|
{
|
||||||
USIZE ChunksNeeded, ChunksFound;
|
USIZE ChunksNeeded, ChunksFound;
|
||||||
USIZE SetIdx, Idx;
|
USIZE SetIdx, Idx;
|
||||||
SSIZE IdxBase = -1;
|
SSIZE IdxBase = -1;
|
||||||
|
|
||||||
if (Page == NULL) {
|
if (Info == NULL || Page == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,6 +161,9 @@ PoolAllocateFromPage(USIZE Gran, POOL_PAGE *Page, USIZE ByteCount)
|
|||||||
SETBIT(&Page->Bitmap, SetIdx);
|
SETBIT(&Page->Bitmap, SetIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Info->BitBase = IdxBase;
|
||||||
|
Info->Page = Page;
|
||||||
|
Info->Gran = Gran;
|
||||||
return PTR_OFFSET(Page, IdxBase * Gran);
|
return PTR_OFFSET(Page, IdxBase * Gran);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,9 +173,10 @@ PoolAllocateFromPage(USIZE Gran, POOL_PAGE *Page, USIZE ByteCount)
|
|||||||
* @ByteCount: Number of bytes to allocate
|
* @ByteCount: Number of bytes to allocate
|
||||||
* @LevelIndex: Segment level index
|
* @LevelIndex: Segment level index
|
||||||
* @Segment: Segment to allocate from
|
* @Segment: Segment to allocate from
|
||||||
|
* @Info: Page information
|
||||||
*/
|
*/
|
||||||
static VOID *
|
static VOID *
|
||||||
PoolAllocateFromSegment(USIZE ByteCount, UCHAR LevelIndex, POOL_SEGMENT *Segment)
|
PoolAllocateFromSegment(USIZE ByteCount, UCHAR LevelIndex, POOL_SEGMENT *Segment, PAGE_INFO *Info)
|
||||||
{
|
{
|
||||||
USIZE ChunkCount, Idx;
|
USIZE ChunkCount, Idx;
|
||||||
ULONG Gran;
|
ULONG Gran;
|
||||||
@@ -176,7 +195,7 @@ PoolAllocateFromSegment(USIZE ByteCount, UCHAR LevelIndex, POOL_SEGMENT *Segment
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (Page != NULL) {
|
while (Page != NULL) {
|
||||||
Ptr = PoolAllocateFromPage(Gran, Page, ByteCount);
|
Ptr = PoolAllocateFromPage(Gran, Page, ByteCount, Info);
|
||||||
if (Ptr != NULL) {
|
if (Ptr != NULL) {
|
||||||
return Ptr;
|
return Ptr;
|
||||||
}
|
}
|
||||||
@@ -202,13 +221,18 @@ ExAllocatePoolWithTag(POOL_TYPE Type, USIZE ByteCount, ULONG Tag)
|
|||||||
UCHAR SegmentIndex;
|
UCHAR SegmentIndex;
|
||||||
POOL_REGION *Region;
|
POOL_REGION *Region;
|
||||||
POOL_SEGMENT *Segment;
|
POOL_SEGMENT *Segment;
|
||||||
|
POOL_HEADER *Header;
|
||||||
|
PAGE_INFO PageInfo;
|
||||||
VOID *Base;
|
VOID *Base;
|
||||||
|
|
||||||
if (ByteCount == 0) {
|
if (ByteCount == 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteCount = ALIGN_UP(ByteCount, POOL_LEVEL_GRAN(0));
|
ByteCount = ALIGN_UP(
|
||||||
|
ByteCount,
|
||||||
|
POOL_LEVEL_GRAN(0)
|
||||||
|
);
|
||||||
|
|
||||||
/* Verify that the pool type is valid */
|
/* Verify that the pool type is valid */
|
||||||
switch (Type) {
|
switch (Type) {
|
||||||
@@ -222,15 +246,24 @@ ExAllocatePoolWithTag(POOL_TYPE Type, USIZE ByteCount, ULONG Tag)
|
|||||||
SegmentIndex = PoolComputeLevelIndex(ByteCount);
|
SegmentIndex = PoolComputeLevelIndex(ByteCount);
|
||||||
Segment = &Region->Level[SegmentIndex];
|
Segment = &Region->Level[SegmentIndex];
|
||||||
Base = PoolAllocateFromSegment(
|
Base = PoolAllocateFromSegment(
|
||||||
ByteCount,
|
ByteCount + ALIGN_UP(sizeof(POOL_HEADER), POOL_LEVEL_GRAN(0)),
|
||||||
SegmentIndex,
|
SegmentIndex,
|
||||||
Segment
|
Segment,
|
||||||
|
&PageInfo
|
||||||
);
|
);
|
||||||
|
|
||||||
if (Base == NULL) {
|
if (Base == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Header = (POOL_HEADER *)Base;
|
||||||
|
Header->Tag = Tag;
|
||||||
|
Header->SizeBytes = ByteCount;
|
||||||
|
Header->Gran = PageInfo.Gran;
|
||||||
|
Header->BitBase = PageInfo.BitBase;
|
||||||
|
Header->Page = PageInfo.Page;
|
||||||
|
|
||||||
|
Base = PTR_OFFSET(Base, sizeof(POOL_HEADER));
|
||||||
RtlMemSet(Base, 0, ByteCount);
|
RtlMemSet(Base, 0, ByteCount);
|
||||||
return Base;
|
return Base;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,6 +64,24 @@ typedef struct {
|
|||||||
POOL_SEGMENT Level[POOL_LEVEL_MAX];
|
POOL_SEGMENT Level[POOL_LEVEL_MAX];
|
||||||
} POOL_REGION;
|
} POOL_REGION;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A pool header is prepended to the start of allocated
|
||||||
|
* memory.
|
||||||
|
*
|
||||||
|
* @Gran: Granularity of page bitmap
|
||||||
|
* @BitBase: Allocation bitbase
|
||||||
|
* @SizeBytes: Allocation size in bytes
|
||||||
|
* @Tag: Tag assigned to allocation
|
||||||
|
* @Page: Page we reside in
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
USHORT Gran;
|
||||||
|
UCHAR BitBase : 6;
|
||||||
|
USIZE SizeBytes;
|
||||||
|
ULONG Tag;
|
||||||
|
POOL_PAGE *Page;
|
||||||
|
} POOL_HEADER;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize a pool region
|
* Initialize a pool region
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user