refactor some copyin/copyout functions
- copy_from_user() - getlong_user() - getint_user() - copy_to_user() - setlong_user() - setint_user()
This commit is contained in:
@ -2159,30 +2159,8 @@ void *phys_to_virt(unsigned long p)
|
|||||||
int copy_from_user(void *dst, const void *src, size_t siz)
|
int copy_from_user(void *dst, const void *src, size_t siz)
|
||||||
{
|
{
|
||||||
struct process_vm *vm = cpu_local_var(current)->vm;
|
struct process_vm *vm = cpu_local_var(current)->vm;
|
||||||
struct vm_range *range;
|
|
||||||
size_t pos;
|
|
||||||
size_t wsiz;
|
|
||||||
unsigned long pgstart = (unsigned long)src;
|
|
||||||
|
|
||||||
wsiz = siz + (pgstart & 0x0000000000000fffUL);
|
return read_process_vm(vm, dst, src, siz);
|
||||||
pgstart &= 0xfffffffffffff000UL;
|
|
||||||
if(!pgstart || pgstart >= MAP_KERNEL_START)
|
|
||||||
return -EFAULT;
|
|
||||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
|
||||||
for(pos = 0; pos < wsiz; pos += 4096, pgstart += 4096){
|
|
||||||
range = lookup_process_memory_range(vm, pgstart, pgstart+1);
|
|
||||||
if(range == NULL){
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
if((range->flag & VR_PROT_MASK) == VR_PROT_NONE){
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
|
||||||
memcpy(dst, src, siz);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int strlen_user(const char *s)
|
int strlen_user(const char *s)
|
||||||
@ -2261,50 +2239,28 @@ int strcpy_from_user(char *dst, const char *src)
|
|||||||
|
|
||||||
long getlong_user(const long *p)
|
long getlong_user(const long *p)
|
||||||
{
|
{
|
||||||
struct process_vm *vm = cpu_local_var(current)->vm;
|
int error;
|
||||||
struct vm_range *range;
|
long l;
|
||||||
unsigned long plong = (unsigned long)p;
|
|
||||||
unsigned long pgstart;
|
|
||||||
|
|
||||||
pgstart = plong & 0xfffffffffffff000UL;
|
error = copy_from_user(&l, p, sizeof(l));
|
||||||
if(!pgstart || pgstart >= MAP_KERNEL_START)
|
if (error) {
|
||||||
return -EFAULT;
|
return error;
|
||||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
|
||||||
range = lookup_process_memory_range(vm, plong, plong + sizeof(long));
|
|
||||||
if(range == NULL){
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
}
|
||||||
if((range->flag & VR_PROT_MASK) == VR_PROT_NONE){
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
return l;
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
|
||||||
return *p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int getint_user(const int *p)
|
int getint_user(const int *p)
|
||||||
{
|
{
|
||||||
struct process_vm *vm = cpu_local_var(current)->vm;
|
int error;
|
||||||
struct vm_range *range;
|
int i;
|
||||||
unsigned long pint = (unsigned long)p;
|
|
||||||
unsigned long pgstart;
|
|
||||||
|
|
||||||
pgstart = pint & 0xfffffffffffff000UL;
|
error = copy_from_user(&i, p, sizeof(i));
|
||||||
if(!pgstart || pgstart >= MAP_KERNEL_START)
|
if (error) {
|
||||||
return -EFAULT;
|
return error;
|
||||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
|
||||||
range = lookup_process_memory_range(vm, pint, pint + sizeof(int));
|
|
||||||
if(range == NULL){
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
}
|
||||||
if((range->flag & VR_PROT_MASK) == VR_PROT_NONE){
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
return i;
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
|
||||||
return *p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int read_process_vm(struct process_vm *vm, void *kdst, const void *usrc, size_t siz)
|
int read_process_vm(struct process_vm *vm, void *kdst, const void *usrc, size_t siz)
|
||||||
@ -2363,83 +2319,18 @@ int read_process_vm(struct process_vm *vm, void *kdst, const void *usrc, size_t
|
|||||||
int copy_to_user(void *dst, const void *src, size_t siz)
|
int copy_to_user(void *dst, const void *src, size_t siz)
|
||||||
{
|
{
|
||||||
struct process_vm *vm = cpu_local_var(current)->vm;
|
struct process_vm *vm = cpu_local_var(current)->vm;
|
||||||
struct vm_range *range;
|
|
||||||
size_t pos;
|
|
||||||
size_t wsiz;
|
|
||||||
unsigned long pgstart = (unsigned long)dst;
|
|
||||||
|
|
||||||
wsiz = siz + (pgstart & 0x0000000000000fffUL);
|
return write_process_vm(vm, dst, src, siz);
|
||||||
pgstart &= 0xfffffffffffff000UL;
|
|
||||||
if(!pgstart || pgstart >= MAP_KERNEL_START)
|
|
||||||
return -EFAULT;
|
|
||||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
|
||||||
for(pos = 0; pos < wsiz; pos += 4096, pgstart += 4096){
|
|
||||||
range = lookup_process_memory_range(vm, pgstart, pgstart+1);
|
|
||||||
if(range == NULL){
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
if(((range->flag & VR_PROT_MASK) == VR_PROT_NONE) ||
|
|
||||||
!(range->flag & VR_PROT_WRITE)){
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
|
||||||
memcpy(dst, src, siz);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int setlong_user(long *dst, long data)
|
int setlong_user(long *dst, long data)
|
||||||
{
|
{
|
||||||
struct process_vm *vm = cpu_local_var(current)->vm;
|
return copy_to_user(dst, &data, sizeof(data));
|
||||||
struct vm_range *range;
|
|
||||||
unsigned long plong = (unsigned long)dst;
|
|
||||||
unsigned long pgstart;
|
|
||||||
|
|
||||||
pgstart = plong & 0xfffffffffffff000UL;
|
|
||||||
if(!pgstart || pgstart >= MAP_KERNEL_START)
|
|
||||||
return -EFAULT;
|
|
||||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
|
||||||
range = lookup_process_memory_range(vm, plong, plong + sizeof(long));
|
|
||||||
if(range == NULL){
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
if(((range->flag & VR_PROT_MASK) == VR_PROT_NONE) ||
|
|
||||||
!(range->flag & VR_PROT_WRITE)){
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
|
||||||
*dst = data;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int setint_user(int *dst, int data)
|
int setint_user(int *dst, int data)
|
||||||
{
|
{
|
||||||
struct process_vm *vm = cpu_local_var(current)->vm;
|
return copy_to_user(dst, &data, sizeof(data));
|
||||||
struct vm_range *range;
|
|
||||||
unsigned long pint = (unsigned long)dst;
|
|
||||||
unsigned long pgstart;
|
|
||||||
|
|
||||||
pgstart = pint & 0xfffffffffffff000UL;
|
|
||||||
if(!pgstart || pgstart >= MAP_KERNEL_START)
|
|
||||||
return -EFAULT;
|
|
||||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
|
||||||
range = lookup_process_memory_range(vm, pint, pint + sizeof(int));
|
|
||||||
if(range == NULL){
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
if(((range->flag & VR_PROT_MASK) == VR_PROT_NONE) ||
|
|
||||||
!(range->flag & VR_PROT_WRITE)){
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
|
||||||
*dst = data;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int write_process_vm(struct process_vm *vm, void *udst, const void *ksrc, size_t siz)
|
int write_process_vm(struct process_vm *vm, void *udst, const void *ksrc, size_t siz)
|
||||||
|
|||||||
Reference in New Issue
Block a user