arch/loongarch/include/asm/uaccess.h

Source file repositories/reference/linux-study-clean/arch/loongarch/include/asm/uaccess.h

File Facts

System
Linux kernel
Corpus path
arch/loongarch/include/asm/uaccess.h
Extension
.h
Size
9515 bytes
Lines
323
Domain
Architecture Layer
Bucket
arch/loongarch
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 __user *)(x))

#define __get_user_common(val, size, ptr)				\
do {									\
	switch (size) {							\
	case 1: __get_data_asm(val, "ld.b", ptr); break;		\
	case 2: __get_data_asm(val, "ld.h", ptr); break;		\
	case 4: __get_data_asm(val, "ld.w", ptr); break;		\
	case 8: __get_data_asm_8(val, ptr); break;			\
	default: BUILD_BUG(); break;					\
	}								\
} while (0)

#define __get_kernel_common(val, size, ptr) __get_user_common(val, size, ptr)

#define __get_data_asm(val, insn, ptr)					\
{									\
	long __gu_tmp;							\
									\
	__asm__ __volatile__(						\
	"1:	" insn "	%1, %2				\n"	\
	"2:							\n"	\
	_ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 2b, %0, %1)			\
	: "+r" (__gu_err), "=r" (__gu_tmp)				\
	: "m" (__m(ptr)));						\
									\
	(val) = (__typeof__(*(ptr))) __gu_tmp;				\
}

#ifdef CONFIG_64BIT
#define __get_data_asm_8(val, ptr) \
	__get_data_asm(val, "ld.d", ptr)
#else /* !CONFIG_64BIT */
#define __get_data_asm_8(val, ptr)					\
{									\
	u32 __lo, __hi;							\
	u32 __user *__ptr = (u32 __user *)(ptr);			\
									\
	__asm__ __volatile__ (						\
		"1:\n"							\
		"	ld.w %1, %3				\n"	\
		"2:\n"							\
		"	ld.w %2, %4				\n"	\
		"3:\n"							\
		_ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 3b, %0, %1)		\
		_ASM_EXTABLE_UACCESS_ERR_ZERO(2b, 3b, %0, %1)		\
		: "+r" (__gu_err), "=&r" (__lo), "=r" (__hi)		\
		: "m" (__ptr[__LSW]), "m" (__ptr[__MSW]));		\
	if (__gu_err)							\
		__hi = 0;						\
	(val) = (__typeof__(val))((__typeof__((val)-(val)))		\
		((((u64)__hi << 32) | __lo)));				\
}
#endif /* CONFIG_64BIT */

#define __put_user_common(ptr, size)					\
do {									\
	switch (size) {							\
	case 1: __put_data_asm("st.b", ptr); break;			\
	case 2: __put_data_asm("st.h", ptr); break;			\
	case 4: __put_data_asm("st.w", ptr); break;			\
	case 8: __put_data_asm_8(ptr); break;				\
	default: BUILD_BUG(); break;					\
	}								\
} while (0)

#define __put_kernel_common(ptr, size) __put_user_common(ptr, size)

#define __put_data_asm(insn, ptr)					\
{									\
	__asm__ __volatile__(						\
	"1:	" insn "	%z2, %1		# __put_user_asm\n"	\
	"2:							\n"	\
	_ASM_EXTABLE_UACCESS_ERR(1b, 2b, %0)				\
	: "+r" (__pu_err), "=m" (__m(ptr))				\
	: "Jr" (__pu_val));						\
}

#ifdef CONFIG_64BIT
#define __put_data_asm_8(ptr) \
	__put_data_asm("st.d", ptr)
#else /* !CONFIG_64BIT */
#define __put_data_asm_8(ptr)						\
{									\
	u32 __user *__ptr = (u32 __user *)(ptr);			\
	u64 __x = (__typeof__((__pu_val)-(__pu_val)))(__pu_val);	\
									\
	__asm__ __volatile__ (						\
		"1:\n"							\

Annotation

Implementation Notes