mirror of
https://github.com/RGBCube/serenity
synced 2025-05-17 18:55:07 +00:00
Free physical pages allocated for a process's page directory on exit.
Also use a ProcessPagingScope instead of region aliasing to implement create-process ELF loading.
This commit is contained in:
parent
c70afd045e
commit
90ddbca127
8 changed files with 113 additions and 55 deletions
|
@ -17,7 +17,7 @@ MemoryManager& MM
|
||||||
|
|
||||||
MemoryManager::MemoryManager()
|
MemoryManager::MemoryManager()
|
||||||
{
|
{
|
||||||
m_kernel_page_directory = (dword*)0x5000;
|
m_kernel_page_directory = (PageDirectory*)0x4000;
|
||||||
m_pageTableZero = (dword*)0x6000;
|
m_pageTableZero = (dword*)0x6000;
|
||||||
m_pageTableOne = (dword*)0x7000;
|
m_pageTableOne = (dword*)0x7000;
|
||||||
|
|
||||||
|
@ -32,10 +32,19 @@ MemoryManager::~MemoryManager()
|
||||||
|
|
||||||
void MemoryManager::populate_page_directory(Process& process)
|
void MemoryManager::populate_page_directory(Process& process)
|
||||||
{
|
{
|
||||||
memset(process.m_pageDirectory, 0, 4096);
|
memset(process.m_page_directory, 0, sizeof(PageDirectory));
|
||||||
|
process.m_page_directory[0] = m_kernel_page_directory[0];
|
||||||
|
process.m_page_directory[1] = m_kernel_page_directory[1];
|
||||||
|
}
|
||||||
|
|
||||||
process.m_pageDirectory[0] = m_kernel_page_directory[0];
|
void MemoryManager::release_page_directory(Process& process)
|
||||||
process.m_pageDirectory[1] = m_kernel_page_directory[1];
|
{
|
||||||
|
ASSERT_INTERRUPTS_DISABLED();
|
||||||
|
for (size_t i = 0; i < 1024; ++i) {
|
||||||
|
auto paddr = process.m_page_directory->physical_addresses[i];
|
||||||
|
if (!paddr.is_null())
|
||||||
|
m_freePages.append(paddr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryManager::initializePaging()
|
void MemoryManager::initializePaging()
|
||||||
|
@ -44,7 +53,7 @@ void MemoryManager::initializePaging()
|
||||||
static_assert(sizeof(MemoryManager::PageTableEntry) == 4);
|
static_assert(sizeof(MemoryManager::PageTableEntry) == 4);
|
||||||
memset(m_pageTableZero, 0, 4096);
|
memset(m_pageTableZero, 0, 4096);
|
||||||
memset(m_pageTableOne, 0, 4096);
|
memset(m_pageTableOne, 0, 4096);
|
||||||
memset(m_kernel_page_directory, 0, 4096);
|
memset(m_kernel_page_directory, 0, 8192);
|
||||||
|
|
||||||
#ifdef MM_DEBUG
|
#ifdef MM_DEBUG
|
||||||
kprintf("MM: Kernel page directory @ %p\n", m_kernel_page_directory);
|
kprintf("MM: Kernel page directory @ %p\n", m_kernel_page_directory);
|
||||||
|
@ -68,7 +77,7 @@ void MemoryManager::initializePaging()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* MemoryManager::allocatePageTable()
|
void* MemoryManager::allocate_page_table()
|
||||||
{
|
{
|
||||||
auto ppages = allocatePhysicalPages(1);
|
auto ppages = allocatePhysicalPages(1);
|
||||||
dword address = ppages[0].get();
|
dword address = ppages[0].get();
|
||||||
|
@ -77,39 +86,40 @@ void* MemoryManager::allocatePageTable()
|
||||||
return (void*)address;
|
return (void*)address;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto MemoryManager::ensurePTE(dword* page_directory, LinearAddress laddr) -> PageTableEntry
|
auto MemoryManager::ensurePTE(PageDirectory* page_directory, LinearAddress laddr) -> PageTableEntry
|
||||||
{
|
{
|
||||||
ASSERT_INTERRUPTS_DISABLED();
|
ASSERT_INTERRUPTS_DISABLED();
|
||||||
dword pageDirectoryIndex = (laddr.get() >> 22) & 0x3ff;
|
dword page_directory_index = (laddr.get() >> 22) & 0x3ff;
|
||||||
dword pageTableIndex = (laddr.get() >> 12) & 0x3ff;
|
dword page_table_index = (laddr.get() >> 12) & 0x3ff;
|
||||||
|
|
||||||
PageDirectoryEntry pde = PageDirectoryEntry(&page_directory[pageDirectoryIndex]);
|
PageDirectoryEntry pde = PageDirectoryEntry(&page_directory->entries[page_directory_index]);
|
||||||
if (!pde.isPresent()) {
|
if (!pde.isPresent()) {
|
||||||
#ifdef MM_DEBUG
|
#ifdef MM_DEBUG
|
||||||
dbgprintf("MM: PDE %u not present, allocating\n", pageDirectoryIndex);
|
dbgprintf("MM: PDE %u not present, allocating\n", page_directory_index);
|
||||||
#endif
|
#endif
|
||||||
if (pageDirectoryIndex == 0) {
|
if (page_directory_index == 0) {
|
||||||
pde.setPageTableBase((dword)m_pageTableZero);
|
pde.setPageTableBase((dword)m_pageTableZero);
|
||||||
pde.setUserAllowed(false);
|
pde.setUserAllowed(false);
|
||||||
pde.setPresent(true);
|
pde.setPresent(true);
|
||||||
pde.setWritable(true);
|
pde.setWritable(true);
|
||||||
} else if (pageDirectoryIndex == 1) {
|
} else if (page_directory_index == 1) {
|
||||||
pde.setPageTableBase((dword)m_pageTableOne);
|
pde.setPageTableBase((dword)m_pageTableOne);
|
||||||
pde.setUserAllowed(false);
|
pde.setUserAllowed(false);
|
||||||
pde.setPresent(true);
|
pde.setPresent(true);
|
||||||
pde.setWritable(true);
|
pde.setWritable(true);
|
||||||
} else {
|
} else {
|
||||||
auto* pageTable = allocatePageTable();
|
auto* page_table = allocate_page_table();
|
||||||
#ifdef MM_DEBUG
|
#ifdef MM_DEBUG
|
||||||
dbgprintf("MM: PDE %x allocated page table #%u (for laddr=%p) at %p\n", page_directory, pageDirectoryIndex, laddr.get(), pageTable);
|
dbgprintf("MM: PDE %x allocated page table #%u (for laddr=%p) at %p\n", page_directory, page_directory_index, laddr.get(), page_table);
|
||||||
#endif
|
#endif
|
||||||
pde.setPageTableBase((dword)pageTable);
|
page_directory->physical_addresses[page_directory_index] = PhysicalAddress((dword)page_table);
|
||||||
|
pde.setPageTableBase((dword)page_table);
|
||||||
pde.setUserAllowed(true);
|
pde.setUserAllowed(true);
|
||||||
pde.setPresent(true);
|
pde.setPresent(true);
|
||||||
pde.setWritable(true);
|
pde.setWritable(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return PageTableEntry(&pde.pageTableBase()[pageTableIndex]);
|
return PageTableEntry(&pde.pageTableBase()[page_table_index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryManager::protectMap(LinearAddress linearAddress, size_t length)
|
void MemoryManager::protectMap(LinearAddress linearAddress, size_t length)
|
||||||
|
@ -217,8 +227,8 @@ void MemoryManager::enter_kernel_paging_scope()
|
||||||
void MemoryManager::enter_process_paging_scope(Process& process)
|
void MemoryManager::enter_process_paging_scope(Process& process)
|
||||||
{
|
{
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
current->m_tss.cr3 = (dword)process.m_pageDirectory;
|
current->m_tss.cr3 = (dword)process.m_page_directory;
|
||||||
asm volatile("movl %%eax, %%cr3"::"a"(process.m_pageDirectory));
|
asm volatile("movl %%eax, %%cr3"::"a"(process.m_page_directory));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryManager::flushEntireTLB()
|
void MemoryManager::flushEntireTLB()
|
||||||
|
@ -234,7 +244,7 @@ void MemoryManager::flushTLB(LinearAddress laddr)
|
||||||
asm volatile("invlpg %0": :"m" (*(char*)laddr.get()));
|
asm volatile("invlpg %0": :"m" (*(char*)laddr.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryManager::map_region_at_address(dword* page_directory, Region& region, LinearAddress laddr, bool user_allowed)
|
void MemoryManager::map_region_at_address(PageDirectory* page_directory, Region& region, LinearAddress laddr, bool user_allowed)
|
||||||
{
|
{
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
auto& zone = *region.zone;
|
auto& zone = *region.zone;
|
||||||
|
@ -252,7 +262,7 @@ void MemoryManager::map_region_at_address(dword* page_directory, Region& region,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryManager::unmap_range(dword* page_directory, LinearAddress laddr, size_t size)
|
void MemoryManager::unmap_range(PageDirectory* page_directory, LinearAddress laddr, size_t size)
|
||||||
{
|
{
|
||||||
ASSERT((size % PAGE_SIZE) == 0);
|
ASSERT((size % PAGE_SIZE) == 0);
|
||||||
|
|
||||||
|
@ -287,6 +297,9 @@ byte* MemoryManager::create_kernel_alias_for_region(Region& region)
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
auto laddr = allocate_linear_address_range(region.size);
|
auto laddr = allocate_linear_address_range(region.size);
|
||||||
map_region_at_address(m_kernel_page_directory, region, laddr, false);
|
map_region_at_address(m_kernel_page_directory, region, laddr, false);
|
||||||
|
#ifdef MM_DEBUG
|
||||||
|
dbgprintf("MM: Created alias L%x for L%x\n", laddr.get(), region.linearAddress.get());
|
||||||
|
#endif
|
||||||
return laddr.asPtr();
|
return laddr.asPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,7 +314,7 @@ bool MemoryManager::unmapRegion(Process& process, Region& region)
|
||||||
auto& zone = *region.zone;
|
auto& zone = *region.zone;
|
||||||
for (size_t i = 0; i < zone.m_pages.size(); ++i) {
|
for (size_t i = 0; i < zone.m_pages.size(); ++i) {
|
||||||
auto laddr = region.linearAddress.offset(i * PAGE_SIZE);
|
auto laddr = region.linearAddress.offset(i * PAGE_SIZE);
|
||||||
auto pte = ensurePTE(process.m_pageDirectory, laddr);
|
auto pte = ensurePTE(process.m_page_directory, laddr);
|
||||||
pte.setPhysicalPageBase(0);
|
pte.setPhysicalPageBase(0);
|
||||||
pte.setPresent(false);
|
pte.setPresent(false);
|
||||||
pte.setWritable(false);
|
pte.setWritable(false);
|
||||||
|
@ -321,7 +334,7 @@ bool MemoryManager::unmapSubregion(Process& process, Subregion& subregion)
|
||||||
ASSERT(numPages);
|
ASSERT(numPages);
|
||||||
for (size_t i = 0; i < numPages; ++i) {
|
for (size_t i = 0; i < numPages; ++i) {
|
||||||
auto laddr = subregion.linearAddress.offset(i * PAGE_SIZE);
|
auto laddr = subregion.linearAddress.offset(i * PAGE_SIZE);
|
||||||
auto pte = ensurePTE(process.m_pageDirectory, laddr);
|
auto pte = ensurePTE(process.m_page_directory, laddr);
|
||||||
pte.setPhysicalPageBase(0);
|
pte.setPhysicalPageBase(0);
|
||||||
pte.setPresent(false);
|
pte.setPresent(false);
|
||||||
pte.setWritable(false);
|
pte.setWritable(false);
|
||||||
|
@ -344,7 +357,7 @@ bool MemoryManager::mapSubregion(Process& process, Subregion& subregion)
|
||||||
ASSERT(numPages);
|
ASSERT(numPages);
|
||||||
for (size_t i = 0; i < numPages; ++i) {
|
for (size_t i = 0; i < numPages; ++i) {
|
||||||
auto laddr = subregion.linearAddress.offset(i * PAGE_SIZE);
|
auto laddr = subregion.linearAddress.offset(i * PAGE_SIZE);
|
||||||
auto pte = ensurePTE(process.m_pageDirectory, laddr);
|
auto pte = ensurePTE(process.m_page_directory, laddr);
|
||||||
pte.setPhysicalPageBase(zone.m_pages[firstPage + i].get());
|
pte.setPhysicalPageBase(zone.m_pages[firstPage + i].get());
|
||||||
pte.setPresent(true);
|
pte.setPresent(true);
|
||||||
pte.setWritable(true);
|
pte.setWritable(true);
|
||||||
|
@ -359,7 +372,7 @@ bool MemoryManager::mapSubregion(Process& process, Subregion& subregion)
|
||||||
|
|
||||||
bool MemoryManager::mapRegion(Process& process, Region& region)
|
bool MemoryManager::mapRegion(Process& process, Region& region)
|
||||||
{
|
{
|
||||||
map_region_at_address(process.m_pageDirectory, region, region.linearAddress, true);
|
map_region_at_address(process.m_page_directory, region, region.linearAddress, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,7 +380,7 @@ bool MemoryManager::validate_user_read(const Process& process, LinearAddress lad
|
||||||
{
|
{
|
||||||
dword pageDirectoryIndex = (laddr.get() >> 22) & 0x3ff;
|
dword pageDirectoryIndex = (laddr.get() >> 22) & 0x3ff;
|
||||||
dword pageTableIndex = (laddr.get() >> 12) & 0x3ff;
|
dword pageTableIndex = (laddr.get() >> 12) & 0x3ff;
|
||||||
auto pde = PageDirectoryEntry(&process.m_pageDirectory[pageDirectoryIndex]);
|
auto pde = PageDirectoryEntry(&process.m_page_directory->entries[pageDirectoryIndex]);
|
||||||
if (!pde.isPresent())
|
if (!pde.isPresent())
|
||||||
return false;
|
return false;
|
||||||
auto pte = PageTableEntry(&pde.pageTableBase()[pageTableIndex]);
|
auto pte = PageTableEntry(&pde.pageTableBase()[pageTableIndex]);
|
||||||
|
@ -382,7 +395,7 @@ bool MemoryManager::validate_user_write(const Process& process, LinearAddress la
|
||||||
{
|
{
|
||||||
dword pageDirectoryIndex = (laddr.get() >> 22) & 0x3ff;
|
dword pageDirectoryIndex = (laddr.get() >> 22) & 0x3ff;
|
||||||
dword pageTableIndex = (laddr.get() >> 12) & 0x3ff;
|
dword pageTableIndex = (laddr.get() >> 12) & 0x3ff;
|
||||||
auto pde = PageDirectoryEntry(&process.m_pageDirectory[pageDirectoryIndex]);
|
auto pde = PageDirectoryEntry(&process.m_page_directory->entries[pageDirectoryIndex]);
|
||||||
if (!pde.isPresent())
|
if (!pde.isPresent())
|
||||||
return false;
|
return false;
|
||||||
auto pte = PageTableEntry(&pde.pageTableBase()[pageTableIndex]);
|
auto pte = PageTableEntry(&pde.pageTableBase()[pageTableIndex]);
|
||||||
|
|
|
@ -17,6 +17,11 @@ enum class PageFaultResponse {
|
||||||
Continue,
|
Continue,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PageDirectory {
|
||||||
|
dword entries[1024];
|
||||||
|
PhysicalAddress physical_addresses[1024];
|
||||||
|
};
|
||||||
|
|
||||||
struct Zone : public Retainable<Zone> {
|
struct Zone : public Retainable<Zone> {
|
||||||
friend ByteBuffer procfs$mm();
|
friend ByteBuffer procfs$mm();
|
||||||
public:
|
public:
|
||||||
|
@ -78,6 +83,7 @@ public:
|
||||||
void unregisterZone(Zone&);
|
void unregisterZone(Zone&);
|
||||||
|
|
||||||
void populate_page_directory(Process&);
|
void populate_page_directory(Process&);
|
||||||
|
void release_page_directory(Process&);
|
||||||
|
|
||||||
byte* create_kernel_alias_for_region(Region&);
|
byte* create_kernel_alias_for_region(Region&);
|
||||||
void remove_kernel_alias_for_region(Region&, byte*);
|
void remove_kernel_alias_for_region(Region&, byte*);
|
||||||
|
@ -93,14 +99,14 @@ private:
|
||||||
~MemoryManager();
|
~MemoryManager();
|
||||||
|
|
||||||
LinearAddress allocate_linear_address_range(size_t);
|
LinearAddress allocate_linear_address_range(size_t);
|
||||||
void map_region_at_address(dword* page_directory, Region&, LinearAddress, bool user_accessible);
|
void map_region_at_address(PageDirectory*, Region&, LinearAddress, bool user_accessible);
|
||||||
void unmap_range(dword* page_directory, LinearAddress, size_t);
|
void unmap_range(PageDirectory*, LinearAddress, size_t);
|
||||||
|
|
||||||
void initializePaging();
|
void initializePaging();
|
||||||
void flushEntireTLB();
|
void flushEntireTLB();
|
||||||
void flushTLB(LinearAddress);
|
void flushTLB(LinearAddress);
|
||||||
|
|
||||||
void* allocatePageTable();
|
void* allocate_page_table();
|
||||||
|
|
||||||
void protectMap(LinearAddress, size_t length);
|
void protectMap(LinearAddress, size_t length);
|
||||||
void identityMap(LinearAddress, size_t length);
|
void identityMap(LinearAddress, size_t length);
|
||||||
|
@ -185,9 +191,9 @@ private:
|
||||||
dword* m_pte;
|
dword* m_pte;
|
||||||
};
|
};
|
||||||
|
|
||||||
PageTableEntry ensurePTE(dword* pageDirectory, LinearAddress);
|
PageTableEntry ensurePTE(PageDirectory*, LinearAddress);
|
||||||
|
|
||||||
dword* m_kernel_page_directory;
|
PageDirectory* m_kernel_page_directory;
|
||||||
dword* m_pageTableZero;
|
dword* m_pageTableZero;
|
||||||
dword* m_pageTableOne;
|
dword* m_pageTableOne;
|
||||||
|
|
||||||
|
@ -203,7 +209,7 @@ struct KernelPagingScope {
|
||||||
~KernelPagingScope() { MM.enter_process_paging_scope(*current); }
|
~KernelPagingScope() { MM.enter_process_paging_scope(*current); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OtherProcessPagingScope {
|
struct ProcessPagingScope {
|
||||||
OtherProcessPagingScope(Process& process) { MM.enter_process_paging_scope(process); }
|
ProcessPagingScope(Process& process) { MM.enter_process_paging_scope(process); }
|
||||||
~OtherProcessPagingScope() { MM.enter_process_paging_scope(*current); }
|
~ProcessPagingScope() { MM.enter_process_paging_scope(*current); }
|
||||||
};
|
};
|
||||||
|
|
|
@ -78,7 +78,7 @@ ByteBuffer procfs$pid_vm(Process& process)
|
||||||
ByteBuffer procfs$pid_stack(Process& process)
|
ByteBuffer procfs$pid_stack(Process& process)
|
||||||
{
|
{
|
||||||
ProcessInspectionScope scope(process);
|
ProcessInspectionScope scope(process);
|
||||||
OtherProcessPagingScope pagingScope(process);
|
ProcessPagingScope pagingScope(process);
|
||||||
struct RecognizedSymbol {
|
struct RecognizedSymbol {
|
||||||
dword address;
|
dword address;
|
||||||
const KSym* ksym;
|
const KSym* ksym;
|
||||||
|
@ -147,14 +147,14 @@ ByteBuffer procfs$mm()
|
||||||
zonePageCount += zone->m_pages.size();
|
zonePageCount += zone->m_pages.size();
|
||||||
auto buffer = ByteBuffer::createUninitialized(1024 + 80 * MM.m_zones.size() + zonePageCount * 10);
|
auto buffer = ByteBuffer::createUninitialized(1024 + 80 * MM.m_zones.size() + zonePageCount * 10);
|
||||||
char* ptr = (char*)buffer.pointer();
|
char* ptr = (char*)buffer.pointer();
|
||||||
ptr += ksprintf(ptr, "Zone count: %u\n", MM.m_zones.size());
|
|
||||||
ptr += ksprintf(ptr, "Free physical pages: %u\n", MM.m_freePages.size());
|
|
||||||
for (auto* zone : MM.m_zones) {
|
for (auto* zone : MM.m_zones) {
|
||||||
ptr += ksprintf(ptr, "Zone %p size: %u\n ", zone, zone->size());
|
ptr += ksprintf(ptr, "Zone %p size: %u\n ", zone, zone->size());
|
||||||
for (auto page : zone->m_pages)
|
for (auto page : zone->m_pages)
|
||||||
ptr += ksprintf(ptr, "%x ", page);
|
ptr += ksprintf(ptr, "%x ", page);
|
||||||
ptr += ksprintf(ptr, "\n");
|
ptr += ksprintf(ptr, "\n");
|
||||||
}
|
}
|
||||||
|
ptr += ksprintf(ptr, "Zone count: %u\n", MM.m_zones.size());
|
||||||
|
ptr += ksprintf(ptr, "Free physical pages: %u\n", MM.m_freePages.size());
|
||||||
buffer.trim(ptr - (char*)buffer.pointer());
|
buffer.trim(ptr - (char*)buffer.pointer());
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -285,22 +285,17 @@ Process* Process::createUserProcess(const String& path, uid_t uid, gid_t gid, pi
|
||||||
|
|
||||||
ExecSpace space;
|
ExecSpace space;
|
||||||
Region* region = nullptr;
|
Region* region = nullptr;
|
||||||
byte* region_alias = nullptr;
|
|
||||||
|
|
||||||
KernelPagingScope pagingScope;
|
ProcessPagingScope pagingScope(*t);
|
||||||
space.hookableAlloc = [&] (const String& name, size_t size) {
|
space.hookableAlloc = [&] (const String& name, size_t size) {
|
||||||
if (!size)
|
if (!size)
|
||||||
return (void*)nullptr;
|
return (void*)nullptr;
|
||||||
size = ((size / 4096) + 1) * 4096; // FIXME: Use ceil_div?
|
size = ((size / 4096) + 1) * 4096; // FIXME: Use ceil_div?
|
||||||
region = t->allocateRegion(size, String(name));
|
region = t->allocateRegion(size, String(name));
|
||||||
ASSERT(region);
|
return (void*)region->linearAddress.get();
|
||||||
region_alias = MM.create_kernel_alias_for_region(*region);
|
|
||||||
return (void*)region_alias;
|
|
||||||
};
|
};
|
||||||
bool success = space.loadELF(move(elfData));
|
bool success = space.loadELF(move(elfData));
|
||||||
if (!success) {
|
if (!success) {
|
||||||
if (region)
|
|
||||||
MM.remove_kernel_alias_for_region(*region, region_alias);
|
|
||||||
delete t;
|
delete t;
|
||||||
kprintf("Failure loading ELF %s\n", path.characters());
|
kprintf("Failure loading ELF %s\n", path.characters());
|
||||||
error = -ENOEXEC;
|
error = -ENOEXEC;
|
||||||
|
@ -325,15 +320,12 @@ Process* Process::createUserProcess(const String& path, uid_t uid, gid_t gid, pi
|
||||||
t->m_tss.eip = (dword)space.symbolPtr("_start");
|
t->m_tss.eip = (dword)space.symbolPtr("_start");
|
||||||
if (!t->m_tss.eip) {
|
if (!t->m_tss.eip) {
|
||||||
// FIXME: This is ugly. If we need to do this, it should be at a different level.
|
// FIXME: This is ugly. If we need to do this, it should be at a different level.
|
||||||
if (region)
|
|
||||||
MM.remove_kernel_alias_for_region(*region, region_alias);
|
|
||||||
delete t;
|
delete t;
|
||||||
error = -ENOEXEC;
|
error = -ENOEXEC;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(region);
|
ASSERT(region);
|
||||||
MM.remove_kernel_alias_for_region(*region, region_alias);
|
|
||||||
|
|
||||||
ProcFileSystem::the().addProcess(*t);
|
ProcFileSystem::the().addProcess(*t);
|
||||||
|
|
||||||
|
@ -414,7 +406,7 @@ Process::Process(String&& name, uid_t uid, gid_t gid, pid_t parentPID, RingLevel
|
||||||
, m_tty(tty)
|
, m_tty(tty)
|
||||||
, m_parentPID(parentPID)
|
, m_parentPID(parentPID)
|
||||||
{
|
{
|
||||||
m_pageDirectory = (dword*)kmalloc_page_aligned(4096);
|
m_page_directory = (PageDirectory*)kmalloc_page_aligned(sizeof(PageDirectory));
|
||||||
MM.populate_page_directory(*this);
|
MM.populate_page_directory(*this);
|
||||||
|
|
||||||
m_file_descriptors.resize(m_max_open_file_descriptors);
|
m_file_descriptors.resize(m_max_open_file_descriptors);
|
||||||
|
@ -456,7 +448,7 @@ Process::Process(String&& name, uid_t uid, gid_t gid, pid_t parentPID, RingLevel
|
||||||
m_tss.ss = ss;
|
m_tss.ss = ss;
|
||||||
m_tss.cs = cs;
|
m_tss.cs = cs;
|
||||||
|
|
||||||
m_tss.cr3 = (dword)m_pageDirectory;
|
m_tss.cr3 = (dword)m_page_directory;
|
||||||
|
|
||||||
if (isRing0()) {
|
if (isRing0()) {
|
||||||
// FIXME: This memory is leaked.
|
// FIXME: This memory is leaked.
|
||||||
|
@ -502,6 +494,8 @@ Process::~Process()
|
||||||
kfree(m_kernelStack);
|
kfree(m_kernelStack);
|
||||||
m_kernelStack = nullptr;
|
m_kernelStack = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MM.release_page_directory(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Process::dumpRegions()
|
void Process::dumpRegions()
|
||||||
|
@ -610,9 +604,9 @@ void Process::processDidCrash(Process* crashedProcess)
|
||||||
|
|
||||||
void Process::doHouseKeeping()
|
void Process::doHouseKeeping()
|
||||||
{
|
{
|
||||||
InterruptDisabler disabler;
|
|
||||||
if (s_deadProcesses->isEmpty())
|
if (s_deadProcesses->isEmpty())
|
||||||
return;
|
return;
|
||||||
|
InterruptDisabler disabler;
|
||||||
Process* next = nullptr;
|
Process* next = nullptr;
|
||||||
for (auto* deadProcess = s_deadProcesses->head(); deadProcess; deadProcess = next) {
|
for (auto* deadProcess = s_deadProcesses->head(); deadProcess; deadProcess = next) {
|
||||||
next = deadProcess->next();
|
next = deadProcess->next();
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "TTY.h"
|
#include "TTY.h"
|
||||||
|
|
||||||
class FileHandle;
|
class FileHandle;
|
||||||
|
class PageDirectory;
|
||||||
class Region;
|
class Region;
|
||||||
class Subregion;
|
class Subregion;
|
||||||
class Zone;
|
class Zone;
|
||||||
|
@ -149,7 +150,7 @@ private:
|
||||||
|
|
||||||
void allocateLDT();
|
void allocateLDT();
|
||||||
|
|
||||||
dword* m_pageDirectory { nullptr };
|
PageDirectory* m_page_directory { nullptr };
|
||||||
|
|
||||||
Process* m_prev { nullptr };
|
Process* m_prev { nullptr };
|
||||||
Process* m_next { nullptr };
|
Process* m_next { nullptr };
|
||||||
|
|
|
@ -49,13 +49,20 @@ static byte parseHexDigit(char nibble)
|
||||||
return 10 + (nibble - 'a');
|
return 10 + (nibble - 'a');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef KSYMS
|
||||||
static Vector<KSym, KmallocEternalAllocator>* s_ksyms;
|
static Vector<KSym, KmallocEternalAllocator>* s_ksyms;
|
||||||
|
static bool s_ksyms_ready;
|
||||||
|
|
||||||
Vector<KSym, KmallocEternalAllocator>& ksyms()
|
Vector<KSym, KmallocEternalAllocator>& ksyms()
|
||||||
{
|
{
|
||||||
return *s_ksyms;
|
return *s_ksyms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
volatile bool ksyms_ready()
|
||||||
|
{
|
||||||
|
return s_ksyms_ready;
|
||||||
|
}
|
||||||
|
|
||||||
const KSym* ksymbolicate(dword address)
|
const KSym* ksymbolicate(dword address)
|
||||||
{
|
{
|
||||||
if (address < ksyms().first().address || address > ksyms().last().address)
|
if (address < ksyms().first().address || address > ksyms().last().address)
|
||||||
|
@ -90,8 +97,38 @@ static void loadKsyms(const ByteBuffer& buffer)
|
||||||
ksyms().append({ address, String(startOfName, bufptr - startOfName) });
|
ksyms().append({ address, String(startOfName, bufptr - startOfName) });
|
||||||
++bufptr;
|
++bufptr;
|
||||||
}
|
}
|
||||||
|
s_ksyms_ready = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dump_backtrace()
|
||||||
|
{
|
||||||
|
if (!current)
|
||||||
|
return;
|
||||||
|
extern volatile bool ksyms_ready();
|
||||||
|
if (!ksyms_ready())
|
||||||
|
return;
|
||||||
|
dword stack_variable;
|
||||||
|
struct RecognizedSymbol {
|
||||||
|
dword address;
|
||||||
|
const KSym* ksym;
|
||||||
|
};
|
||||||
|
Vector<RecognizedSymbol> recognizedSymbols;
|
||||||
|
for (dword* stackPtr = &stack_variable; current->isValidAddressForKernel(LinearAddress((dword)stackPtr)); stackPtr = (dword*)*stackPtr) {
|
||||||
|
dword retaddr = stackPtr[1];
|
||||||
|
if (auto* ksym = ksymbolicate(retaddr))
|
||||||
|
recognizedSymbols.append({ retaddr, ksym });
|
||||||
|
}
|
||||||
|
size_t bytesNeeded = 0;
|
||||||
|
for (auto& symbol : recognizedSymbols) {
|
||||||
|
bytesNeeded += symbol.ksym->name.length() + 8 + 16;
|
||||||
|
}
|
||||||
|
for (auto& symbol : recognizedSymbols) {
|
||||||
|
unsigned offset = symbol.address - symbol.ksym->address;
|
||||||
|
dbgprintf("%p %s +%u\n", symbol.address, symbol.ksym->name.characters(), offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void undertaker_main() NORETURN;
|
static void undertaker_main() NORETURN;
|
||||||
static void undertaker_main()
|
static void undertaker_main()
|
||||||
{
|
{
|
||||||
|
@ -109,8 +146,8 @@ static void spawn_stress()
|
||||||
for (unsigned i = 0; i < 10000; ++i) {
|
for (unsigned i = 0; i < 10000; ++i) {
|
||||||
int error;
|
int error;
|
||||||
Process::createUserProcess("/bin/id", (uid_t)100, (gid_t)100, (pid_t)0, error, nullptr, tty0);
|
Process::createUserProcess("/bin/id", (uid_t)100, (gid_t)100, (pid_t)0, error, nullptr, tty0);
|
||||||
kprintf("malloc stats: alloc:%u free:%u page_aligned:%u eternal:%u\n", sum_alloc, sum_free, kmalloc_page_aligned, kmalloc_sum_eternal);
|
// kprintf("malloc stats: alloc:%u free:%u page_aligned:%u eternal:%u\n", sum_alloc, sum_free, kmalloc_page_aligned, kmalloc_sum_eternal);
|
||||||
kprintf("delta:%u\n", sum_alloc - lastAlloc);
|
// kprintf("delta:%u\n", sum_alloc - lastAlloc);
|
||||||
lastAlloc = sum_alloc;
|
lastAlloc = sum_alloc;
|
||||||
sleep(60);
|
sleep(60);
|
||||||
}
|
}
|
||||||
|
@ -223,6 +260,11 @@ void init()
|
||||||
{
|
{
|
||||||
cli();
|
cli();
|
||||||
|
|
||||||
|
#ifdef KSYMS
|
||||||
|
s_ksyms = nullptr;
|
||||||
|
s_ksyms_ready = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
kmalloc_init();
|
kmalloc_init();
|
||||||
vga_init();
|
vga_init();
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,8 @@ public:
|
||||||
void set(dword address) { m_address = address; }
|
void set(dword address) { m_address = address; }
|
||||||
void mask(dword m) { m_address &= m; }
|
void mask(dword m) { m_address &= m; }
|
||||||
|
|
||||||
|
bool is_null() const { return m_address == 0; }
|
||||||
|
|
||||||
byte* asPtr() { return reinterpret_cast<byte*>(m_address); }
|
byte* asPtr() { return reinterpret_cast<byte*>(m_address); }
|
||||||
const byte* asPtr() const { return reinterpret_cast<const byte*>(m_address); }
|
const byte* asPtr() const { return reinterpret_cast<const byte*>(m_address); }
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ int main(int c, char** v)
|
||||||
|
|
||||||
struct passwd* pw = getpwuid(uid);
|
struct passwd* pw = getpwuid(uid);
|
||||||
|
|
||||||
printf("uid=%u(%s), gid=%u\n", uid, pw ? pw->pw_name : "n/a", gid);
|
printf("uid=%u(%s), gid=%u, pid=%u\n", uid, pw ? pw->pw_name : "n/a", gid, getpid());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue