arch/sparc/kernel/sys_sparc_32.c

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

File Facts

System
Linux kernel
Corpus path
arch/sparc/kernel/sys_sparc_32.c
Extension
.c
Size
5539 bytes
Lines
232
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; /* Possibly older binaries want 8192 on sun4's? */
}

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 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;
	}

	/* See asm-sparc/uaccess.h */
	if (len > TASK_SIZE - PAGE_SIZE)
		return -ENOMEM;
	if (!addr)
		addr = TASK_UNMAPPED_BASE;

	info.length = len;
	info.low_limit = addr;
	info.high_limit = TASK_SIZE;
	if (!file_hugepage) {
		info.align_mask = (flags & MAP_SHARED) ?
			(PAGE_MASK & (SHMLBA - 1)) : 0;
		info.align_offset = pgoff << PAGE_SHIFT;
	} else {
		info.align_mask = huge_page_mask_align(filp);
	}
	return vm_unmapped_area(&info);
}

/*
 * sys_pipe() is the normal C calling standard for creating
 * a pipe. It's not the way unix traditionally does this, though.
 */
SYSCALL_DEFINE0(sparc_pipe)
{
	int fd[2];
	int error;

	error = do_pipe_flags(fd, 0);
	if (error)
		goto out;
	current_pt_regs()->u_regs[UREG_I1] = fd[1];
	error = fd[0];
out:
	return error;
}

int sparc_mmap_check(unsigned long addr, unsigned long len)
{
	/* See asm-sparc/uaccess.h */
	if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE)
		return -EINVAL;

	return 0;
}

/* Linux version of mmap */

SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
	unsigned long, prot, unsigned long, flags, unsigned long, fd,
	unsigned long, pgoff)
{
	/* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE
	   we have. */
	return ksys_mmap_pgoff(addr, len, prot, flags, fd,
			       pgoff >> (PAGE_SHIFT - 12));
}

SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
	unsigned long, prot, unsigned long, flags, unsigned long, fd,
	unsigned long, off)
{
	/* no alignment check? */
	return ksys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
}

SYSCALL_DEFINE5(sparc_remap_file_pages, unsigned long, start, unsigned long, size,

Annotation

Implementation Notes