Implement copyin/copyout
This commit is contained in:
parent
9c8f3c099b
commit
b2c2b7c45a
@ -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",
|
||||
|
@ -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
23
sys/amd64/support.S
Normal 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)
|
||||
|
@ -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 >= ©_unsafe) &&
|
||||
(tf->rip <= ©_unsafe_done)) {
|
||||
tf->rip = ©_unsafe_fault;
|
||||
return;
|
||||
}
|
||||
|
||||
// Halt on kernel errors
|
||||
if (tf->vector <= T_CPU_LAST)
|
||||
{
|
||||
|
@ -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
40
sys/kern/copy.c
Normal 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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user