Implement copyin/copyout

This commit is contained in:
Ali Mashtizadeh 2014-10-12 13:17:18 -07:00
parent 9c8f3c099b
commit b2c2b7c45a
6 changed files with 81 additions and 0 deletions

View File

@ -20,6 +20,7 @@ src_amd64 = [
"amd64/machine.c",
"amd64/pci.c",
"amd64/pmap.c",
"amd64/support.S",
"amd64/switch.S",
"amd64/thread.c",
"amd64/time.c",

View File

@ -31,6 +31,7 @@
*/
#define MEM_USERSPACE_BASE 0x0000000000000000ULL
#define MEM_USERSPACE_LEN 0x0000800000000000ULL
#define MEM_USERSPACE_TOP (MEM_USERSPACE_BASE + MEM_USERSPACE_LEN)
#define MEM_DIRECTMAP_BASE 0xFFFF800000000000ULL
#define MEM_DIRECTMAP_LEN 0x0000010000000000ULL

23
sys/amd64/support.S Normal file
View File

@ -0,0 +1,23 @@
/*
* Support Functions
*/
#include <errno.h>
#include <machine/asm.h>
.text
// copy_unsafe(to, from, len)
FUNC_BEGIN(copy_unsafe)
movq %rdx, %rcx
rep movsb
.globl copy_unsafe_done
copy_unsafe_done:
xorq %rax, %rax
retq
.globl copy_unsafe_fault
copy_unsafe_fault:
movq $EFAULT, %rax
retq
FUNC_END(copy_unsafe)

View File

@ -108,6 +108,10 @@ Trap_Dump(TrapFrame *tf)
tf->r13, tf->r14, tf->r15);
}
extern int copy_unsafe(void *to, void *from, uintptr_t len);
extern void copy_unsafe_done(void);
extern void copy_unsafe_fault(void);
void
trap_entry(TrapFrame *tf)
{
@ -124,6 +128,14 @@ trap_entry(TrapFrame *tf)
return;
}
// User IO
if ((tf->vector == T_PF) &&
(tf->rip >= &copy_unsafe) &&
(tf->rip <= &copy_unsafe_done)) {
tf->rip = &copy_unsafe_fault;
return;
}
// Halt on kernel errors
if (tf->vector <= T_CPU_LAST)
{

View File

@ -58,5 +58,9 @@ uint64_t Handle_Add(Thread *thr, Handle *handle);
void Handle_Remove(Thread *thr, Handle *handle);
Handle *Handle_Lookup(Thread *thr, uint64_t fd);
// CopyIn/CopyOut Functions
int CopyIn(void *fromuser, void *tokernel, uintptr_t len);
int CopyOut(void *fromkernel, void *touser, uintptr_t len);
#endif /* __SYS_THREAD_H__ */

40
sys/kern/copy.c Normal file
View File

@ -0,0 +1,40 @@
/*
* Generic Copyin/Copyout routines
*/
extern int copy_unsafe(void *to_addr, void *from_addr, uintptr_t len);
int
CopyIn(void *fromuser, void *tokernel, uintptr_t len)
{
if (len == 0)
return 0;
// Kernel space
if (fromuser >= MEM_USERSPACE_TOP)
return EFAULT;
// Wrap around
if (len < (MEM_USERSPACE_TOP - fromuser))
return EFAULT;
return copy_unsafe(tokernel, fromuser, len);
}
int
CopyOut(void *fromkernel, void *touser, uintptr_t len)
{
if (len == 0)
return 0;
// Kernel space
if (touser >= MEM_USERSPACE_TOP)
return EFAULT;
// Wrap around
if (len < (MEM_USERSPACE_TOP - touser))
return EFAULT;
return copy_unsafe(touser, fromkernel, len);
}