cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

syscall.h (3903B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2/*
      3 * Access to user system call parameters and results
      4 *
      5 *  Copyright IBM Corp. 2008
      6 *  Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
      7 */
      8
      9#ifndef _ASM_SYSCALL_H
     10#define _ASM_SYSCALL_H	1
     11
     12#include <uapi/linux/audit.h>
     13#include <linux/sched.h>
     14#include <linux/err.h>
     15#include <asm/ptrace.h>
     16
     17extern const sys_call_ptr_t sys_call_table[];
     18extern const sys_call_ptr_t sys_call_table_emu[];
     19
     20static inline long syscall_get_nr(struct task_struct *task,
     21				  struct pt_regs *regs)
     22{
     23	return test_pt_regs_flag(regs, PIF_SYSCALL) ?
     24		(regs->int_code & 0xffff) : -1;
     25}
     26
     27static inline void syscall_rollback(struct task_struct *task,
     28				    struct pt_regs *regs)
     29{
     30	regs->gprs[2] = regs->orig_gpr2;
     31}
     32
     33static inline long syscall_get_error(struct task_struct *task,
     34				     struct pt_regs *regs)
     35{
     36	unsigned long error = regs->gprs[2];
     37#ifdef CONFIG_COMPAT
     38	if (test_tsk_thread_flag(task, TIF_31BIT)) {
     39		/*
     40		 * Sign-extend the value so (int)-EFOO becomes (long)-EFOO
     41		 * and will match correctly in comparisons.
     42		 */
     43		error = (long)(int)error;
     44	}
     45#endif
     46	return IS_ERR_VALUE(error) ? error : 0;
     47}
     48
     49static inline long syscall_get_return_value(struct task_struct *task,
     50					    struct pt_regs *regs)
     51{
     52	return regs->gprs[2];
     53}
     54
     55static inline void syscall_set_return_value(struct task_struct *task,
     56					    struct pt_regs *regs,
     57					    int error, long val)
     58{
     59	set_pt_regs_flag(regs, PIF_SYSCALL_RET_SET);
     60	regs->gprs[2] = error ? error : val;
     61}
     62
     63static inline void syscall_get_arguments(struct task_struct *task,
     64					 struct pt_regs *regs,
     65					 unsigned long *args)
     66{
     67	unsigned long mask = -1UL;
     68	unsigned int n = 6;
     69
     70#ifdef CONFIG_COMPAT
     71	if (test_tsk_thread_flag(task, TIF_31BIT))
     72		mask = 0xffffffff;
     73#endif
     74	while (n-- > 0)
     75		if (n > 0)
     76			args[n] = regs->gprs[2 + n] & mask;
     77
     78	args[0] = regs->orig_gpr2 & mask;
     79}
     80
     81static inline int syscall_get_arch(struct task_struct *task)
     82{
     83#ifdef CONFIG_COMPAT
     84	if (test_tsk_thread_flag(task, TIF_31BIT))
     85		return AUDIT_ARCH_S390;
     86#endif
     87	return AUDIT_ARCH_S390X;
     88}
     89
     90static inline bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs)
     91{
     92	return false;
     93}
     94
     95#define SYSCALL_FMT_0
     96#define SYSCALL_FMT_1 , "0" (r2)
     97#define SYSCALL_FMT_2 , "d" (r3) SYSCALL_FMT_1
     98#define SYSCALL_FMT_3 , "d" (r4) SYSCALL_FMT_2
     99#define SYSCALL_FMT_4 , "d" (r5) SYSCALL_FMT_3
    100#define SYSCALL_FMT_5 , "d" (r6) SYSCALL_FMT_4
    101#define SYSCALL_FMT_6 , "d" (r7) SYSCALL_FMT_5
    102
    103#define SYSCALL_PARM_0
    104#define SYSCALL_PARM_1 , long arg1
    105#define SYSCALL_PARM_2 SYSCALL_PARM_1, long arg2
    106#define SYSCALL_PARM_3 SYSCALL_PARM_2, long arg3
    107#define SYSCALL_PARM_4 SYSCALL_PARM_3, long arg4
    108#define SYSCALL_PARM_5 SYSCALL_PARM_4, long arg5
    109#define SYSCALL_PARM_6 SYSCALL_PARM_5, long arg6
    110
    111#define SYSCALL_REGS_0
    112#define SYSCALL_REGS_1							\
    113	register long r2 asm("2") = arg1
    114#define SYSCALL_REGS_2							\
    115	SYSCALL_REGS_1;							\
    116	register long r3 asm("3") = arg2
    117#define SYSCALL_REGS_3							\
    118	SYSCALL_REGS_2;							\
    119	register long r4 asm("4") = arg3
    120#define SYSCALL_REGS_4							\
    121	SYSCALL_REGS_3;							\
    122	register long r5 asm("5") = arg4
    123#define SYSCALL_REGS_5							\
    124	SYSCALL_REGS_4;							\
    125	register long r6 asm("6") = arg5
    126#define SYSCALL_REGS_6							\
    127	SYSCALL_REGS_5;							\
    128	register long r7 asm("7") = arg6
    129
    130#define GENERATE_SYSCALL_FUNC(nr)					\
    131static __always_inline							\
    132long syscall##nr(unsigned long syscall SYSCALL_PARM_##nr)		\
    133{									\
    134	register unsigned long r1 asm ("1") = syscall;			\
    135	register long rc asm ("2");					\
    136	SYSCALL_REGS_##nr;						\
    137									\
    138	asm volatile (							\
    139		"	svc	0\n"					\
    140		: "=d" (rc)						\
    141		: "d" (r1) SYSCALL_FMT_##nr				\
    142		: "memory");						\
    143	return rc;							\
    144}
    145
    146GENERATE_SYSCALL_FUNC(0)
    147GENERATE_SYSCALL_FUNC(1)
    148GENERATE_SYSCALL_FUNC(2)
    149GENERATE_SYSCALL_FUNC(3)
    150GENERATE_SYSCALL_FUNC(4)
    151GENERATE_SYSCALL_FUNC(5)
    152GENERATE_SYSCALL_FUNC(6)
    153
    154#endif	/* _ASM_SYSCALL_H */