arch/sparc/include/asm/uaccess_64.h

Source file repositories/reference/linux-study-clean/arch/sparc/include/asm/uaccess_64.h

File Facts

System
Linux kernel
Corpus path
arch/sparc/include/asm/uaccess_64.h
Extension
.h
Size
7882 bytes
Lines
252
Domain
Architecture Layer
Bucket
arch/sparc
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct __large_struct { unsigned long buf[100]; };
#define __m(x) ((struct __large_struct *)(x))

#define __put_kernel_nofault(dst, src, type, label)			\
do {									\
	type *addr = (type __force *)(dst);				\
	type data = *(type *)src;					\
	register int __pu_ret;						\
	switch (sizeof(type)) {						\
	case 1: __put_kernel_asm(data, b, addr, __pu_ret); break;	\
	case 2: __put_kernel_asm(data, h, addr, __pu_ret); break;	\
	case 4: __put_kernel_asm(data, w, addr, __pu_ret); break;	\
	case 8: __put_kernel_asm(data, x, addr, __pu_ret); break;	\
	default: __pu_ret = __put_user_bad(); break;			\
	}								\
	if (__pu_ret)							\
		goto label;						\
} while (0)

#define __put_kernel_asm(x, size, addr, ret)				\
__asm__ __volatile__(							\
		"/* Put kernel asm, inline. */\n"			\
	"1:\t"	"st"#size " %1, [%2]\n\t"				\
		"clr	%0\n"						\
	"2:\n\n\t"							\
		".section .fixup,#alloc,#execinstr\n\t"			\
		".align	4\n"						\
	"3:\n\t"							\
		"sethi	%%hi(2b), %0\n\t"				\
		"jmpl	%0 + %%lo(2b), %%g0\n\t"			\
		" mov	%3, %0\n\n\t"					\
		".previous\n\t"						\
		".section __ex_table,\"a\"\n\t"				\
		".align	4\n\t"						\
		".word	1b, 3b\n\t"					\
		".previous\n\n\t"					\
	       : "=r" (ret) : "r" (x), "r" (__m(addr)),			\
		 "i" (-EFAULT))

#define __put_user_nocheck(data, addr, size) ({			\
	register int __pu_ret;					\
	switch (size) {						\
	case 1: __put_user_asm(data, b, addr, __pu_ret); break;	\
	case 2: __put_user_asm(data, h, addr, __pu_ret); break;	\
	case 4: __put_user_asm(data, w, addr, __pu_ret); break;	\
	case 8: __put_user_asm(data, x, addr, __pu_ret); break;	\
	default: __pu_ret = __put_user_bad(); break;		\
	}							\
	__pu_ret;						\
})

#define __put_user_asm(x, size, addr, ret)				\
__asm__ __volatile__(							\
		"/* Put user asm, inline. */\n"				\
	"1:\t"	"st"#size "a %1, [%2] %%asi\n\t"			\
		"clr	%0\n"						\
	"2:\n\n\t"							\
		".section .fixup,#alloc,#execinstr\n\t"			\
		".align	4\n"						\
	"3:\n\t"							\
		"sethi	%%hi(2b), %0\n\t"				\
		"jmpl	%0 + %%lo(2b), %%g0\n\t"			\
		" mov	%3, %0\n\n\t"					\
		".previous\n\t"						\
		".section __ex_table,\"a\"\n\t"				\
		".align	4\n\t"						\
		".word	1b, 3b\n\t"					\
		".previous\n\n\t"					\
	       : "=r" (ret) : "r" (x), "r" (__m(addr)),			\
		 "i" (-EFAULT))

int __put_user_bad(void);

#define __get_kernel_nofault(dst, src, type, label)			     \
do {									     \
	type *addr = (type __force *)(src);		     		     \
	register int __gu_ret;						     \
	register unsigned long __gu_val;				     \
	switch (sizeof(type)) {						     \
		case 1: __get_kernel_asm(__gu_val, ub, addr, __gu_ret); break; \
		case 2: __get_kernel_asm(__gu_val, uh, addr, __gu_ret); break; \
		case 4: __get_kernel_asm(__gu_val, uw, addr, __gu_ret); break; \
		case 8: __get_kernel_asm(__gu_val, x, addr, __gu_ret); break;  \
		default:						     \
			__gu_val = 0;					     \
			__gu_ret = __get_user_bad();			     \
			break;						     \
	} 								     \
	if (__gu_ret)							     \
		goto label;						     \

Annotation

Implementation Notes