diff options
author | Alex Auvolat <alex@adnab.me> | 2015-03-13 18:02:01 +0100 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2015-03-13 18:02:01 +0100 |
commit | 151edb44eea9bf25ec466133e9dbef87bd6b1372 (patch) | |
tree | 14537daf1be1896a5453dcff21593a4233f1c3b5 /src/kernel/core | |
parent | 5bc7fcc00507bbc5ff5bf957a1589209f8495534 (diff) | |
download | kogata-151edb44eea9bf25ec466133e9dbef87bd6b1372.tar.gz kogata-151edb44eea9bf25ec466133e9dbef87bd6b1372.zip |
Add missing mutex-locking in procesc.c ; discovered design fault somewhere.
Diffstat (limited to 'src/kernel/core')
-rw-r--r-- | src/kernel/core/frame.c | 2 | ||||
-rw-r--r-- | src/kernel/core/paging.c | 19 | ||||
-rw-r--r-- | src/kernel/core/prng.c | 9 | ||||
-rw-r--r-- | src/kernel/core/sys.c | 6 | ||||
-rw-r--r-- | src/kernel/core/thread.c | 11 |
5 files changed, 31 insertions, 16 deletions
diff --git a/src/kernel/core/frame.c b/src/kernel/core/frame.c index 489d010..255abb6 100644 --- a/src/kernel/core/frame.c +++ b/src/kernel/core/frame.c @@ -53,6 +53,7 @@ uint32_t frame_alloc(size_t n) { nused_frames += n; mutex_unlock(&frame_allocator_mutex); + /*dbg_printf("AF 0x%p\n", i * 32 + j);*/ return i * 32 + j; } } @@ -65,6 +66,7 @@ void frame_free(uint32_t base, size_t n) { mutex_lock(&frame_allocator_mutex); for (size_t i = 0; i < n; i++) { + /*dbg_printf("FF 0x%p\n", base + i);*/ uint32_t idx = INDEX_FROM_BIT(base + i); uint32_t ofs = OFFSET_FROM_BIT(base + i); if (frame_bitset[idx] & (0x1 << ofs)) { diff --git a/src/kernel/core/paging.c b/src/kernel/core/paging.c index fa22879..f7ebf9c 100644 --- a/src/kernel/core/paging.c +++ b/src/kernel/core/paging.c @@ -3,7 +3,6 @@ #include <idt.h> #include <dbglog.h> #include <region.h> -#include <mutex.h> #include <thread.h> #include <malloc.h> #include <freemem.h> @@ -25,8 +24,6 @@ struct page_directory { user_pf_handler_t user_pfh; void* user_pfh_data; - - mutex_t mutex; }; @@ -60,6 +57,11 @@ void page_fault_handler(registers_t *regs) { ASSERT(current_thread->user_ex_handler != 0); current_thread->user_ex_handler(regs); } else { + if (pd->user_pfh == 0) { + dbg_printf("Error: usermode page fault on PD with no user PFH.\n"); + dbg_printf("PD: 0x%p, kernel PD: 0x%p\n", get_current_pagedir(), get_kernel_pagedir()); + PANIC("Un-handlable usermode PF.\n"); + } ASSERT(pd->user_pfh != 0); pd->user_pfh(pd->user_pfh_data, regs, vaddr); } @@ -122,7 +124,6 @@ void paging_setup(void* kernel_data_end) { // setup kernel_pd_d structure kernel_pd_d.phys_addr = (size_t)&kernel_pd - K_HIGHHALF_ADDR; - kernel_pd_d.mutex = MUTEX_UNLOCKED; // setup kernel_pt0 ASSERT(PAGE_OF_ADDR(K_HIGHHALF_ADDR) == 0); // kernel is 4M-aligned @@ -201,15 +202,15 @@ bool pd_map_page(void* vaddr, uint32_t frame_id, bool rw) { bool on_kernel_pd = (size_t)vaddr >= K_HIGHHALF_ADDR || current_thread == 0; - pagedir_t *pdd = (on_kernel_pd ? &kernel_pd_d : current_thread->current_pd_d); + // pagedir_t *pdd = (on_kernel_pd ? &kernel_pd_d : current_thread->current_pd_d); pagetable_t *pd = (on_kernel_pd ? &kernel_pd : current_pd); - mutex_lock(&pdd->mutex); + int st = enter_critical(CL_NOINT); if (!(pd->page[pt] & PTE_PRESENT)) { uint32_t new_pt_frame = frame_alloc(1); if (new_pt_frame == 0) { - mutex_unlock(&pdd->mutex); + exit_critical(st); return false; } @@ -227,7 +228,7 @@ bool pd_map_page(void* vaddr, uint32_t frame_id, bool rw) { | (rw ? PTE_RW : 0); invlpg(vaddr); - mutex_unlock(&pdd->mutex); + exit_critical(st); return true; } @@ -236,7 +237,6 @@ void pd_unmap_page(void* vaddr) { uint32_t page = PAGE_OF_ADDR(vaddr); pagetable_t *pd = ((size_t)vaddr >= K_HIGHHALF_ADDR ? &kernel_pd : current_pd); - // no need to lock the PD's mutex if (!(pd->page[pt] & PTE_PRESENT)) return; if (!(current_pt[pt].page[page] & PTE_PRESENT)) return; @@ -270,7 +270,6 @@ pagedir_t *create_pagedir(user_pf_handler_t pf, void* pfd) { if (!map_ok) goto error; pd->phys_addr = pd_phys * PAGE_SIZE; - pd->mutex = MUTEX_UNLOCKED; pd->user_pfh = pf; pd->user_pfh_data = pfd; diff --git a/src/kernel/core/prng.c b/src/kernel/core/prng.c index dbffba5..77dff7d 100644 --- a/src/kernel/core/prng.c +++ b/src/kernel/core/prng.c @@ -11,6 +11,8 @@ static const uint32_t a = 16807; static const uint32_t m = 0x7FFFFFFF; uint16_t prng_word() { + int st = enter_critical(CL_NOINT); + if (++n >= 100) { n = 0; if (entropy_count) { @@ -18,7 +20,12 @@ uint16_t prng_word() { } } x = (x * a) % m; - return x & 0xFFFF; + + uint16_t ret = x & 0xFFFF; + + exit_critical(st); + + return ret; } void prng_bytes(uint8_t* out, size_t nbytes) { diff --git a/src/kernel/core/sys.c b/src/kernel/core/sys.c index 554c95e..290fdfa 100644 --- a/src/kernel/core/sys.c +++ b/src/kernel/core/sys.c @@ -71,7 +71,7 @@ void load_kernel_symbol_map(char* text, size_t len) { void kernel_stacktrace(uint32_t ebp, uint32_t eip) { int i = 0; - while (ebp >= K_HIGHHALF_ADDR && eip >= K_HIGHHALF_ADDR && i++ < 10) { + while (ebp >= K_HIGHHALF_ADDR && eip >= K_HIGHHALF_ADDR) { char* sym = 0; if (kernel_symbol_map != 0) sym = btree_lower(kernel_symbol_map, (void*)eip); @@ -80,6 +80,10 @@ void kernel_stacktrace(uint32_t ebp, uint32_t eip) { uint32_t *d = (uint32_t*)ebp; ebp = d[0]; eip = d[1]; + if (i++ == 20) { + dbg_printf("| ..."); + break; + } } } diff --git a/src/kernel/core/thread.c b/src/kernel/core/thread.c index 1009ec7..53b3e70 100644 --- a/src/kernel/core/thread.c +++ b/src/kernel/core/thread.c @@ -43,8 +43,6 @@ void set_pit_frequency(uint32_t freq) { int enter_critical(int level) { asm volatile("cli"); - /*dbg_printf(" >%d< ", level);*/ - if (current_thread == 0) return CL_EXCL; int prev_level = current_thread->critical_level; @@ -52,18 +50,20 @@ int enter_critical(int level) { if (current_thread->critical_level < CL_NOINT) asm volatile("sti"); + /*dbg_printf(" >%d< ", current_thread->critical_level);*/ + return prev_level; } void exit_critical(int prev_level) { asm volatile("cli"); - /*dbg_printf(" <%d> ", prev_level);*/ - if (current_thread == 0) return; if (prev_level < current_thread->critical_level) current_thread->critical_level = prev_level; if (current_thread->critical_level < CL_NOINT) asm volatile("sti"); + + /*dbg_printf(" <%d> ", current_thread->critical_level);*/ } // ================== // @@ -315,12 +315,15 @@ bool wait_on_many(void** x, size_t n) { waiters = current_thread->next_waiter; } else { ASSERT(waiters != 0); + bool deleted = false; for (thread_t *w = waiters; w->next_waiter != 0; w = w->next_waiter) { if (w->next_waiter == current_thread) { w->next_waiter = current_thread->next_waiter; + deleted = true; break; } } + ASSERT(deleted); } exit_critical(st); |