From 7e9744419ed6013e60fe7b34181f0258f65c5f62 Mon Sep 17 00:00:00 2001 From: apio Date: Wed, 19 Oct 2022 20:16:21 +0200 Subject: [PATCH] sh: Improve it --- apps/src/sh.c | 10 +++-- kernel/src/memory/AddressSpace.cpp | 67 +++++++++++++++++++++++------- kernel/src/thread/Scheduler.cpp | 3 ++ 3 files changed, 61 insertions(+), 19 deletions(-) diff --git a/apps/src/sh.c b/apps/src/sh.c index f27fd9e1..0b229810 100644 --- a/apps/src/sh.c +++ b/apps/src/sh.c @@ -4,6 +4,8 @@ #include #include +static int status; + typedef struct { char* buffer; @@ -13,7 +15,7 @@ typedef struct void show_prompt() { - printf("> "); + printf("[%ld]> ", getpid()); } void command_expand(command* cmd, long new_capacity) @@ -70,7 +72,6 @@ void command_execute(command* cmd) perror(cmd->buffer); exit(127); } - int status; pid_t result; while ((result = waitpid(child, &status, 0)) == 0) { msleep(20); } if (result < 0) @@ -80,7 +81,10 @@ void command_execute(command* cmd) show_prompt(); return; } - if (WEXITSTATUS(status) != 0) { printf("Exited with code %d\n", WEXITSTATUS(status)); } + int exit_status = WEXITSTATUS(status); + if (exit_status == -2 || exit_status == -3) printf("(PID %ld) Segmentation fault\n", result); + else if (exit_status) + printf("Exited with code %d\n", WEXITSTATUS(status)); command_clear(cmd); show_prompt(); } diff --git a/kernel/src/memory/AddressSpace.cpp b/kernel/src/memory/AddressSpace.cpp index 8e9debc1..e844fe54 100644 --- a/kernel/src/memory/AddressSpace.cpp +++ b/kernel/src/memory/AddressSpace.cpp @@ -134,12 +134,19 @@ void AddressSpace::clear() kdbgln("Reclaimed %ld pages from address space!", pages_freed); } +static PageTable* try_clone_page_table(PageTable* source) +{ + PageTable* dst = (PageTable*)PMM::request_page(); + if (PMM_DID_FAIL(dst)) { return 0; } + memcpy(dst, source, sizeof(PageTable)); + return dst; +} + AddressSpace AddressSpace::clone() // FIXME: Add out-of-memory checks to this function. { AddressSpace result; - result.m_pml4 = (PageTable*)PMM::request_page(); + result.m_pml4 = try_clone_page_table(m_pml4); if (!result.m_pml4) return result; - memcpy(result.m_pml4, m_pml4, PAGE_SIZE); for (int i = 0; i < 512; i++) { PageDirectoryEntry& pdp_pde = m_pml4->entries[i]; @@ -147,14 +154,22 @@ AddressSpace AddressSpace::clone() // FIXME: Add out-of-memory checks to this fu if (!pdp_pde.present) continue; if (pdp_pde.larger_pages) { - void* cloned = PMM::request_page(); - memcpy(cloned, (void*)pdp_pde.get_address(), PAGE_SIZE); + void* cloned = try_clone_page_table((PageTable*)pdp_pde.get_address()); + if (!cloned) + { + cloned_pdp_pde.present = false; + continue; + } cloned_pdp_pde.set_address((uint64_t)cloned); continue; } PageTable* pdp = (PageTable*)pdp_pde.get_address(); - PageTable* cloned_pdp = (PageTable*)PMM::request_page(); - memcpy(cloned_pdp, pdp, PAGE_SIZE); + PageTable* cloned_pdp = try_clone_page_table(pdp); + if (!cloned_pdp) + { + cloned_pdp_pde.present = false; + continue; + } cloned_pdp_pde.set_address((uint64_t)cloned_pdp); for (int j = 0; j < 511; j++) // skip the last page directory, it's the kernel one { @@ -163,14 +178,22 @@ AddressSpace AddressSpace::clone() // FIXME: Add out-of-memory checks to this fu if (!pd_pde.present) continue; if (pd_pde.larger_pages) { - void* cloned = PMM::request_page(); - memcpy(cloned, (void*)pd_pde.get_address(), PAGE_SIZE); + void* cloned = try_clone_page_table((PageTable*)pd_pde.get_address()); + if (!cloned) + { + cloned_pd_pde.present = false; + continue; + } cloned_pd_pde.set_address((uint64_t)cloned); continue; } PageTable* pd = (PageTable*)pd_pde.get_address(); - PageTable* cloned_pd = (PageTable*)PMM::request_page(); - memcpy(cloned_pd, pd, PAGE_SIZE); + PageTable* cloned_pd = try_clone_page_table(pd); + if (!cloned_pd) + { + cloned_pd_pde.present = false; + continue; + } cloned_pd_pde.set_address((uint64_t)cloned_pd); for (int k = 0; k < 512; k++) { @@ -179,22 +202,34 @@ AddressSpace AddressSpace::clone() // FIXME: Add out-of-memory checks to this fu if (!pt_pde.present) continue; if (pt_pde.larger_pages) { - void* cloned = PMM::request_page(); - memcpy(cloned, (void*)pt_pde.get_address(), PAGE_SIZE); + void* cloned = try_clone_page_table((PageTable*)pt_pde.get_address()); + if (!cloned) + { + cloned_pt_pde.present = false; + continue; + } cloned_pt_pde.set_address((uint64_t)cloned); continue; } PageTable* pt = (PageTable*)pt_pde.get_address(); - PageTable* cloned_pt = (PageTable*)PMM::request_page(); - memcpy(cloned_pt, pt, PAGE_SIZE); + PageTable* cloned_pt = try_clone_page_table(pt); + if (!cloned_pt) + { + cloned_pt_pde.present = false; + continue; + } cloned_pt_pde.set_address((uint64_t)cloned_pt); for (int l = 0; l < 512; l++) { PageDirectoryEntry& pde = pt->entries[l]; PageDirectoryEntry& cloned_pde = cloned_pt->entries[l]; if (!pde.present) continue; - void* cloned = PMM::request_page(); - memcpy(cloned, (void*)pde.get_address(), PAGE_SIZE); + void* cloned = try_clone_page_table((PageTable*)pde.get_address()); + if (!cloned) + { + cloned_pde.present = false; + continue; + } cloned_pde.set_address((uint64_t)cloned); continue; } diff --git a/kernel/src/thread/Scheduler.cpp b/kernel/src/thread/Scheduler.cpp index d434fa1c..502d1ce3 100644 --- a/kernel/src/thread/Scheduler.cpp +++ b/kernel/src/thread/Scheduler.cpp @@ -485,12 +485,15 @@ void sys_waitpid(Context* context, long pid, int* wstatus, } if (wstatus) { + VMM::switch_to_user_address_space(sched_current_task->address_space); + VMM::enter_syscall_context(); int* kwstatus = obtain_user_ref(wstatus); if (kwstatus) { *kwstatus = (int)(child->exit_status & 0xff); release_user_ref(kwstatus); } + else { kinfoln("wstatus ptr is invalid: %p", (void*)wstatus); } } child->state = child->Exited; context->rax = (long)child->id;