diff --git a/kernel/arch/i386/klib386.S b/kernel/arch/i386/klib386.S index 6e136cc11..852fa6c8b 100644 --- a/kernel/arch/i386/klib386.S +++ b/kernel/arch/i386/klib386.S @@ -692,3 +692,39 @@ idt_reload: reload_ds: RELOAD_SEG_REG(%ds) ret + +/*===========================================================================*/ +/* switch_address_space */ +/*===========================================================================*/ +/* PUBLIC void switch_address_space(struct proc *p) + * + * sets the %cr3 register to the supplied value if it is not already set to the + * same value in which case it would only result in an extra TLB flush which is + * not desirable + */ + .balign 16 +.globl switch_address_space +switch_address_space: + + /* read the process pointer */ + mov 4(%esp), %edx + /* enable process' segment descriptors */ + lldt P_LDT_SEL(%edx) + /* get the new cr3 value */ + movl P_CR3(%edx), %eax + /* test if the new cr3 != NULL */ + cmpl $0, %eax + je 0f + + /* + * test if the cr3 is loaded with the current value to avoid unnecessary + * TLB flushes + */ + mov %cr3, %ecx + cmp %ecx, %eax + je 0f + mov %eax, %cr3 + mov %edx, ptproc + movl $0, dirtypde +0: + ret diff --git a/kernel/arch/i386/mpx386.S b/kernel/arch/i386/mpx386.S index d67ba0acc..321bc59a5 100644 --- a/kernel/arch/i386/mpx386.S +++ b/kernel/arch/i386/mpx386.S @@ -470,22 +470,6 @@ restart: /* %eax is set by schedcheck() to the process to run */ mov %eax, %ebp /* will assume P_STACKBASE == 0 */ - cmpl $0, P_CR3(%ebp) - jz 0f - - /* - * test if the cr3 is loaded with the current value to avoid unnecessary - * TLB flushes - */ - mov P_CR3(%ebp), %eax - mov %cr3, %ecx - cmp %ecx, %eax - jz 0f - mov %eax, %cr3 - mov %ebp, ptproc - movl $0, dirtypde -0: - /* reconstruct the stack for iret */ movl SSREG(%ebp), %eax push %eax @@ -500,7 +484,6 @@ restart: RESTORE_GP_REGS(%ebp) - lldt P_LDT_SEL(%ebp) /* enable process' segment descriptors */ RESTORE_SEGS(%ebp) movl %ss:BPREG(%ebp), %ebp diff --git a/kernel/arch/i386/system.c b/kernel/arch/i386/system.c index 703056cc3..d857eeece 100644 --- a/kernel/arch/i386/system.c +++ b/kernel/arch/i386/system.c @@ -477,9 +477,6 @@ PUBLIC void arch_do_syscall(struct proc *proc) m_ptr = (message *) proc->p_reg.bx; bit_map = proc->p_reg.dx; - /* do_ipc() expects the given process's memory to be accessible. */ - vm_set_cr3(proc); - /* Make the system call, for real this time. */ proc->p_reg.retreg = do_ipc(call_nr, src_dst_e, m_ptr, bit_map); } diff --git a/kernel/proc.c b/kernel/proc.c index 99a2b202d..04062a105 100644 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -198,6 +198,8 @@ not_runnable_pick_new: idle(); } + switch_address_space(proc_ptr); + check_misc_flags: vmassert(proc_ptr); diff --git a/kernel/proto.h b/kernel/proto.h index 69c4d9f07..5226727a4 100644 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -171,4 +171,5 @@ _PROTOTYPE( int arch_phys_map, (int index, phys_bytes *addr, _PROTOTYPE( int arch_phys_map_reply, (int index, vir_bytes addr)); _PROTOTYPE( int arch_enable_paging, (void)); +_PROTOTYPE(void switch_address_space, (struct proc * p)); #endif /* PROTO_H */