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

TOMOYO Linux Cross Reference
Linux/arch/s390/lib/uaccess.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  *  Standard user space access functions based on mvcp/mvcs and doing
  4  *  interesting things in the secondary space mode.
  5  *
  6  *    Copyright IBM Corp. 2006,2014
  7  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
  8  *               Gerald Schaefer (gerald.schaefer@de.ibm.com)
  9  */
 10 
 11 #include <linux/uaccess.h>
 12 #include <linux/export.h>
 13 #include <linux/mm.h>
 14 #include <asm/asm-extable.h>
 15 #include <asm/ctlreg.h>
 16 
 17 #ifdef CONFIG_DEBUG_ENTRY
 18 void debug_user_asce(int exit)
 19 {
 20         struct ctlreg cr1, cr7;
 21 
 22         local_ctl_store(1, &cr1);
 23         local_ctl_store(7, &cr7);
 24         if (cr1.val == get_lowcore()->kernel_asce.val && cr7.val == get_lowcore()->user_asce.val)
 25                 return;
 26         panic("incorrect ASCE on kernel %s\n"
 27               "cr1:    %016lx cr7:  %016lx\n"
 28               "kernel: %016lx user: %016lx\n",
 29               exit ? "exit" : "entry", cr1.val, cr7.val,
 30               get_lowcore()->kernel_asce.val, get_lowcore()->user_asce.val);
 31 }
 32 #endif /*CONFIG_DEBUG_ENTRY */
 33 
 34 static unsigned long raw_copy_from_user_key(void *to, const void __user *from,
 35                                             unsigned long size, unsigned long key)
 36 {
 37         unsigned long rem;
 38         union oac spec = {
 39                 .oac2.key = key,
 40                 .oac2.as = PSW_BITS_AS_SECONDARY,
 41                 .oac2.k = 1,
 42                 .oac2.a = 1,
 43         };
 44 
 45         asm volatile(
 46                 "       lr      0,%[spec]\n"
 47                 "0:     mvcos   0(%[to]),0(%[from]),%[size]\n"
 48                 "1:     jz      5f\n"
 49                 "       algr    %[size],%[val]\n"
 50                 "       slgr    %[from],%[val]\n"
 51                 "       slgr    %[to],%[val]\n"
 52                 "       j       0b\n"
 53                 "2:     la      %[rem],4095(%[from])\n" /* rem = from + 4095 */
 54                 "       nr      %[rem],%[val]\n"        /* rem = (from + 4095) & -4096 */
 55                 "       slgr    %[rem],%[from]\n"
 56                 "       clgr    %[size],%[rem]\n"       /* copy crosses next page boundary? */
 57                 "       jnh     6f\n"
 58                 "3:     mvcos   0(%[to]),0(%[from]),%[rem]\n"
 59                 "4:     slgr    %[size],%[rem]\n"
 60                 "       j       6f\n"
 61                 "5:     slgr    %[size],%[size]\n"
 62                 "6:\n"
 63                 EX_TABLE(0b, 2b)
 64                 EX_TABLE(1b, 2b)
 65                 EX_TABLE(3b, 6b)
 66                 EX_TABLE(4b, 6b)
 67                 : [size] "+&a" (size), [from] "+&a" (from), [to] "+&a" (to), [rem] "=&a" (rem)
 68                 : [val] "a" (-4096UL), [spec] "d" (spec.val)
 69                 : "cc", "memory", "");
 70         return size;
 71 }
 72 
 73 unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n)
 74 {
 75         return raw_copy_from_user_key(to, from, n, 0);
 76 }
 77 EXPORT_SYMBOL(raw_copy_from_user);
 78 
 79 unsigned long _copy_from_user_key(void *to, const void __user *from,
 80                                   unsigned long n, unsigned long key)
 81 {
 82         unsigned long res = n;
 83 
 84         might_fault();
 85         if (!should_fail_usercopy()) {
 86                 instrument_copy_from_user_before(to, from, n);
 87                 res = raw_copy_from_user_key(to, from, n, key);
 88                 instrument_copy_from_user_after(to, from, n, res);
 89         }
 90         if (unlikely(res))
 91                 memset(to + (n - res), 0, res);
 92         return res;
 93 }
 94 EXPORT_SYMBOL(_copy_from_user_key);
 95 
 96 static unsigned long raw_copy_to_user_key(void __user *to, const void *from,
 97                                           unsigned long size, unsigned long key)
 98 {
 99         unsigned long rem;
100         union oac spec = {
101                 .oac1.key = key,
102                 .oac1.as = PSW_BITS_AS_SECONDARY,
103                 .oac1.k = 1,
104                 .oac1.a = 1,
105         };
106 
107         asm volatile(
108                 "       lr      0,%[spec]\n"
109                 "0:     mvcos   0(%[to]),0(%[from]),%[size]\n"
110                 "1:     jz      5f\n"
111                 "       algr    %[size],%[val]\n"
112                 "       slgr    %[to],%[val]\n"
113                 "       slgr    %[from],%[val]\n"
114                 "       j       0b\n"
115                 "2:     la      %[rem],4095(%[to])\n"   /* rem = to + 4095 */
116                 "       nr      %[rem],%[val]\n"        /* rem = (to + 4095) & -4096 */
117                 "       slgr    %[rem],%[to]\n"
118                 "       clgr    %[size],%[rem]\n"       /* copy crosses next page boundary? */
119                 "       jnh     6f\n"
120                 "3:     mvcos   0(%[to]),0(%[from]),%[rem]\n"
121                 "4:     slgr    %[size],%[rem]\n"
122                 "       j       6f\n"
123                 "5:     slgr    %[size],%[size]\n"
124                 "6:\n"
125                 EX_TABLE(0b, 2b)
126                 EX_TABLE(1b, 2b)
127                 EX_TABLE(3b, 6b)
128                 EX_TABLE(4b, 6b)
129                 : [size] "+&a" (size), [to] "+&a" (to), [from] "+&a" (from), [rem] "=&a" (rem)
130                 : [val] "a" (-4096UL), [spec] "d" (spec.val)
131                 : "cc", "memory", "");
132         return size;
133 }
134 
135 unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n)
136 {
137         return raw_copy_to_user_key(to, from, n, 0);
138 }
139 EXPORT_SYMBOL(raw_copy_to_user);
140 
141 unsigned long _copy_to_user_key(void __user *to, const void *from,
142                                 unsigned long n, unsigned long key)
143 {
144         might_fault();
145         if (should_fail_usercopy())
146                 return n;
147         instrument_copy_to_user(to, from, n);
148         return raw_copy_to_user_key(to, from, n, key);
149 }
150 EXPORT_SYMBOL(_copy_to_user_key);
151 
152 unsigned long __clear_user(void __user *to, unsigned long size)
153 {
154         unsigned long rem;
155         union oac spec = {
156                 .oac1.as = PSW_BITS_AS_SECONDARY,
157                 .oac1.a = 1,
158         };
159 
160         asm volatile(
161                 "       lr      0,%[spec]\n"
162                 "0:     mvcos   0(%[to]),0(%[zeropg]),%[size]\n"
163                 "1:     jz      5f\n"
164                 "       algr    %[size],%[val]\n"
165                 "       slgr    %[to],%[val]\n"
166                 "       j       0b\n"
167                 "2:     la      %[rem],4095(%[to])\n"   /* rem = to + 4095 */
168                 "       nr      %[rem],%[val]\n"        /* rem = (to + 4095) & -4096 */
169                 "       slgr    %[rem],%[to]\n"
170                 "       clgr    %[size],%[rem]\n"       /* copy crosses next page boundary? */
171                 "       jnh     6f\n"
172                 "3:     mvcos   0(%[to]),0(%[zeropg]),%[rem]\n"
173                 "4:     slgr    %[size],%[rem]\n"
174                 "       j       6f\n"
175                 "5:     slgr    %[size],%[size]\n"
176                 "6:\n"
177                 EX_TABLE(0b, 2b)
178                 EX_TABLE(1b, 2b)
179                 EX_TABLE(3b, 6b)
180                 EX_TABLE(4b, 6b)
181                 : [size] "+&a" (size), [to] "+&a" (to), [rem] "=&a" (rem)
182                 : [val] "a" (-4096UL), [zeropg] "a" (empty_zero_page), [spec] "d" (spec.val)
183                 : "cc", "memory", "");
184         return size;
185 }
186 EXPORT_SYMBOL(__clear_user);
187 

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

kernel.org | git.kernel.org | LWN.net | Project Home | 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.

sflogo.php