fix: continue fix page fault heap regression

This commit is contained in:
2026-02-28 00:14:28 +01:00
parent ca85553eec
commit 1809ae55e5
9 changed files with 174 additions and 40 deletions
+3 -15
View File
@@ -61,22 +61,10 @@ namespace Zenith {
return userVa;
}
// Free all heap allocations for a process slot (called on process exit)
static void CleanupHeapForSlot(int slot, uint64_t pml4Phys) {
// 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*/) {
if (slot < 0 || slot >= Sched::MaxProcesses) return;
for (int i = 0; i < g_heapAllocCount[slot]; i++) {
uint64_t va = g_heapAllocs[slot][i].va;
uint64_t numPages = g_heapAllocs[slot][i].numPages;
for (uint64_t p = 0; p < numPages; p++) {
uint64_t pageVa = va + p * 0x1000;
uint64_t physAddr = Memory::VMM::Paging::GetPhysAddr(pml4Phys, pageVa);
if (physAddr != 0) {
Memory::g_pfa->Free((void*)Memory::HHDM(physAddr));
}
Memory::VMM::Paging::UnmapUserIn(pml4Phys, pageVa);
}
}
g_heapAllocCount[slot] = 0;
}
+29 -1
View File
@@ -8,6 +8,9 @@
#pragma once
#include <Sched/Scheduler.hpp>
#include <Timekeeping/ApicTimer.hpp>
#include <Memory/Paging.hpp>
#include <Memory/PageFrameAllocator.hpp>
#include <Memory/HHDM.hpp>
#include "Syscall.hpp"
#include "WinServer.hpp"
@@ -105,9 +108,34 @@ namespace Zenith {
auto* proc = Sched::GetProcessByPid(pid);
if (!proc) return -1;
// Clean up any windows owned by this process
// Clean up any windows owned by this process (unmaps pixel pages from desktop)
WinServer::CleanupProcess(pid);
// Free I/O redirect buffers
if (proc->outBuf) {
Memory::g_pfa->Free(proc->outBuf);
proc->outBuf = nullptr;
}
if (proc->inBuf) {
Memory::g_pfa->Free(proc->inBuf);
proc->inBuf = nullptr;
}
// Free all user-space pages and page table structures
Memory::VMM::Paging::FreeUserHalf(proc->pml4Phys);
// Free kernel stack (safe — killed process isn't running on single-core)
if (proc->stackBase != 0) {
Memory::g_pfa->Free((void*)proc->stackBase, Sched::StackPages);
proc->stackBase = 0;
}
// Free the PML4 page
if (proc->pml4Phys != 0) {
Memory::g_pfa->Free((void*)Memory::HHDM(proc->pml4Phys));
proc->pml4Phys = 0;
}
proc->state = Sched::ProcessState::Terminated;
return 0;
}
+14
View File
@@ -10,6 +10,7 @@
#include <Memory/HHDM.hpp>
#include <Libraries/Memory.hpp>
#include <Terminal/Terminal.hpp>
#include <Sched/Scheduler.hpp>
namespace WinServer {
@@ -229,6 +230,19 @@ namespace WinServer {
if (g_slots[i].used && g_slots[i].ownerPid == pid) {
Kt::KernelLogStream(Kt::INFO, "WinServer") << "Cleaning up window "
<< i << " for exited PID " << pid;
// Unmap pixel pages from desktop's address space to prevent stale access
if (g_slots[i].desktopVa != 0 && g_slots[i].desktopPid != 0) {
auto* desktopProc = Sched::GetProcessByPid(g_slots[i].desktopPid);
if (desktopProc) {
for (int p = 0; p < g_slots[i].pixelNumPages; p++) {
Memory::VMM::Paging::UnmapUserIn(
desktopProc->pml4Phys,
g_slots[i].desktopVa + (uint64_t)p * 0x1000);
}
}
}
g_slots[i].used = false;
}
}