From 4f3e22140c164359bd13de0778dc3bee4979286b Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Sat, 17 Mar 2012 18:14:57 +0100 Subject: [PATCH] Fixed x64 memory leaks upon process termination. --- sortix/x64/boot.s | 4 ++-- sortix/x64/memorymanagement.cpp | 22 ++++++++++++++++++++-- sortix/x86/memorymanagement.cpp | 3 ++- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/sortix/x64/boot.s b/sortix/x64/boot.s index aa7744f7..53286351 100644 --- a/sortix/x64/boot.s +++ b/sortix/x64/boot.s @@ -78,8 +78,8 @@ multiboot_entry: addl $0x1000, %edi # Page-Directory (no user-space access here) - movl $0x24203, (%edi) # (First 2 MiB) - movl $0x25203, 8(%edi) # (Second 2 MiB) + movl $0x24003, (%edi) # (First 2 MiB) + movl $0x25003, 8(%edi) # (Second 2 MiB) addl $0x1000, %edi # Page-Table diff --git a/sortix/x64/memorymanagement.cpp b/sortix/x64/memorymanagement.cpp index a12ac52f..97eb28aa 100644 --- a/sortix/x64/memorymanagement.cpp +++ b/sortix/x64/memorymanagement.cpp @@ -35,6 +35,7 @@ namespace Sortix { extern size_t stackused; extern size_t stacklength; + void ExtendStack(); } namespace Memory @@ -131,17 +132,34 @@ namespace Sortix void DestroyAddressSpace() { + // Look up the last few entries used for the fractal mapping. These + // cannot be unmapped as that would destroy the world. Instead, we + // will remember them, switch to another adress space, and safely + // mark them as unused. Also handling the forking related pages. + addr_t fractal3 = (PMLS[4] + 0)->entry[510UL]; + addr_t fork2 = (PMLS[3] + 510UL)->entry[0]; + addr_t fractal2 = (PMLS[3] + 510UL)->entry[510]; + addr_t fork1 = (PMLS[2] + 510UL * 512UL + 510UL)->entry[0]; + addr_t fractal1 = (PMLS[2] + 510UL * 512UL + 510UL)->entry[510]; + addr_t dir = currentdir; + // First let's do the safe part. Garbage collect any PML1/0's left // behind by user-space. These are completely safe to delete. RecursiveFreeUserspacePages(TOPPMLLEVEL, 0); - // TODO: Right now this just leaks memory. - // Switch to the address space from when the world was originally // created. It should contain the kernel, the whole kernel, and // nothing but the kernel. PML* const BOOTPML4 = (PML* const) 0x21000UL; SwitchAddressSpace((addr_t) BOOTPML4); + + // Now safely mark the pages as unused. + Page::Put(fractal3 & PML_ADDRESS); + Page::Put(fractal2 & PML_ADDRESS); + Page::Put(fractal1 & PML_ADDRESS); + Page::Put(fork2 & PML_ADDRESS); + Page::Put(fork1 & PML_ADDRESS); + Page::Put(dir & PML_ADDRESS); } const size_t KERNEL_STACK_SIZE = 256UL * 1024UL; diff --git a/sortix/x86/memorymanagement.cpp b/sortix/x86/memorymanagement.cpp index 74032e11..18d0c0e7 100644 --- a/sortix/x86/memorymanagement.cpp +++ b/sortix/x86/memorymanagement.cpp @@ -140,7 +140,8 @@ namespace Sortix // Make sure Page::Put does NOT cause any Page::Get's internally! const size_t NUM_PAGES = 2; - if ( Page::stacklength - Page::stackused < NUM_PAGES ) { Page::ExtendStack(); } + size_t pagestackfree = Page::stacklength - Page::stackused; + if ( pagestackfree < NUM_PAGES ) { Page::ExtendStack(); } addr_t fractal1 = PMLS[2]->entry[1022];