arch/x86/kernel/sys_ia32.c

Source file repositories/reference/linux-study-clean/arch/x86/kernel/sys_ia32.c

File Facts

System
Linux kernel
Corpus path
arch/x86/kernel/sys_ia32.c
Extension
.c
Size
7554 bytes
Lines
258
Domain
Architecture Layer
Bucket
arch/x86
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_DEFINE3(ia32_truncate64, const char __user *, filename,
		unsigned long, offset_low, unsigned long, offset_high)
{
	return ksys_truncate(filename,
			    ((loff_t) offset_high << 32) | offset_low);
}

SYSCALL_DEFINE3(ia32_ftruncate64, unsigned int, fd,
		unsigned long, offset_low, unsigned long, offset_high)
{
	return ksys_ftruncate(fd, ((loff_t) offset_high << 32) | offset_low,
			FTRUNCATE_LFS);
}

/* warning: next two assume little endian */
SYSCALL_DEFINE5(ia32_pread64, unsigned int, fd, char __user *, ubuf,
		u32, count, u32, poslo, u32, poshi)
{
	return ksys_pread64(fd, ubuf, count,
			    ((loff_t)AA(poshi) << 32) | AA(poslo));
}

SYSCALL_DEFINE5(ia32_pwrite64, unsigned int, fd, const char __user *, ubuf,
		u32, count, u32, poslo, u32, poshi)
{
	return ksys_pwrite64(fd, ubuf, count,
			     ((loff_t)AA(poshi) << 32) | AA(poslo));
}


/*
 * Some system calls that need sign extended arguments. This could be
 * done by a generic wrapper.
 */
SYSCALL_DEFINE6(ia32_fadvise64_64, int, fd, __u32, offset_low,
		__u32, offset_high, __u32, len_low, __u32, len_high,
		int, advice)
{
	return ksys_fadvise64_64(fd,
				 (((u64)offset_high)<<32) | offset_low,
				 (((u64)len_high)<<32) | len_low,
				 advice);
}

SYSCALL_DEFINE4(ia32_readahead, int, fd, unsigned int, off_lo,
		unsigned int, off_hi, size_t, count)
{
	return ksys_readahead(fd, ((u64)off_hi << 32) | off_lo, count);
}

SYSCALL_DEFINE6(ia32_sync_file_range, int, fd, unsigned int, off_low,
		unsigned int, off_hi, unsigned int, n_low,
		unsigned int, n_hi, int, flags)
{
	return ksys_sync_file_range(fd,
				    ((u64)off_hi << 32) | off_low,
				    ((u64)n_hi << 32) | n_low, flags);
}

SYSCALL_DEFINE5(ia32_fadvise64, int, fd, unsigned int, offset_lo,
		unsigned int, offset_hi, size_t, len, int, advice)
{
	return ksys_fadvise64_64(fd, ((u64)offset_hi << 32) | offset_lo,
				 len, advice);
}

SYSCALL_DEFINE6(ia32_fallocate, int, fd, int, mode,
		unsigned int, offset_lo, unsigned int, offset_hi,
		unsigned int, len_lo, unsigned int, len_hi)
{
	return ksys_fallocate(fd, mode, ((u64)offset_hi << 32) | offset_lo,
			      ((u64)len_hi << 32) | len_lo);
}

#ifdef CONFIG_IA32_EMULATION
/*
 * Another set for IA32/LFS -- x86_64 struct stat is different due to
 * support for 64bit inode numbers.
 */
static int cp_stat64(struct stat64 __user *ubuf, struct kstat *stat)
{
	typeof(ubuf->st_uid) uid = 0;
	typeof(ubuf->st_gid) gid = 0;
	SET_UID(uid, from_kuid_munged(current_user_ns(), stat->uid));
	SET_GID(gid, from_kgid_munged(current_user_ns(), stat->gid));
	if (!user_write_access_begin(ubuf, sizeof(struct stat64)))
		return -EFAULT;
	unsafe_put_user(huge_encode_dev(stat->dev), &ubuf->st_dev, Efault);
	unsafe_put_user(stat->ino, &ubuf->__st_ino, Efault);
	unsafe_put_user(stat->ino, &ubuf->st_ino, Efault);

Annotation

Implementation Notes