LCOV - code coverage report
Current view: top level - arch/x86/include/asm - syscall.h (source / functions) Hit Total Coverage
Test: combined.info Lines: 8 31 25.8 %
Date: 2022-04-01 13:59:58 Functions: 0 0 -
Branches: 8 22 36.4 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: GPL-2.0-only */
       2                 :            : /*
       3                 :            :  * Access to user system call parameters and results
       4                 :            :  *
       5                 :            :  * Copyright (C) 2008-2009 Red Hat, Inc.  All rights reserved.
       6                 :            :  *
       7                 :            :  * See asm-generic/syscall.h for descriptions of what we must do here.
       8                 :            :  */
       9                 :            : 
      10                 :            : #ifndef _ASM_X86_SYSCALL_H
      11                 :            : #define _ASM_X86_SYSCALL_H
      12                 :            : 
      13                 :            : #include <uapi/linux/audit.h>
      14                 :            : #include <linux/sched.h>
      15                 :            : #include <linux/err.h>
      16                 :            : #include <asm/asm-offsets.h>      /* For NR_syscalls */
      17                 :            : #include <asm/thread_info.h>      /* for TS_COMPAT */
      18                 :            : #include <asm/unistd.h>
      19                 :            : 
      20                 :            : #ifdef CONFIG_X86_64
      21                 :            : typedef asmlinkage long (*sys_call_ptr_t)(const struct pt_regs *);
      22                 :            : #else
      23                 :            : typedef asmlinkage long (*sys_call_ptr_t)(unsigned long, unsigned long,
      24                 :            :                                           unsigned long, unsigned long,
      25                 :            :                                           unsigned long, unsigned long);
      26                 :            : #endif /* CONFIG_X86_64 */
      27                 :            : extern const sys_call_ptr_t sys_call_table[];
      28                 :            : 
      29                 :            : #if defined(CONFIG_X86_32)
      30                 :            : #define ia32_sys_call_table sys_call_table
      31                 :            : #define __NR_syscall_compat_max __NR_syscall_max
      32                 :            : #define IA32_NR_syscalls NR_syscalls
      33                 :            : #endif
      34                 :            : 
      35                 :            : #if defined(CONFIG_IA32_EMULATION)
      36                 :            : extern const sys_call_ptr_t ia32_sys_call_table[];
      37                 :            : #endif
      38                 :            : 
      39                 :            : #ifdef CONFIG_X86_X32_ABI
      40                 :            : extern const sys_call_ptr_t x32_sys_call_table[];
      41                 :            : #endif
      42                 :            : 
      43                 :            : /*
      44                 :            :  * Only the low 32 bits of orig_ax are meaningful, so we return int.
      45                 :            :  * This importantly ignores the high bits on 64-bit, so comparisons
      46                 :            :  * sign-extend the low 32 bits.
      47                 :            :  */
      48                 :     269139 : static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
      49                 :            : {
      50   [ -  +  -  + ]:     269139 :         return regs->orig_ax;
      51                 :            : }
      52                 :            : 
      53                 :          0 : static inline void syscall_rollback(struct task_struct *task,
      54                 :            :                                     struct pt_regs *regs)
      55                 :            : {
      56                 :          0 :         regs->ax = regs->orig_ax;
      57                 :            : }
      58                 :            : 
      59                 :     269139 : static inline long syscall_get_error(struct task_struct *task,
      60                 :            :                                      struct pt_regs *regs)
      61                 :            : {
      62                 :     269139 :         unsigned long error = regs->ax;
      63                 :            : #ifdef CONFIG_IA32_EMULATION
      64                 :            :         /*
      65                 :            :          * TS_COMPAT is set for 32-bit syscall entries and then
      66                 :            :          * remains set until we return to user mode.
      67                 :            :          */
      68   [ -  +  -  + ]:     269139 :         if (task->thread_info.status & (TS_COMPAT|TS_I386_REGS_POKED))
      69                 :            :                 /*
      70                 :            :                  * Sign-extend the value so (int)-EFOO becomes (long)-EFOO
      71                 :            :                  * and will match correctly in comparisons.
      72                 :            :                  */
      73                 :          0 :                 error = (long) (int) error;
      74                 :            : #endif
      75   [ +  +  -  + ]:     269139 :         return IS_ERR_VALUE(error) ? error : 0;
      76                 :            : }
      77                 :            : 
      78                 :          0 : static inline long syscall_get_return_value(struct task_struct *task,
      79                 :            :                                             struct pt_regs *regs)
      80                 :            : {
      81                 :          0 :         return regs->ax;
      82                 :            : }
      83                 :            : 
      84                 :        780 : static inline void syscall_set_return_value(struct task_struct *task,
      85                 :            :                                             struct pt_regs *regs,
      86                 :            :                                             int error, long val)
      87                 :            : {
      88         [ +  - ]:       1560 :         regs->ax = (long) error ?: val;
      89                 :            : }
      90                 :            : 
      91                 :            : #ifdef CONFIG_X86_32
      92                 :            : 
      93                 :            : static inline void syscall_get_arguments(struct task_struct *task,
      94                 :            :                                          struct pt_regs *regs,
      95                 :            :                                          unsigned long *args)
      96                 :            : {
      97                 :            :         memcpy(args, &regs->bx, 6 * sizeof(args[0]));
      98                 :            : }
      99                 :            : 
     100                 :            : static inline void syscall_set_arguments(struct task_struct *task,
     101                 :            :                                          struct pt_regs *regs,
     102                 :            :                                          unsigned int i, unsigned int n,
     103                 :            :                                          const unsigned long *args)
     104                 :            : {
     105                 :            :         BUG_ON(i + n > 6);
     106                 :            :         memcpy(&regs->bx + i, args, n * sizeof(args[0]));
     107                 :            : }
     108                 :            : 
     109                 :            : static inline int syscall_get_arch(struct task_struct *task)
     110                 :            : {
     111                 :            :         return AUDIT_ARCH_I386;
     112                 :            : }
     113                 :            : 
     114                 :            : #else    /* CONFIG_X86_64 */
     115                 :            : 
     116                 :          0 : static inline void syscall_get_arguments(struct task_struct *task,
     117                 :            :                                          struct pt_regs *regs,
     118                 :            :                                          unsigned long *args)
     119                 :            : {
     120                 :            : # ifdef CONFIG_IA32_EMULATION
     121   [ #  #  #  # ]:          0 :         if (task->thread_info.status & TS_COMPAT) {
     122                 :          0 :                 *args++ = regs->bx;
     123                 :          0 :                 *args++ = regs->cx;
     124                 :          0 :                 *args++ = regs->dx;
     125                 :          0 :                 *args++ = regs->si;
     126                 :          0 :                 *args++ = regs->di;
     127                 :          0 :                 *args   = regs->bp;
     128                 :            :         } else
     129                 :            : # endif
     130                 :            :         {
     131                 :          0 :                 *args++ = regs->di;
     132                 :          0 :                 *args++ = regs->si;
     133                 :          0 :                 *args++ = regs->dx;
     134                 :          0 :                 *args++ = regs->r10;
     135                 :          0 :                 *args++ = regs->r8;
     136                 :          0 :                 *args   = regs->r9;
     137                 :            :         }
     138                 :            : }
     139                 :            : 
     140                 :            : static inline void syscall_set_arguments(struct task_struct *task,
     141                 :            :                                          struct pt_regs *regs,
     142                 :            :                                          const unsigned long *args)
     143                 :            : {
     144                 :            : # ifdef CONFIG_IA32_EMULATION
     145                 :            :         if (task->thread_info.status & TS_COMPAT) {
     146                 :            :                 regs->bx = *args++;
     147                 :            :                 regs->cx = *args++;
     148                 :            :                 regs->dx = *args++;
     149                 :            :                 regs->si = *args++;
     150                 :            :                 regs->di = *args++;
     151                 :            :                 regs->bp = *args;
     152                 :            :         } else
     153                 :            : # endif
     154                 :            :         {
     155                 :            :                 regs->di = *args++;
     156                 :            :                 regs->si = *args++;
     157                 :            :                 regs->dx = *args++;
     158                 :            :                 regs->r10 = *args++;
     159                 :            :                 regs->r8 = *args++;
     160                 :            :                 regs->r9 = *args;
     161                 :            :         }
     162                 :            : }
     163                 :            : 
     164                 :          0 : static inline int syscall_get_arch(struct task_struct *task)
     165                 :            : {
     166                 :            :         /* x32 tasks should be considered AUDIT_ARCH_X86_64. */
     167                 :          0 :         return (IS_ENABLED(CONFIG_IA32_EMULATION) &&
     168                 :          0 :                 task->thread_info.status & TS_COMPAT)
     169   [ #  #  #  # ]:          0 :                 ? AUDIT_ARCH_I386 : AUDIT_ARCH_X86_64;
     170                 :            : }
     171                 :            : #endif  /* CONFIG_X86_32 */
     172                 :            : 
     173                 :            : #endif  /* _ASM_X86_SYSCALL_H */

Generated by: LCOV version 1.14