100 lines
2.0 KiB
C
100 lines
2.0 KiB
C
/*
|
|
* Generic Copyin/Copyout routines
|
|
*/
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <sys/kassert.h>
|
|
#include <machine/pmap.h>
|
|
|
|
extern int copy_unsafe(void *to_addr, void *from_addr, uintptr_t len);
|
|
extern int copystr_unsafe(void *to_addr, void *from_addr, uintptr_t len);
|
|
|
|
int
|
|
CopyIn(uintptr_t fromuser, void *tokernel, uintptr_t len)
|
|
{
|
|
if (len == 0)
|
|
return 0;
|
|
|
|
// Kernel space
|
|
if (fromuser >= MEM_USERSPACE_TOP) {
|
|
kprintf("CopyIn: address exceeds userspace top\n");
|
|
return EFAULT;
|
|
}
|
|
|
|
// Wrap around
|
|
if (len > (MEM_USERSPACE_TOP - fromuser)) {
|
|
kprintf("CopyIn: length exceeds userspace top\n");
|
|
return EFAULT;
|
|
}
|
|
|
|
return copy_unsafe(tokernel, (void *)fromuser, len);
|
|
}
|
|
|
|
int
|
|
CopyOut(void *fromkernel, uintptr_t touser, uintptr_t len)
|
|
{
|
|
if (len == 0)
|
|
return 0;
|
|
|
|
// Kernel space
|
|
if (touser >= MEM_USERSPACE_TOP) {
|
|
kprintf("CopyOut: address exceeds userspace top\n");
|
|
return EFAULT;
|
|
}
|
|
|
|
// Wrap around
|
|
if (len > (MEM_USERSPACE_TOP - touser)) {
|
|
kprintf("CopyOut: length exceeds userspace top\n");
|
|
return EFAULT;
|
|
}
|
|
|
|
return copy_unsafe((void *)touser, fromkernel, len);
|
|
}
|
|
|
|
int
|
|
CopyStrIn(uintptr_t fromuser, void *tokernel, uintptr_t len)
|
|
{
|
|
if (len == 0)
|
|
return 0;
|
|
|
|
// Kernel space
|
|
if (fromuser >= MEM_USERSPACE_TOP) {
|
|
kprintf("CopyStrIn: address exceeds userspace top\n");
|
|
return EFAULT;
|
|
}
|
|
|
|
// Wrap around
|
|
if (len > (MEM_USERSPACE_TOP - fromuser)) {
|
|
kprintf("CopyStrIn: length exceeds userspace top\n");
|
|
return EFAULT;
|
|
}
|
|
|
|
return copystr_unsafe(tokernel, (void *)fromuser, len);
|
|
}
|
|
|
|
int
|
|
CopyStrOut(void *fromkernel, uintptr_t touser, uintptr_t len)
|
|
{
|
|
if (len == 0)
|
|
return 0;
|
|
|
|
// Kernel space
|
|
if (touser >= MEM_USERSPACE_TOP) {
|
|
kprintf("CopyStrOut: address exceeds userspace top\n");
|
|
return EFAULT;
|
|
}
|
|
|
|
// Wrap around
|
|
if (len > (MEM_USERSPACE_TOP - touser)) {
|
|
kprintf("CopyStrOut: length exceeds userspace top\n");
|
|
return EFAULT;
|
|
}
|
|
|
|
return copystr_unsafe((void *)touser, fromkernel, len);
|
|
}
|
|
|