From 30804b9ed7e915adffbc1b39370ba049383a3869 Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Mon, 5 Oct 2009 15:22:31 +0000 Subject: [PATCH] thanks to tomas: fix for level0() race condition - global variable can be used concurrently. pass the function in eax instead; this gets rid of the global variable. also execute the function directly if we're already trapped into the kernel. revert of u32_t endpoint_t to int (some code assumes endpoints are negative for negative slot numbers). --- kernel/arch/i386/klib386.s | 11 ++++++++--- kernel/arch/i386/memory.c | 14 +++++--------- kernel/arch/i386/mpx386.s | 6 +++++- kernel/arch/i386/proto.h | 1 - kernel/glo.h | 2 -- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/kernel/arch/i386/klib386.s b/kernel/arch/i386/klib386.s index d506059f9..ed0cc22cb 100755 --- a/kernel/arch/i386/klib386.s +++ b/kernel/arch/i386/klib386.s @@ -489,11 +489,11 @@ idt_zero: .data4 0, 0 _idle_task: ! This task is called when the system has nothing else to do. The HLT ! instruction puts the processor in a state where it draws minimum power. - push halt + push _halt call _level0 ! level0(halt) pop eax jmp _idle_task -halt: +_halt: sti hlt cli @@ -508,10 +508,15 @@ halt: ! _level0: mov eax, 4(esp) - mov (_level0_func), eax + cmpb (_k_reenter), -1 + jne direct int LEVEL0_VECTOR ret +direct: + call eax + ret + !*===========================================================================* !* read_flags * diff --git a/kernel/arch/i386/memory.c b/kernel/arch/i386/memory.c index c5eb9de6e..013e609db 100644 --- a/kernel/arch/i386/memory.c +++ b/kernel/arch/i386/memory.c @@ -36,7 +36,6 @@ PRIVATE int nfreepdes = 0, freepdes[WANT_FREEPDES], inusepde = NOPDE; #define HASPT(procptr) ((procptr)->p_seg.p_cr3 != 0) FORWARD _PROTOTYPE( u32_t phys_get32, (vir_bytes v) ); -FORWARD _PROTOTYPE( void set_cr3, (void) ); FORWARD _PROTOTYPE( void vm_enable_paging, (void) ); @@ -241,26 +240,23 @@ phys_bytes addr; PRIVATE u32_t vm_cr3; /* temp arg to level0() func */ +PRIVATE void set_cr3() +{ + write_cr3(vm_cr3); +} + PUBLIC void vm_set_cr3(struct proc *newptproc) { int u = 0; if(!intr_disabled()) { lock; u = 1; } vm_cr3= newptproc->p_seg.p_cr3; if(vm_cr3) { - vmassert(intr_disabled()); level0(set_cr3); - vmassert(intr_disabled()); ptproc = newptproc; - vmassert(intr_disabled()); } if(u) { unlock; } } -PRIVATE void set_cr3() -{ - write_cr3(vm_cr3); -} - char *cr0_str(u32_t e) { static char str[80]; diff --git a/kernel/arch/i386/mpx386.s b/kernel/arch/i386/mpx386.s index 742891545..ccebabfd6 100755 --- a/kernel/arch/i386/mpx386.s +++ b/kernel/arch/i386/mpx386.s @@ -585,8 +585,12 @@ _reload_cr3: !* level0_call * !*===========================================================================* _level0_call: +! which level0 function to call was passed here by putting it in eax, so +! we get that from the saved state. call save - jmp (_level0_func) + mov eax, (_proc_ptr) + mov eax, AXREG(eax) + jmp eax !*===========================================================================* !* data * diff --git a/kernel/arch/i386/proto.h b/kernel/arch/i386/proto.h index 5ab71ea57..dccb92256 100644 --- a/kernel/arch/i386/proto.h +++ b/kernel/arch/i386/proto.h @@ -76,7 +76,6 @@ _PROTOTYPE( void phys_insb, (U16_t port, phys_bytes buf, size_t count) ); _PROTOTYPE( void phys_insw, (U16_t port, phys_bytes buf, size_t count) ); _PROTOTYPE( void phys_outsb, (U16_t port, phys_bytes buf, size_t count) ); _PROTOTYPE( void phys_outsw, (U16_t port, phys_bytes buf, size_t count) ); -_PROTOTYPE( void i386_invlpg_level0, (void) ); _PROTOTYPE( int _memcpy_k, (void *dst, void *src, size_t n) ); _PROTOTYPE( int _memcpy_k_fault, (void) ); _PROTOTYPE( u32_t read_cr3, (void) ); diff --git a/kernel/glo.h b/kernel/glo.h index 7c340560c..b6f289392 100755 --- a/kernel/glo.h +++ b/kernel/glo.h @@ -78,6 +78,4 @@ extern struct boot_image image[]; /* system image processes */ extern char *t_stack[]; /* task stack space */ extern struct segdesc_s gdt[]; /* global descriptor table */ -EXTERN _PROTOTYPE( void (*level0_func), (void) ); - #endif /* GLO_H */