diff --git a/kernel/arch/i386/memory.c b/kernel/arch/i386/memory.c index 9fceb45ac..ba369bcb4 100644 --- a/kernel/arch/i386/memory.c +++ b/kernel/arch/i386/memory.c @@ -531,6 +531,34 @@ PRIVATE void vm_suspend(struct proc *caller, const struct proc *target, vmrequest = caller; } +/*===========================================================================* + * vm_check_range * + *===========================================================================*/ +PUBLIC int vm_check_range(struct proc *caller, struct proc *target, + vir_bytes vir_addr, size_t bytes) +{ + /* Public interface to vm_suspend(), for use by kernel calls. On behalf + * of 'caller', call into VM to check linear virtual address range of + * process 'target', starting at 'vir_addr', for 'bytes' bytes. This + * function assumes that it will called twice if VM returned an error + * the first time (since nothing has changed in that case), and will + * then return the error code resulting from the first call. Upon the + * first call, a non-success error code is returned as well. + */ + int r; + + if (!vm_running) + return EFAULT; + + if ((caller->p_misc_flags & MF_KCALL_RESUME) && + (r = caller->p_vmrequest.vmresult) != OK) + return r; + + vm_suspend(caller, target, vir_addr, bytes, VMSTYPE_KERNELCALL); + + return VMSUSPEND; +} + /*===========================================================================* * delivermsg * *===========================================================================*/ diff --git a/kernel/proto.h b/kernel/proto.h index 4ba3328b3..764341e74 100644 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -211,6 +211,8 @@ _PROTOTYPE( void proc_stacktrace, (struct proc *proc) ); _PROTOTYPE( int vm_lookup, (const struct proc *proc, vir_bytes virtual, phys_bytes *result, u32_t *ptent)); _PROTOTYPE( size_t vm_lookup_range, (const struct proc *proc, vir_bytes vir_addr, phys_bytes *phys_addr, size_t bytes) ); +_PROTOTYPE( int vm_check_range, (struct proc *caller, + struct proc *target, vir_bytes vir_addr, size_t bytes) ); _PROTOTYPE( void delivermsg, (struct proc *target)); _PROTOTYPE( void arch_do_syscall, (struct proc *proc) ); _PROTOTYPE( int arch_phys_map, (int index, phys_bytes *addr,