Path: blob/master/arch/powerpc/lib/checksum_wrappers_64.c
10817 views
/*1* This program is free software; you can redistribute it and/or modify2* it under the terms of the GNU General Public License as published by3* the Free Software Foundation; either version 2 of the License, or4* (at your option) any later version.5*6* This program is distributed in the hope that it will be useful,7* but WITHOUT ANY WARRANTY; without even the implied warranty of8* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9* GNU General Public License for more details.10*11* You should have received a copy of the GNU General Public License12* along with this program; if not, write to the Free Software13* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.14*15* Copyright (C) IBM Corporation, 201016*17* Author: Anton Blanchard <[email protected]>18*/19#include <linux/module.h>20#include <linux/compiler.h>21#include <linux/types.h>22#include <asm/checksum.h>23#include <asm/uaccess.h>2425__wsum csum_and_copy_from_user(const void __user *src, void *dst,26int len, __wsum sum, int *err_ptr)27{28unsigned int csum;2930might_sleep();3132*err_ptr = 0;3334if (!len) {35csum = 0;36goto out;37}3839if (unlikely((len < 0) || !access_ok(VERIFY_READ, src, len))) {40*err_ptr = -EFAULT;41csum = (__force unsigned int)sum;42goto out;43}4445csum = csum_partial_copy_generic((void __force *)src, dst,46len, sum, err_ptr, NULL);4748if (unlikely(*err_ptr)) {49int missing = __copy_from_user(dst, src, len);5051if (missing) {52memset(dst + len - missing, 0, missing);53*err_ptr = -EFAULT;54} else {55*err_ptr = 0;56}5758csum = csum_partial(dst, len, sum);59}6061out:62return (__force __wsum)csum;63}64EXPORT_SYMBOL(csum_and_copy_from_user);6566__wsum csum_and_copy_to_user(const void *src, void __user *dst, int len,67__wsum sum, int *err_ptr)68{69unsigned int csum;7071might_sleep();7273*err_ptr = 0;7475if (!len) {76csum = 0;77goto out;78}7980if (unlikely((len < 0) || !access_ok(VERIFY_WRITE, dst, len))) {81*err_ptr = -EFAULT;82csum = -1; /* invalid checksum */83goto out;84}8586csum = csum_partial_copy_generic(src, (void __force *)dst,87len, sum, NULL, err_ptr);8889if (unlikely(*err_ptr)) {90csum = csum_partial(src, len, sum);9192if (copy_to_user(dst, src, len)) {93*err_ptr = -EFAULT;94csum = -1; /* invalid checksum */95}96}9798out:99return (__force __wsum)csum;100}101EXPORT_SYMBOL(csum_and_copy_to_user);102103104