diff options
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/include/asm/checksum.h | 4 | ||||
-rw-r--r-- | arch/powerpc/lib/checksum_wrappers.c | 68 |
2 files changed, 23 insertions, 49 deletions
diff --git a/arch/powerpc/include/asm/checksum.h b/arch/powerpc/include/asm/checksum.h index 64299785f639..dba685d984c0 100644 --- a/arch/powerpc/include/asm/checksum.h +++ b/arch/powerpc/include/asm/checksum.h @@ -24,10 +24,10 @@ extern __wsum csum_partial_copy_generic(const void *src, void *dst, #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER extern __wsum csum_and_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *err_ptr); + int len); #define HAVE_CSUM_COPY_USER extern __wsum csum_and_copy_to_user(const void *src, void __user *dst, - int len, __wsum sum, int *err_ptr); + int len); #define _HAVE_ARCH_CSUM_AND_COPY #define csum_partial_copy_nocheck(src, dst, len) \ diff --git a/arch/powerpc/lib/checksum_wrappers.c b/arch/powerpc/lib/checksum_wrappers.c index fabe4db28726..b1faa82dd8af 100644 --- a/arch/powerpc/lib/checksum_wrappers.c +++ b/arch/powerpc/lib/checksum_wrappers.c @@ -12,82 +12,56 @@ #include <linux/uaccess.h> __wsum csum_and_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *err_ptr) + int len) { unsigned int csum; + int err = 0; might_sleep(); - allow_read_from_user(src, len); - - *err_ptr = 0; - if (!len) { - csum = 0; - goto out; - } + if (unlikely(!access_ok(src, len))) + return 0; - if (unlikely((len < 0) || !access_ok(src, len))) { - *err_ptr = -EFAULT; - csum = (__force unsigned int)sum; - goto out; - } + allow_read_from_user(src, len); csum = csum_partial_copy_generic((void __force *)src, dst, - len, sum, err_ptr, NULL); + len, ~0U, &err, NULL); - if (unlikely(*err_ptr)) { + if (unlikely(err)) { int missing = __copy_from_user(dst, src, len); - if (missing) { - memset(dst + len - missing, 0, missing); - *err_ptr = -EFAULT; - } else { - *err_ptr = 0; - } - - csum = csum_partial(dst, len, sum); + if (missing) + csum = 0; + else + csum = csum_partial(dst, len, ~0U); } -out: prevent_read_from_user(src, len); return (__force __wsum)csum; } EXPORT_SYMBOL(csum_and_copy_from_user); -__wsum csum_and_copy_to_user(const void *src, void __user *dst, int len, - __wsum sum, int *err_ptr) +__wsum csum_and_copy_to_user(const void *src, void __user *dst, int len) { unsigned int csum; + int err = 0; might_sleep(); - allow_write_to_user(dst, len); - - *err_ptr = 0; - - if (!len) { - csum = 0; - goto out; - } + if (unlikely(!access_ok(dst, len))) + return 0; - if (unlikely((len < 0) || !access_ok(dst, len))) { - *err_ptr = -EFAULT; - csum = -1; /* invalid checksum */ - goto out; - } + allow_write_to_user(dst, len); csum = csum_partial_copy_generic(src, (void __force *)dst, - len, sum, NULL, err_ptr); + len, ~0U, NULL, &err); - if (unlikely(*err_ptr)) { - csum = csum_partial(src, len, sum); + if (unlikely(err)) { + csum = csum_partial(src, len, ~0U); - if (copy_to_user(dst, src, len)) { - *err_ptr = -EFAULT; - csum = -1; /* invalid checksum */ - } + if (copy_to_user(dst, src, len)) + csum = 0; } -out: prevent_write_to_user(dst, len); return (__force __wsum)csum; } |