completely redesign how user mode memory is allocated, fix a few smp and scheduler bugs, terminating a process now terminates the process, telemetry, optimize text editor, new font, new color scheme
This commit is contained in:
1 parent
27b31f62b6
commit
325149006c
45 files changed
+2091
-760
No files matched your search
+50
-7
@@ -11,7 +11,8 @@
|
||||
//
|
||||
// User heap:
|
||||
// A single best-fit free list in the lower half.
|
||||
// Backed on demand from the PMM. No per-process heaps.
|
||||
// Page-granular lower-half regions owned by PROCESS metadata. Sub-page
|
||||
// allocation is a user-mode runtime concern.
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <intrin.h>
|
||||
@@ -164,7 +165,7 @@ int MmHandleTlbShootdownNmi(void) {
|
||||
// ---------------------------------------------------------------------------
|
||||
// Public mapping
|
||||
// ---------------------------------------------------------------------------
|
||||
__declspec(dllexport) KSTATUS MmMapPage(uintptr_t virt, PHYSICAL_ADDRESS phys, uint64_t flags) {
|
||||
__declspec(dllexport) KSTATUS MmMapPage(uintptr_t virt, PHYSICAL_ADDRESS phys, uint64_t flags, MM_MAP_MODE mode) {
|
||||
unsigned userFlag = (flags & PAGE_USER) ? PAGE_USER : 0;
|
||||
|
||||
uintptr_t lockFlags = KeAcquireSpinlock(&gPageTableLock);
|
||||
@@ -186,6 +187,10 @@ __declspec(dllexport) KSTATUS MmMapPage(uintptr_t virt, PHYSICAL_ADDRESS phys, u
|
||||
}
|
||||
|
||||
uint64_t* pte = KiPtePtr(pt, PT_IDX(virt));
|
||||
if ((*pte & PAGE_PRESENT) && mode == MmMapFailIfPresent) {
|
||||
KeReleaseSpinlock(&gPageTableLock, lockFlags);
|
||||
return STATUS_ALREADY_EXISTS;
|
||||
}
|
||||
*pte = phys | flags;
|
||||
|
||||
KeReleaseSpinlock(&gPageTableLock, lockFlags);
|
||||
@@ -525,7 +530,7 @@ static int KiHeapEnsureMapped(HEAP* h, uintptr_t start, size_t size) {
|
||||
|
||||
PHYSICAL_ADDRESS frame = MmAllocateFrame();
|
||||
if (!frame) return 0;
|
||||
KSTATUS ms = MmMapPage(va, frame, h->MapFlags);
|
||||
KSTATUS ms = MmMapPage(va, frame, h->MapFlags, MmMapFailIfPresent);
|
||||
if (!KSUCCESS(ms)) {
|
||||
MmFreeFrame(frame);
|
||||
return 0;
|
||||
@@ -544,7 +549,7 @@ static int KiHeapGrow(HEAP* h, size_t need) {
|
||||
for (uintptr_t va = h->Brk; va < h->Brk + grow; va += PAGE_SIZE) {
|
||||
PHYSICAL_ADDRESS frame = MmAllocateFrame();
|
||||
if (!frame) return 0;
|
||||
if (!KSUCCESS(MmMapPage(va, frame, h->MapFlags))) {
|
||||
if (!KSUCCESS(MmMapPage(va, frame, h->MapFlags, MmMapFailIfPresent))) {
|
||||
MmFreeFrame(frame);
|
||||
return 0;
|
||||
}
|
||||
@@ -965,7 +970,7 @@ KSTATUS MmCreateUserRegion(PROCESS* process, size_t size, size_t alignment,
|
||||
s = STATUS_NO_MEMORY;
|
||||
break;
|
||||
}
|
||||
s = MmMapPage(va, frame, pageFlags);
|
||||
s = MmMapPage(va, frame, pageFlags, MmMapFailIfPresent);
|
||||
if (!KSUCCESS(s)) {
|
||||
MmFreeFrame(frame);
|
||||
break;
|
||||
@@ -1036,7 +1041,7 @@ KSTATUS MmEnsureUserRegionMapped(PROCESS* process, void* base, size_t size, uint
|
||||
PHYSICAL_ADDRESS frame = MmAllocateFrame();
|
||||
if (!frame) return STATUS_NO_MEMORY;
|
||||
|
||||
KSTATUS ms = MmMapPage(va, frame, flags);
|
||||
KSTATUS ms = MmMapPage(va, frame, flags, MmMapFailIfPresent);
|
||||
if (!KSUCCESS(ms)) {
|
||||
MmFreeFrame(frame);
|
||||
return ms;
|
||||
@@ -1073,6 +1078,16 @@ KSTATUS MmProtectUserRegion(PROCESS* process, void* base, size_t size, uint64_t
|
||||
return STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (pageFlags == 0) {
|
||||
for (uintptr_t va = alignedStart; va < alignedEnd; va += PAGE_SIZE) {
|
||||
if (va < regionBase || va >= regionEnd) return STATUS_ACCESS_DENIED;
|
||||
PHYSICAL_ADDRESS phys = MmGetPhysicalAddress(va);
|
||||
if (phys && KSUCCESS(MmUnmapPage(va)))
|
||||
MmFreeFrame(phys);
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
uint64_t finalFlags = pageFlags | PAGE_PRESENT | PAGE_USER;
|
||||
|
||||
for (uintptr_t va = alignedStart; va < alignedEnd; va += PAGE_SIZE) {
|
||||
@@ -1091,7 +1106,7 @@ KSTATUS MmProtectUserRegion(PROCESS* process, void* base, size_t size, uint64_t
|
||||
if (!KSUCCESS(qs) || !(existingFlags & PAGE_PRESENT)) {
|
||||
PHYSICAL_ADDRESS frame = MmAllocateFrame();
|
||||
if (!frame) return STATUS_NO_MEMORY;
|
||||
KSTATUS ms = MmMapPage(va, frame, PAGE_PRESENT | PAGE_WRITE | PAGE_USER | PAGE_NX);
|
||||
KSTATUS ms = MmMapPage(va, frame, PAGE_PRESENT | PAGE_WRITE | PAGE_USER | PAGE_NX, MmMapFailIfPresent);
|
||||
if (!KSUCCESS(ms)) {
|
||||
MmFreeFrame(frame);
|
||||
return ms;
|
||||
@@ -1161,6 +1176,34 @@ void MmDestroyAllUserRegions(PROCESS* process) {
|
||||
}
|
||||
}
|
||||
|
||||
KSTATUS MmQueryUserRegion(PROCESS* process, const void* address, void** baseOut, size_t* sizeOut,
|
||||
uint64_t* pageFlagsOut, USER_REGION_TYPE* typeOut, uint32_t* regionFlagsOut) {
|
||||
if (!process || !address) return STATUS_INVALID_PARAMETER;
|
||||
uintptr_t addr = (uintptr_t)address;
|
||||
|
||||
uintptr_t procFlags = KeAcquireSpinlock(&process->UserRegionLock);
|
||||
for (LIST_ENTRY* node = process->UserRegions.Fwd; node != &process->UserRegions; node = node->Fwd) {
|
||||
USER_VA_REGION* r = CONTAINING_RECORD(node, USER_VA_REGION, ProcessLink);
|
||||
uintptr_t end = r->Base + r->CommittedSize;
|
||||
if (addr >= r->Base && addr < end) {
|
||||
if (baseOut) *baseOut = (void*)r->Base;
|
||||
if (sizeOut) *sizeOut = r->CommittedSize;
|
||||
if (pageFlagsOut) {
|
||||
PHYSICAL_ADDRESS phys = 0;
|
||||
uint64_t flags = 0;
|
||||
KSTATUS qs = MmQueryPage(addr & PAGE_MASK, &phys, &flags);
|
||||
*pageFlagsOut = KSUCCESS(qs) ? flags : 0;
|
||||
}
|
||||
if (typeOut) *typeOut = r->Type;
|
||||
if (regionFlagsOut) *regionFlagsOut = r->Flags;
|
||||
KeReleaseSpinlock(&process->UserRegionLock, procFlags);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
KeReleaseSpinlock(&process->UserRegionLock, procFlags);
|
||||
return STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
size_t MmGetUserRegionSize(PROCESS* process, const void* base) {
|
||||
if (!process || !base) return 0;
|
||||
uintptr_t procFlags = KeAcquireSpinlock(&process->UserRegionLock);
|
||||
|
||||
Reference in new issue
Block a user