fix: various kernel bug fixes
This commit is contained in:
+36
-13
@@ -20,11 +20,11 @@ namespace Montauk {
|
||||
|
||||
static constexpr int MaxHeapAllocs = 512;
|
||||
|
||||
static HeapAlloc g_heapAllocs[Sched::MaxProcesses][MaxHeapAllocs];
|
||||
static int g_heapAllocCount[Sched::MaxProcesses];
|
||||
inline HeapAlloc g_heapAllocs[Sched::MaxProcesses][MaxHeapAllocs] = {};
|
||||
inline int g_heapAllocCount[Sched::MaxProcesses] = {};
|
||||
|
||||
// Get the process table slot index for the current process
|
||||
static int GetCurrentSlot() {
|
||||
inline int GetCurrentSlot() {
|
||||
auto* proc = Sched::GetCurrentProcessPtr();
|
||||
if (proc == nullptr) return -1;
|
||||
// Process slot index = pointer offset from slot 0
|
||||
@@ -32,9 +32,11 @@ namespace Montauk {
|
||||
return (int)(proc - slot0);
|
||||
}
|
||||
|
||||
static uint64_t Sys_Alloc(uint64_t size) {
|
||||
inline uint64_t Sys_Alloc(uint64_t size) {
|
||||
auto* proc = Sched::GetCurrentProcessPtr();
|
||||
if (proc == nullptr) return 0;
|
||||
int slot = GetCurrentSlot();
|
||||
if (slot < 0) return 0;
|
||||
|
||||
// Guard against overflow before rounding
|
||||
static constexpr uint64_t USER_SPACE_END = 0x0000800000000000ULL;
|
||||
@@ -50,36 +52,57 @@ namespace Montauk {
|
||||
if (userVa + size < userVa || userVa + size > USER_SPACE_END) return 0;
|
||||
|
||||
uint64_t numPages = size / 0x1000;
|
||||
if (g_heapAllocCount[slot] >= MaxHeapAllocs) return 0;
|
||||
|
||||
// Allocate physical pages and map them into the process
|
||||
uint64_t mappedPages = 0;
|
||||
for (uint64_t i = 0; i < numPages; i++) {
|
||||
void* page = Memory::g_pfa->AllocateZeroed();
|
||||
if (page == nullptr) return 0;
|
||||
if (page == nullptr) {
|
||||
for (uint64_t j = 0; j < mappedPages; j++) {
|
||||
uint64_t pageVa = userVa + j * 0x1000;
|
||||
uint64_t physAddr = Memory::VMM::Paging::GetPhysAddr(proc->pml4Phys, pageVa);
|
||||
if (physAddr != 0) {
|
||||
Memory::g_pfa->Free((void*)Memory::HHDM(physAddr));
|
||||
}
|
||||
Memory::VMM::Paging::UnmapUserIn(proc->pml4Phys, pageVa);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
uint64_t physAddr = Memory::SubHHDM((uint64_t)page);
|
||||
if (!Memory::VMM::Paging::MapUserIn(proc->pml4Phys, physAddr, userVa + i * 0x1000)) return 0;
|
||||
if (!Memory::VMM::Paging::MapUserIn(proc->pml4Phys, physAddr, userVa + i * 0x1000)) {
|
||||
Memory::g_pfa->Free(page);
|
||||
for (uint64_t j = 0; j < mappedPages; j++) {
|
||||
uint64_t pageVa = userVa + j * 0x1000;
|
||||
uint64_t mappedPhys = Memory::VMM::Paging::GetPhysAddr(proc->pml4Phys, pageVa);
|
||||
if (mappedPhys != 0) {
|
||||
Memory::g_pfa->Free((void*)Memory::HHDM(mappedPhys));
|
||||
}
|
||||
Memory::VMM::Paging::UnmapUserIn(proc->pml4Phys, pageVa);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
mappedPages++;
|
||||
}
|
||||
|
||||
proc->heapNext += size;
|
||||
|
||||
// Track the allocation so Sys_Free can release it
|
||||
int slot = GetCurrentSlot();
|
||||
if (slot >= 0) Sched::g_allocatedPages[slot] += numPages;
|
||||
if (slot >= 0 && g_heapAllocCount[slot] < MaxHeapAllocs) {
|
||||
g_heapAllocs[slot][g_heapAllocCount[slot]++] = { userVa, numPages };
|
||||
}
|
||||
Sched::g_allocatedPages[slot] += numPages;
|
||||
g_heapAllocs[slot][g_heapAllocCount[slot]++] = { userVa, numPages };
|
||||
|
||||
return userVa;
|
||||
}
|
||||
|
||||
// Reset heap allocation tracking for a process slot.
|
||||
// The actual physical pages are freed by Paging::FreeUserHalf() during process cleanup.
|
||||
static void CleanupHeapForSlot(int slot, uint64_t /*pml4Phys*/) {
|
||||
inline void CleanupHeapForSlot(int slot, uint64_t /*pml4Phys*/) {
|
||||
if (slot < 0 || slot >= Sched::MaxProcesses) return;
|
||||
g_heapAllocCount[slot] = 0;
|
||||
Sched::g_allocatedPages[slot] = 0;
|
||||
}
|
||||
|
||||
static void Sys_Free(uint64_t addr) {
|
||||
inline void Sys_Free(uint64_t addr) {
|
||||
auto* proc = Sched::GetCurrentProcessPtr();
|
||||
if (proc == nullptr) return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user