arch/sparc/kernel/sys_sparc_64.c

Source file repositories/reference/linux-study-clean/arch/sparc/kernel/sys_sparc_64.c

File Facts

System
Linux kernel
Corpus path
arch/sparc/kernel/sys_sparc_64.c
Extension
.c
Size
17774 bytes
Lines
724
Domain
Architecture Layer
Bucket
arch/sparc
Inferred role
Architecture Layer: syscall or user/kernel boundary
Status
core 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

SYSCALL_DEFINE0(getpagesize)
{
	return PAGE_SIZE;
}

/* Does addr --> addr+len fall within 4GB of the VA-space hole or
 * overflow past the end of the 64-bit address space?
 */
static inline int invalid_64bit_range(unsigned long addr, unsigned long len)
{
	unsigned long va_exclude_start, va_exclude_end;

	va_exclude_start = VA_EXCLUDE_START;
	va_exclude_end   = VA_EXCLUDE_END;

	if (unlikely(len >= va_exclude_start))
		return 1;

	if (unlikely((addr + len) < addr))
		return 1;

	if (unlikely((addr >= va_exclude_start && addr < va_exclude_end) ||
		     ((addr + len) >= va_exclude_start &&
		      (addr + len) < va_exclude_end)))
		return 1;

	return 0;
}

/* These functions differ from the default implementations in
 * mm/mmap.c in two ways:
 *
 * 1) For file backed MAP_SHARED mmap()'s we D-cache color align,
 *    for fixed such mappings we just validate what the user gave us.
 * 2) For 64-bit tasks we avoid mapping anything within 4GB of
 *    the spitfire/niagara VA-hole.
 */

static inline unsigned long COLOR_ALIGN(unsigned long addr,
					 unsigned long pgoff)
{
	unsigned long base = (addr+SHMLBA-1)&~(SHMLBA-1);
	unsigned long off = (pgoff<<PAGE_SHIFT) & (SHMLBA-1);

	return base + off;
}

static unsigned long get_align_mask(struct file *filp, unsigned long flags)
{
	if (filp && is_file_hugepages(filp))
		return huge_page_mask_align(filp);
	if (filp || (flags & MAP_SHARED))
		return PAGE_MASK & (SHMLBA - 1);

	return 0;
}

unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags)
{
	struct mm_struct *mm = current->mm;
	struct vm_area_struct * vma;
	unsigned long task_size = TASK_SIZE;
	int do_color_align;
	struct vm_unmapped_area_info info = {};
	bool file_hugepage = false;

	if (filp && is_file_hugepages(filp))
		file_hugepage = true;

	if (flags & MAP_FIXED) {
		/* We do not accept a shared mapping if it would violate
		 * cache aliasing constraints.
		 */
		if (!file_hugepage && (flags & MAP_SHARED) &&
		    ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
			return -EINVAL;
		return addr;
	}

	if (test_thread_flag(TIF_32BIT))
		task_size = STACK_TOP32;
	if (unlikely(len > task_size || len >= VA_EXCLUDE_START))
		return -ENOMEM;

	do_color_align = 0;
	if ((filp || (flags & MAP_SHARED)) && !file_hugepage)
		do_color_align = 1;

	if (addr) {
		if (do_color_align)

Annotation

Implementation Notes