linux/arch/x86/include/asm/compat.h
<<
>>
Prefs
   1#ifndef _ASM_X86_COMPAT_H
   2#define _ASM_X86_COMPAT_H
   3
   4/*
   5 * Architecture specific compatibility types
   6 */
   7#include <linux/types.h>
   8#include <linux/sched.h>
   9#include <asm/processor.h>
  10#include <asm/user32.h>
  11#include <asm/unistd.h>
  12
  13#define COMPAT_USER_HZ          100
  14#define COMPAT_UTS_MACHINE      "i686\0\0"
  15
  16typedef u32             compat_size_t;
  17typedef s32             compat_ssize_t;
  18typedef s32             compat_time_t;
  19typedef s32             compat_clock_t;
  20typedef s32             compat_pid_t;
  21typedef u16             __compat_uid_t;
  22typedef u16             __compat_gid_t;
  23typedef u32             __compat_uid32_t;
  24typedef u32             __compat_gid32_t;
  25typedef u16             compat_mode_t;
  26typedef u32             compat_ino_t;
  27typedef u16             compat_dev_t;
  28typedef s32             compat_off_t;
  29typedef s64             compat_loff_t;
  30typedef u16             compat_nlink_t;
  31typedef u16             compat_ipc_pid_t;
  32typedef s32             compat_daddr_t;
  33typedef u32             compat_caddr_t;
  34typedef __kernel_fsid_t compat_fsid_t;
  35typedef s32             compat_timer_t;
  36typedef s32             compat_key_t;
  37
  38typedef s32             compat_int_t;
  39typedef s32             compat_long_t;
  40typedef s64 __attribute__((aligned(4))) compat_s64;
  41typedef u32             compat_uint_t;
  42typedef u32             compat_ulong_t;
  43typedef u64 __attribute__((aligned(4))) compat_u64;
  44typedef u32             compat_uptr_t;
  45
  46struct compat_timespec {
  47        compat_time_t   tv_sec;
  48        s32             tv_nsec;
  49};
  50
  51struct compat_timeval {
  52        compat_time_t   tv_sec;
  53        s32             tv_usec;
  54};
  55
  56struct compat_stat {
  57        compat_dev_t    st_dev;
  58        u16             __pad1;
  59        compat_ino_t    st_ino;
  60        compat_mode_t   st_mode;
  61        compat_nlink_t  st_nlink;
  62        __compat_uid_t  st_uid;
  63        __compat_gid_t  st_gid;
  64        compat_dev_t    st_rdev;
  65        u16             __pad2;
  66        u32             st_size;
  67        u32             st_blksize;
  68        u32             st_blocks;
  69        u32             st_atime;
  70        u32             st_atime_nsec;
  71        u32             st_mtime;
  72        u32             st_mtime_nsec;
  73        u32             st_ctime;
  74        u32             st_ctime_nsec;
  75        u32             __unused4;
  76        u32             __unused5;
  77};
  78
  79struct compat_flock {
  80        short           l_type;
  81        short           l_whence;
  82        compat_off_t    l_start;
  83        compat_off_t    l_len;
  84        compat_pid_t    l_pid;
  85};
  86
  87#define F_GETLK64       12      /*  using 'struct flock64' */
  88#define F_SETLK64       13
  89#define F_SETLKW64      14
  90
  91/*
  92 * IA32 uses 4 byte alignment for 64 bit quantities,
  93 * so we need to pack this structure.
  94 */
  95struct compat_flock64 {
  96        short           l_type;
  97        short           l_whence;
  98        compat_loff_t   l_start;
  99        compat_loff_t   l_len;
 100        compat_pid_t    l_pid;
 101} __attribute__((packed));
 102
 103struct compat_statfs {
 104        int             f_type;
 105        int             f_bsize;
 106        int             f_blocks;
 107        int             f_bfree;
 108        int             f_bavail;
 109        int             f_files;
 110        int             f_ffree;
 111        compat_fsid_t   f_fsid;
 112        int             f_namelen;      /* SunOS ignores this field. */
 113        int             f_frsize;
 114        int             f_flags;
 115        int             f_spare[4];
 116};
 117
 118#define COMPAT_RLIM_OLD_INFINITY        0x7fffffff
 119#define COMPAT_RLIM_INFINITY            0xffffffff
 120
 121typedef u32             compat_old_sigset_t;    /* at least 32 bits */
 122
 123#define _COMPAT_NSIG            64
 124#define _COMPAT_NSIG_BPW        32
 125
 126typedef u32               compat_sigset_word;
 127
 128typedef union compat_sigval {
 129        compat_int_t    sival_int;
 130        compat_uptr_t   sival_ptr;
 131} compat_sigval_t;
 132
 133typedef struct compat_siginfo {
 134        int si_signo;
 135        int si_errno;
 136        int si_code;
 137
 138        union {
 139                int _pad[128/sizeof(int) - 3];
 140
 141                /* kill() */
 142                struct {
 143                        unsigned int _pid;      /* sender's pid */
 144                        unsigned int _uid;      /* sender's uid */
 145                } _kill;
 146
 147                /* POSIX.1b timers */
 148                struct {
 149                        compat_timer_t _tid;    /* timer id */
 150                        int _overrun;           /* overrun count */
 151                        compat_sigval_t _sigval;        /* same as below */
 152                        int _sys_private;       /* not to be passed to user */
 153                        int _overrun_incr;      /* amount to add to overrun */
 154                } _timer;
 155
 156                /* POSIX.1b signals */
 157                struct {
 158                        unsigned int _pid;      /* sender's pid */
 159                        unsigned int _uid;      /* sender's uid */
 160                        compat_sigval_t _sigval;
 161                } _rt;
 162
 163                /* SIGCHLD */
 164                struct {
 165                        unsigned int _pid;      /* which child */
 166                        unsigned int _uid;      /* sender's uid */
 167                        int _status;            /* exit code */
 168                        compat_clock_t _utime;
 169                        compat_clock_t _stime;
 170                } _sigchld;
 171
 172                /* SIGCHLD (x32 version) */
 173                struct {
 174                        unsigned int _pid;      /* which child */
 175                        unsigned int _uid;      /* sender's uid */
 176                        int _status;            /* exit code */
 177                        compat_s64 _utime;
 178                        compat_s64 _stime;
 179                } _sigchld_x32;
 180
 181                /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
 182                struct {
 183                        unsigned int _addr;     /* faulting insn/memory ref. */
 184                } _sigfault;
 185
 186                /* SIGPOLL */
 187                struct {
 188                        int _band;      /* POLL_IN, POLL_OUT, POLL_MSG */
 189                        int _fd;
 190                } _sigpoll;
 191
 192                struct {
 193                        unsigned int _call_addr; /* calling insn */
 194                        int _syscall;   /* triggering system call number */
 195                        unsigned int _arch;     /* AUDIT_ARCH_* of syscall */
 196                } _sigsys;
 197        } _sifields;
 198} compat_siginfo_t;
 199
 200#define COMPAT_OFF_T_MAX        0x7fffffff
 201#define COMPAT_LOFF_T_MAX       0x7fffffffffffffffL
 202
 203struct compat_ipc64_perm {
 204        compat_key_t key;
 205        __compat_uid32_t uid;
 206        __compat_gid32_t gid;
 207        __compat_uid32_t cuid;
 208        __compat_gid32_t cgid;
 209        unsigned short mode;
 210        unsigned short __pad1;
 211        unsigned short seq;
 212        unsigned short __pad2;
 213        compat_ulong_t unused1;
 214        compat_ulong_t unused2;
 215};
 216
 217struct compat_semid64_ds {
 218        struct compat_ipc64_perm sem_perm;
 219        compat_time_t  sem_otime;
 220        compat_ulong_t __unused1;
 221        compat_time_t  sem_ctime;
 222        compat_ulong_t __unused2;
 223        compat_ulong_t sem_nsems;
 224        compat_ulong_t __unused3;
 225        compat_ulong_t __unused4;
 226};
 227
 228struct compat_msqid64_ds {
 229        struct compat_ipc64_perm msg_perm;
 230        compat_time_t  msg_stime;
 231        compat_ulong_t __unused1;
 232        compat_time_t  msg_rtime;
 233        compat_ulong_t __unused2;
 234        compat_time_t  msg_ctime;
 235        compat_ulong_t __unused3;
 236        compat_ulong_t msg_cbytes;
 237        compat_ulong_t msg_qnum;
 238        compat_ulong_t msg_qbytes;
 239        compat_pid_t   msg_lspid;
 240        compat_pid_t   msg_lrpid;
 241        compat_ulong_t __unused4;
 242        compat_ulong_t __unused5;
 243};
 244
 245struct compat_shmid64_ds {
 246        struct compat_ipc64_perm shm_perm;
 247        compat_size_t  shm_segsz;
 248        compat_time_t  shm_atime;
 249        compat_ulong_t __unused1;
 250        compat_time_t  shm_dtime;
 251        compat_ulong_t __unused2;
 252        compat_time_t  shm_ctime;
 253        compat_ulong_t __unused3;
 254        compat_pid_t   shm_cpid;
 255        compat_pid_t   shm_lpid;
 256        compat_ulong_t shm_nattch;
 257        compat_ulong_t __unused4;
 258        compat_ulong_t __unused5;
 259};
 260
 261/*
 262 * The type of struct elf_prstatus.pr_reg in compatible core dumps.
 263 */
 264#ifdef CONFIG_X86_X32_ABI
 265typedef struct user_regs_struct compat_elf_gregset_t;
 266
 267#define PR_REG_SIZE(S) (test_thread_flag(TIF_IA32) ? 68 : 216)
 268#define PRSTATUS_SIZE(S) (test_thread_flag(TIF_IA32) ? 144 : 296)
 269#define SET_PR_FPVALID(S,V) \
 270  do { *(int *) (((void *) &((S)->pr_reg)) + PR_REG_SIZE(0)) = (V); } \
 271  while (0)
 272
 273#define COMPAT_USE_64BIT_TIME \
 274        (!!(task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT))
 275#else
 276typedef struct user_regs_struct32 compat_elf_gregset_t;
 277#endif
 278
 279/*
 280 * A pointer passed in from user mode. This should not
 281 * be used for syscall parameters, just declare them
 282 * as pointers because the syscall entry code will have
 283 * appropriately converted them already.
 284 */
 285
 286static inline void __user *compat_ptr(compat_uptr_t uptr)
 287{
 288        return (void __user *)(unsigned long)uptr;
 289}
 290
 291static inline compat_uptr_t ptr_to_compat(void __user *uptr)
 292{
 293        return (u32)(unsigned long)uptr;
 294}
 295
 296static inline void __user *arch_compat_alloc_user_space(long len)
 297{
 298        compat_uptr_t sp;
 299
 300        if (test_thread_flag(TIF_IA32)) {
 301                sp = task_pt_regs(current)->sp;
 302        } else {
 303                /* -128 for the x32 ABI redzone */
 304                sp = this_cpu_read(old_rsp) - 128;
 305        }
 306
 307        return (void __user *)round_down(sp - len, 16);
 308}
 309
 310static inline bool is_x32_task(void)
 311{
 312#ifdef CONFIG_X86_X32_ABI
 313        if (task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT)
 314                return true;
 315#endif
 316        return false;
 317}
 318
 319static inline bool is_compat_task(void)
 320{
 321        return is_ia32_task() || is_x32_task();
 322}
 323
 324#endif /* _ASM_X86_COMPAT_H */
 325