arch/arm/include/asm/fncpy.h

Source file repositories/reference/linux-study-clean/arch/arm/include/asm/fncpy.h

File Facts

System
Linux kernel
Corpus path
arch/arm/include/asm/fncpy.h
Extension
.h
Size
2552 bytes
Lines
83
Domain
Architecture Layer
Bucket
arch/arm
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

#ifndef __ASM_FNCPY_H
#define __ASM_FNCPY_H

#include <linux/types.h>
#include <linux/string.h>

#include <asm/bug.h>
#include <asm/cacheflush.h>

/*
 * Minimum alignment requirement for the source and destination addresses
 * for function copying.
 */
#define FNCPY_ALIGN 8

#define fncpy(dest_buf, funcp, size) ({					\
	uintptr_t __funcp_address;					\
	typeof(funcp) __result;						\
									\
	asm("" : "=r" (__funcp_address) : "0" (funcp));			\
									\
	/*								\
	 * Ensure alignment of source and destination addresses,	\
	 * disregarding the function's Thumb bit:			\
	 */								\
	BUG_ON((uintptr_t)(dest_buf) & (FNCPY_ALIGN - 1) ||		\
		(__funcp_address & ~(uintptr_t)1 & (FNCPY_ALIGN - 1)));	\
									\
	memcpy(dest_buf, (void const *)(__funcp_address & ~1), size);	\
	flush_icache_range((unsigned long)(dest_buf),			\
		(unsigned long)(dest_buf) + (size));			\
									\
	asm("" : "=r" (__result)					\
		: "0" ((uintptr_t)(dest_buf) | (__funcp_address & 1)));	\
									\
	__result;							\
})

#endif /* !__ASM_FNCPY_H */

Annotation

Implementation Notes