~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/parisc/include/asm/futex.h

Version: ~ [ linux-5.5 ] ~ [ linux-5.4.15 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.98 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.167 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.211 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.211 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.81 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0 */
  2 #ifndef _ASM_PARISC_FUTEX_H
  3 #define _ASM_PARISC_FUTEX_H
  4 
  5 #ifdef __KERNEL__
  6 
  7 #include <linux/futex.h>
  8 #include <linux/uaccess.h>
  9 #include <asm/atomic.h>
 10 #include <asm/errno.h>
 11 
 12 /* The following has to match the LWS code in syscall.S.  We have
 13    sixteen four-word locks. */
 14 
 15 static inline void
 16 _futex_spin_lock_irqsave(u32 __user *uaddr, unsigned long int *flags)
 17 {
 18         extern u32 lws_lock_start[];
 19         long index = ((long)uaddr & 0xf0) >> 2;
 20         arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index];
 21         local_irq_save(*flags);
 22         arch_spin_lock(s);
 23 }
 24 
 25 static inline void
 26 _futex_spin_unlock_irqrestore(u32 __user *uaddr, unsigned long int *flags)
 27 {
 28         extern u32 lws_lock_start[];
 29         long index = ((long)uaddr & 0xf0) >> 2;
 30         arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index];
 31         arch_spin_unlock(s);
 32         local_irq_restore(*flags);
 33 }
 34 
 35 static inline int
 36 arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
 37 {
 38         unsigned long int flags;
 39         int oldval, ret;
 40         u32 tmp;
 41 
 42         _futex_spin_lock_irqsave(uaddr, &flags);
 43         pagefault_disable();
 44 
 45         ret = -EFAULT;
 46         if (unlikely(get_user(oldval, uaddr) != 0))
 47                 goto out_pagefault_enable;
 48 
 49         ret = 0;
 50         tmp = oldval;
 51 
 52         switch (op) {
 53         case FUTEX_OP_SET:
 54                 tmp = oparg;
 55                 break;
 56         case FUTEX_OP_ADD:
 57                 tmp += oparg;
 58                 break;
 59         case FUTEX_OP_OR:
 60                 tmp |= oparg;
 61                 break;
 62         case FUTEX_OP_ANDN:
 63                 tmp &= ~oparg;
 64                 break;
 65         case FUTEX_OP_XOR:
 66                 tmp ^= oparg;
 67                 break;
 68         default:
 69                 ret = -ENOSYS;
 70         }
 71 
 72         if (ret == 0 && unlikely(put_user(tmp, uaddr) != 0))
 73                 ret = -EFAULT;
 74 
 75 out_pagefault_enable:
 76         pagefault_enable();
 77         _futex_spin_unlock_irqrestore(uaddr, &flags);
 78 
 79         if (!ret)
 80                 *oval = oldval;
 81 
 82         return ret;
 83 }
 84 
 85 static inline int
 86 futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 87                               u32 oldval, u32 newval)
 88 {
 89         u32 val;
 90         unsigned long flags;
 91 
 92         /* futex.c wants to do a cmpxchg_inatomic on kernel NULL, which is
 93          * our gateway page, and causes no end of trouble...
 94          */
 95         if (uaccess_kernel() && !uaddr)
 96                 return -EFAULT;
 97 
 98         if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
 99                 return -EFAULT;
100 
101         /* HPPA has no cmpxchg in hardware and therefore the
102          * best we can do here is use an array of locks. The
103          * lock selected is based on a hash of the userspace
104          * address. This should scale to a couple of CPUs.
105          */
106 
107         _futex_spin_lock_irqsave(uaddr, &flags);
108         if (unlikely(get_user(val, uaddr) != 0)) {
109                 _futex_spin_unlock_irqrestore(uaddr, &flags);
110                 return -EFAULT;
111         }
112 
113         if (val == oldval && unlikely(put_user(newval, uaddr) != 0)) {
114                 _futex_spin_unlock_irqrestore(uaddr, &flags);
115                 return -EFAULT;
116         }
117 
118         *uval = val;
119         _futex_spin_unlock_irqrestore(uaddr, &flags);
120 
121         return 0;
122 }
123 
124 #endif /*__KERNEL__*/
125 #endif /*_ASM_PARISC_FUTEX_H*/
126 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp