arch/s390/include/asm/syscall.h

Source file repositories/reference/linux-study-clean/arch/s390/include/asm/syscall.h

File Facts

System
Linux kernel
Corpus path
arch/s390/include/asm/syscall.h
Extension
.h
Size
4017 bytes
Lines
157
Domain
Architecture Layer
Bucket
arch/s390
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

#ifndef _ASM_SYSCALL_H
#define _ASM_SYSCALL_H	1

#include <uapi/linux/audit.h>
#include <linux/sched.h>
#include <linux/err.h>
#include <asm/ptrace.h>

extern const sys_call_ptr_t sys_call_table[];

static inline long syscall_get_nr(struct task_struct *task,
				  struct pt_regs *regs)
{
	return test_pt_regs_flag(regs, PIF_SYSCALL) ?
		(regs->int_code & 0xffff) : -1;
}

static inline void syscall_set_nr(struct task_struct *task,
				  struct pt_regs *regs,
				  int nr)
{
	/*
	 * Unlike syscall_get_nr(), syscall_set_nr() can be called only when
	 * the target task is stopped for tracing on entering syscall, so
	 * there is no need to have the same check syscall_get_nr() has.
	 */
	regs->int_code = (regs->int_code & ~0xffff) | (nr & 0xffff);
}

static inline void syscall_rollback(struct task_struct *task,
				    struct pt_regs *regs)
{
	regs->gprs[2] = regs->orig_gpr2;
}

static inline long syscall_get_error(struct task_struct *task,
				     struct pt_regs *regs)
{
	unsigned long error = regs->gprs[2];

	return IS_ERR_VALUE(error) ? error : 0;
}

static inline long syscall_get_return_value(struct task_struct *task,
					    struct pt_regs *regs)
{
	return regs->gprs[2];
}

static inline void syscall_set_return_value(struct task_struct *task,
					    struct pt_regs *regs,
					    int error, long val)
{
	set_pt_regs_flag(regs, PIF_SYSCALL_RET_SET);
	regs->gprs[2] = error ? error : val;
}

static inline void syscall_get_arguments(struct task_struct *task,
					 struct pt_regs *regs,
					 unsigned long *args)
{
	unsigned long mask = -1UL;

	for (int i = 1; i < 6; i++)
		args[i] = regs->gprs[2 + i] & mask;

	args[0] = regs->orig_gpr2 & mask;
}

static inline void syscall_set_arguments(struct task_struct *task,
					 struct pt_regs *regs,
					 const unsigned long *args)
{
	regs->orig_gpr2 = args[0];
	for (int n = 1; n < 6; n++)
		regs->gprs[2 + n] = args[n];
}

static inline int syscall_get_arch(struct task_struct *task)
{
	return AUDIT_ARCH_S390X;
}

static inline bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs)
{
	return false;
}

#define SYSCALL_FMT_0
#define SYSCALL_FMT_1 , "0" (r2)

Annotation

Implementation Notes