/*
 *  include/asm-s390/uaccess.h
 *
 *  S390 version
 *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
 *    Author(s): Hartmut Penner (hp@de.ibm.com),
 *               Martin Schwidefsky (schwidefsky@de.ibm.com)
 *
 *  Derived from "include/asm-i386/uaccess.h"
 */
#ifndef __S390_UACCESS_H
#define __S390_UACCESS_H

/*
 * User space memory access functions
 */
#include <linux/sched.h>
#include <linux/errno.h>

#define VERIFY_READ     0
#define VERIFY_WRITE    1


/*
 * The fs value determines whether argument validity checking should be
 * performed or not.  If get_fs() == USER_DS, checking is performed, with
 * get_fs() == KERNEL_DS, checking is bypassed.
 *
 * For historical reasons, these macros are grossly misnamed.
 */

#define MAKE_MM_SEG(a)  ((mm_segment_t) { (a) })


#define KERNEL_DS       MAKE_MM_SEG(0)
#define USER_DS         MAKE_MM_SEG(1)

#define get_ds()        (KERNEL_DS)
#define get_fs()        (current->thread.mm_segment)

#ifdef __s390x__
#define set_fs(x) \
({									\
	unsigned long __pto;						\
	current->thread.mm_segment = (x);				\
	__pto = current->thread.mm_segment.ar4 ?			\
		S390_lowcore.user_asce : S390_lowcore.kernel_asce;	\
	asm volatile ("lctlg 7,7,%0" : : "m" (__pto) );			\
})
#else
#define set_fs(x) \
({									\
	unsigned long __pto;						\
	current->thread.mm_segment = (x);				\
	__pto = current->thread.mm_segment.ar4 ?			\
		S390_lowcore.user_asce : S390_lowcore.kernel_asce;	\
	asm volatile ("lctl  7,7,%0" : : "m" (__pto) );			\
})
#endif

#define segment_eq(a,b) ((a).ar4 == (b).ar4)


#define __access_ok(addr,size) (1)

#define access_ok(type,addr,size) __access_ok(addr,size)

extern inline int verify_area(int type, const void __user *addr,
						unsigned long size)
{
	return access_ok(type, addr, size) ? 0 : -EFAULT;
}

/*
 * The exception table consists of pairs of addresses: the first is the
 * address of an instruction that is allowed to fault, and the second is
 * the address at which the program should continue.  No registers are
 * modified, so it is entirely up to the continuation code to figure out
 * what to do.
 *
 * All the routines below use bits of fixup code that are out of line
 * with the main instruction path.  This means when everything is well,
 * we don't even have to jump over them.  Further, they do not intrude
 * on our cache or tlb entries.
 */

struct exception_table_entry
{
        unsigned long insn, fixup;
};

#ifndef __s390x__
#define __uaccess_fixup \
	".section .fixup,\"ax\"\n"	\
	"2: lhi    %0,%4\n"		\
	"   bras   1,3f\n"		\
	"   .long  1b\n"		\
	"3: l      1,0(1)\n"		\
	"   br     1\n"			\
	".previous\n"			\
	".section __ex_table,\"a\"\n"	\
	"   .align 4\n"			\
	"   .long  0b,2b\n"		\
	".previous"
#define __uaccess_clobber "cc", "1"
#else /* __s390x__ */
#define __uaccess_fixup \
	".section .fixup,\"ax\"\n"	\
	"2: lghi   %0,%4\n"		\
	"   jg     1b\n"		\
	".previous\n"			\
	".section __ex_table,\"a\"\n"	\
	"   .align 8\n"			\
	"   .quad  0b,2b\n"		\
	".previous"
#define __uaccess_clobber "cc"
#endif /* __s390x__ */

/*
 * These are the main single-value transfer routines.  They automatically
 * use the right size if we just have the right pointer type.
 */
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
#define __put_user_asm(x, ptr, err) \
({								\
	err = 0;						\
	asm volatile(						\
		"0: mvcs  0(%1,%2),%3,%0\n"			\
		"1:\n"						\
		__uaccess_fixup					\
		: "+&d" (err)					\
		: "d" (sizeof(*(ptr))), "a" (ptr), "Q" (x),	\
		  "K" (-EFAULT)					\
		: __uaccess_clobber );				\
})
#else
#define __put_user_asm(x, ptr, err) \
({								\
	err = 0;						\
	asm volatile(						\
		"0: mvcs  0(%1,%2),0(%3),%0\n"			\
		"1:\n"						\
		__uaccess_fixup					\
		: "+&d" (err)					\
		: "d" (sizeof(*(ptr))), "a" (ptr), "a" (&(x)),	\
		  "K" (-EFAULT), "m" (x)			\
		: __uaccess_clobber );				\
})
#endif

#ifndef __CHECKER__
#define __put_user(x, ptr) \
({								\
	__typeof__(*(ptr)) __x = (x);				\
	int __pu_err;						\
	switch (sizeof (*(ptr))) {				\
	case 1:							\
	case 2:							\
	case 4:							\
	case 8:							\
		__put_user_asm(__x, ptr, __pu_err);		\
		break;						\
	default:						\
		__pu_err = __put_user_bad();			\
		break;						\
	 }							\
	__pu_err;						\
})
#else
#define __put_user(x, ptr)			\
({						\
	void __user *p;				\
	p = (ptr);				\
	0;					\
})
#endif

#define put_user(x, ptr)					\
({								\
	might_sleep();						\
	__put_user(x, ptr);					\
})


extern int __put_user_bad(void);

#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
#define __get_user_asm(x, ptr, err) \
({								\
	err = 0;						\
	asm volatile (						\
		"0: mvcp  %O1(%2,%R1),0(%3),%0\n"		\
		"1:\n"						\
		__uaccess_fixup					\
		: "+&d" (err), "=Q" (x)				\
		: "d" (sizeof(*(ptr))), "a" (ptr),		\
		  "K" (-EFAULT)					\
		: __uaccess_clobber );				\
})
#else
#define __get_user_asm(x, ptr, err) \
({								\
	err = 0;						\
	asm volatile (						\
		"0: mvcp  0(%2,%5),0(%3),%0\n"			\
		"1:\n"						\
		__uaccess_fixup					\
		: "+&d" (err), "=m" (x)				\
		: "d" (sizeof(*(ptr))), "a" (ptr),		\
		  "K" (-EFAULT), "a" (&(x))			\
		: __uaccess_clobber );				\
})
#endif

#ifndef __CHECKER__
#define __get_user(x, ptr)					\
({								\
	__typeof__(*(ptr)) __x;					\
	int __gu_err;						\
	switch (sizeof(*(ptr))) {				\
	case 1:							\
	case 2:							\
	case 4:							\
	case 8:							\
		__get_user_asm(__x, ptr, __gu_err);		\
		break;						\
	default:						\
		__x = 0;					\
		__gu_err = __get_user_bad();			\
		break;						\
	}							\
	(x) = __x;						\
	__gu_err;						\
})
#else
#define __get_user(x, ptr)			\
({						\
	void __user *p;				\
	p = (ptr);				\
	0;					\
})
#endif


#define get_user(x, ptr)					\
({								\
	might_sleep();						\
	__get_user(x, ptr);					\
})

extern int __get_user_bad(void);

#define __put_user_unaligned __put_user
#define __get_user_unaligned __get_user

extern long __copy_to_user_asm(const void *from, long n, void __user *to);

/**
 * __copy_to_user: - Copy a block of data into user space, with less checking.
 * @to:   Destination address, in user space.
 * @from: Source address, in kernel space.
 * @n:    Number of bytes to copy.
 *
 * Context: User context only.  This function may sleep.
 *
 * Copy data from kernel space to user space.  Caller must check
 * the specified block with access_ok() before calling this function.
 *
 * Returns number of bytes that could not be copied.
 * On success, this will be zero.
 */
static inline unsigned long
__copy_to_user(void __user *to, const void *from, unsigned long n)
{
	return __copy_to_user_asm(from, n, to);
}

#define __copy_to_user_inatomic __copy_to_user
#define __copy_from_user_inatomic __copy_from_user

/**
 * copy_to_user: - Copy a block of data into user space.
 * @to:   Destination address, in user space.
 * @from: Source address, in kernel space.
 * @n:    Number of bytes to copy.
 *
 * Context: User context only.  This function may sleep.
 *
 * Copy data from kernel space to user space.
 *
 * Returns number of bytes that could not be copied.
 * On success, this will be zero.
 */
static inline unsigned long
copy_to_user(void __user *to, const void *from, unsigned long n)
{
	might_sleep();
	if (access_ok(VERIFY_WRITE, to, n))
		n = __copy_to_user(to, from, n);
	return n;
}

extern long __copy_from_user_asm(void *to, long n, const void __user *from);

/**
 * __copy_from_user: - Copy a block of data from user space, with less checking.
 * @to:   Destination address, in kernel space.
 * @from: Source address, in user space.
 * @n:    Number of bytes to copy.
 *
 * Context: User context only.  This function may sleep.
 *
 * Copy data from user space to kernel space.  Caller must check
 * the specified block with access_ok() before calling this function.
 *
 * Returns number of bytes that could not be copied.
 * On success, this will be zero.
 *
 * If some data could not be copied, this function will pad the copied
 * data to the requested size using zero bytes.
 */
static inline unsigned long
__copy_from_user(void *to, const void __user *from, unsigned long n)
{
	return __copy_from_user_asm(to, n, from);
}

/**
 * copy_from_user: - Copy a block of data from user space.
 * @to:   Destination address, in kernel space.
 * @from: Source address, in user space.
 * @n:    Number of bytes to copy.
 *
 * Context: User context only.  This function may sleep.
 *
 * Copy data from user space to kernel space.
 *
 * Returns number of bytes that could not be copied.
 * On success, this will be zero.
 *
 * If some data could not be copied, this function will pad the copied
 * data to the requested size using zero bytes.
 */
static inline unsigned long
copy_from_user(void *to, const void __user *from, unsigned long n)
{
	might_sleep();
	if (access_ok(VERIFY_READ, from, n))
		n = __copy_from_user(to, from, n);
	else
		memset(to, 0, n);
	return n;
}

extern unsigned long __copy_in_user_asm(const void __user *from, long n,
							void __user *to);

static inline unsigned long
__copy_in_user(void __user *to, const void __user *from, unsigned long n)
{
	return __copy_in_user_asm(from, n, to);
}

static inline unsigned long
copy_in_user(void __user *to, const void __user *from, unsigned long n)
{
	might_sleep();
	if (__access_ok(from,n) && __access_ok(to,n))
		n = __copy_in_user_asm(from, n, to);
	return n;
}

/*
 * Copy a null terminated string from userspace.
 */
extern long __strncpy_from_user_asm(long count, char *dst,
					const char __user *src);

static inline long
strncpy_from_user(char *dst, const char __user *src, long count)
{
        long res = -EFAULT;
        might_sleep();
        if (access_ok(VERIFY_READ, src, 1))
                res = __strncpy_from_user_asm(count, dst, src);
        return res;
}


extern long __strnlen_user_asm(long count, const char __user *src);

static inline unsigned long
strnlen_user(const char __user * src, unsigned long n)
{
	might_sleep();
	return __strnlen_user_asm(n, src);
}

/**
 * strlen_user: - Get the size of a string in user space.
 * @str: The string to measure.
 *
 * Context: User context only.  This function may sleep.
 *
 * Get the size of a NUL-terminated string in user space.
 *
 * Returns the size of the string INCLUDING the terminating NUL.
 * On exception, returns 0.
 *
 * If there is a limit on the length of a valid string, you may wish to
 * consider using strnlen_user() instead.
 */
#define strlen_user(str) strnlen_user(str, ~0UL)

/*
 * Zero Userspace
 */

extern long __clear_user_asm(void __user *to, long n);

static inline unsigned long
__clear_user(void __user *to, unsigned long n)
{
	return __clear_user_asm(to, n);
}

static inline unsigned long
clear_user(void __user *to, unsigned long n)
{
	might_sleep();
	if (access_ok(VERIFY_WRITE, to, n))
		n = __clear_user_asm(to, n);
	return n;
}

#endif /* __S390_UACCESS_H */
