Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8c773914 authored by Anton Blanchard's avatar Anton Blanchard Committed by Benjamin Herrenschmidt
Browse files

powerpc: Add 64bit csum_and_copy_to_user



This adds the equivalent of csum_and_copy_from_user for the receive side so we
can copy and checksum in one pass. It is modelled on the generic checksum
routine.

Signed-off-by: default avatarAnton Blanchard <anton@samba.org>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent fdd374b6
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -57,6 +57,9 @@ extern __wsum csum_partial_copy_generic(const void *src, void *dst,
#define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER
#define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER
extern __wsum csum_and_copy_from_user(const void __user *src, void *dst,
extern __wsum csum_and_copy_from_user(const void __user *src, void *dst,
				      int len, __wsum sum, int *err_ptr);
				      int len, __wsum sum, int *err_ptr);
#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);
#else
#else
/*
/*
 * the same as csum_partial, but copies from src to dst while it
 * the same as csum_partial, but copies from src to dst while it
+37 −0
Original line number Original line Diff line number Diff line
@@ -63,3 +63,40 @@ __wsum csum_and_copy_from_user(const void __user *src, void *dst,
	return (__force __wsum)csum;
	return (__force __wsum)csum;
}
}
EXPORT_SYMBOL(csum_and_copy_from_user);
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)
{
	unsigned int csum;

	might_sleep();

	*err_ptr = 0;

	if (!len) {
		csum = 0;
		goto out;
	}

	if (unlikely((len < 0) || !access_ok(VERIFY_WRITE, dst, len))) {
		*err_ptr = -EFAULT;
		csum = -1; /* invalid checksum */
		goto out;
	}

	csum = csum_partial_copy_generic(src, (void __force *)dst,
					 len, sum, NULL, err_ptr);

	if (unlikely(*err_ptr)) {
		csum = csum_partial(src, len, sum);

		if (copy_to_user(dst, src, len)) {
			*err_ptr = -EFAULT;
			csum = -1; /* invalid checksum */
		}
	}

out:
	return (__force __wsum)csum;
}
EXPORT_SYMBOL(csum_and_copy_to_user);