um: Rework uaccess code

Rework UML's uaccess code to reuse as much as possible
from asm-generic/uaccess.c.

Signed-off-by: Richard Weinberger <richard@nod.at>
This commit is contained in:
Richard Weinberger
2015-05-12 00:17:28 +02:00
szülő 1d04c8d779
commit f8d65d27e6
7 fájl változott, egészen pontosan 53 új sor hozzáadva és 183 régi sor törölve

Fájl megtekintése

@@ -87,10 +87,10 @@ static int do_op_one_page(unsigned long addr, int len, int is_write,
return n;
}
static int buffer_op(unsigned long addr, int len, int is_write,
int (*op)(unsigned long, int, void *), void *arg)
static long buffer_op(unsigned long addr, int len, int is_write,
int (*op)(unsigned long, int, void *), void *arg)
{
int size, remain, n;
long size, remain, n;
size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
remain = len;
@@ -139,18 +139,16 @@ static int copy_chunk_from_user(unsigned long from, int len, void *arg)
return 0;
}
int copy_from_user(void *to, const void __user *from, int n)
long __copy_from_user(void *to, const void __user *from, unsigned long n)
{
if (segment_eq(get_fs(), KERNEL_DS)) {
memcpy(to, (__force void*)from, n);
return 0;
}
return access_ok(VERIFY_READ, from, n) ?
buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to):
n;
return buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to);
}
EXPORT_SYMBOL(copy_from_user);
EXPORT_SYMBOL(__copy_from_user);
static int copy_chunk_to_user(unsigned long to, int len, void *arg)
{
@@ -161,18 +159,16 @@ static int copy_chunk_to_user(unsigned long to, int len, void *arg)
return 0;
}
int copy_to_user(void __user *to, const void *from, int n)
long __copy_to_user(void __user *to, const void *from, unsigned long n)
{
if (segment_eq(get_fs(), KERNEL_DS)) {
memcpy((__force void *) to, from, n);
return 0;
}
return access_ok(VERIFY_WRITE, to, n) ?
buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) :
n;
return buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from);
}
EXPORT_SYMBOL(copy_to_user);
EXPORT_SYMBOL(__copy_to_user);
static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
{
@@ -188,9 +184,9 @@ static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
return 0;
}
int strncpy_from_user(char *dst, const char __user *src, int count)
long __strncpy_from_user(char *dst, const char __user *src, long count)
{
int n;
long n;
char *ptr = dst;
if (segment_eq(get_fs(), KERNEL_DS)) {
@@ -198,16 +194,13 @@ int strncpy_from_user(char *dst, const char __user *src, int count)
return strnlen(dst, count);
}
if (!access_ok(VERIFY_READ, src, 1))
return -EFAULT;
n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user,
&ptr);
if (n != 0)
return -EFAULT;
return strnlen(dst, count);
}
EXPORT_SYMBOL(strncpy_from_user);
EXPORT_SYMBOL(__strncpy_from_user);
static int clear_chunk(unsigned long addr, int len, void *unused)
{
@@ -215,22 +208,16 @@ static int clear_chunk(unsigned long addr, int len, void *unused)
return 0;
}
int __clear_user(void __user *mem, int len)
{
return buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL);
}
int clear_user(void __user *mem, int len)
unsigned long __clear_user(void __user *mem, unsigned long len)
{
if (segment_eq(get_fs(), KERNEL_DS)) {
memset((__force void*)mem, 0, len);
return 0;
}
return access_ok(VERIFY_WRITE, mem, len) ?
buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len;
return buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL);
}
EXPORT_SYMBOL(clear_user);
EXPORT_SYMBOL(__clear_user);
static int strnlen_chunk(unsigned long str, int len, void *arg)
{
@@ -244,7 +231,7 @@ static int strnlen_chunk(unsigned long str, int len, void *arg)
return 0;
}
int strnlen_user(const void __user *str, int len)
long __strnlen_user(const void __user *str, long len)
{
int count = 0, n;
@@ -256,4 +243,4 @@ int strnlen_user(const void __user *str, int len)
return count + 1;
return 0;
}
EXPORT_SYMBOL(strnlen_user);
EXPORT_SYMBOL(__strnlen_user);