Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

alpha: propagate the calling convention changes down to csum_partial_copy.c helpers

get rid of set_fs() in csum_partial_copy_nocheck(), while we are at it -
just take the part of csum_and_copy_from_user() sans the access_ok() check
into a helper function and have csum_partial_copy_nocheck() call that.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro b7121395 c693cc46

+70 -89
+70 -89
arch/alpha/lib/csum_partial_copy.c
··· 39 39 #define insqh(x,y,z) \ 40 40 __asm__ __volatile__("insqh %1,%2,%0":"=r" (z):"r" (x),"r" (y)) 41 41 42 - 43 - #define __get_user_u(x,ptr) \ 42 + #define __get_word(insn,x,ptr) \ 44 43 ({ \ 45 44 long __guu_err; \ 46 45 __asm__ __volatile__( \ 47 - "1: ldq_u %0,%2\n" \ 46 + "1: "#insn" %0,%2\n" \ 48 47 "2:\n" \ 49 48 EXC(1b,2b,%0,%1) \ 50 49 : "=r"(x), "=r"(__guu_err) \ 51 50 : "m"(__m(ptr)), "1"(0)); \ 52 51 __guu_err; \ 53 52 }) 54 - 55 - #define __put_user_u(x,ptr) \ 56 - ({ \ 57 - long __puu_err; \ 58 - __asm__ __volatile__( \ 59 - "1: stq_u %2,%1\n" \ 60 - "2:\n" \ 61 - EXC(1b,2b,$31,%0) \ 62 - : "=r"(__puu_err) \ 63 - : "m"(__m(addr)), "rJ"(x), "0"(0)); \ 64 - __puu_err; \ 65 - }) 66 - 67 53 68 54 static inline unsigned short from64to16(unsigned long x) 69 55 { ··· 81 95 */ 82 96 static inline unsigned long 83 97 csum_partial_cfu_aligned(const unsigned long __user *src, unsigned long *dst, 84 - long len, unsigned long checksum, 85 - int *errp) 98 + long len) 86 99 { 100 + unsigned long checksum = ~0U; 87 101 unsigned long carry = 0; 88 - int err = 0; 89 102 90 103 while (len >= 0) { 91 104 unsigned long word; 92 - err |= __get_user(word, src); 105 + if (__get_word(ldq, word, src)) 106 + return 0; 93 107 checksum += carry; 94 108 src++; 95 109 checksum += word; ··· 102 116 checksum += carry; 103 117 if (len) { 104 118 unsigned long word, tmp; 105 - err |= __get_user(word, src); 119 + if (__get_word(ldq, word, src)) 120 + return 0; 106 121 tmp = *dst; 107 122 mskql(word, len, word); 108 123 checksum += word; ··· 112 125 *dst = word | tmp; 113 126 checksum += carry; 114 127 } 115 - if (err && errp) *errp = err; 116 128 return checksum; 117 129 } 118 130 ··· 123 137 csum_partial_cfu_dest_aligned(const unsigned long __user *src, 124 138 unsigned long *dst, 125 139 unsigned long soff, 126 - long len, unsigned long checksum, 127 - int *errp) 140 + long len) 128 141 { 129 142 unsigned long first; 130 143 unsigned long word, carry; 131 144 unsigned long lastsrc = 7+len+(unsigned long)src; 132 - int err = 0; 145 + unsigned long checksum = ~0U; 133 146 134 - err |= __get_user_u(first,src); 147 + if (__get_word(ldq_u, first,src)) 148 + return 0; 135 149 carry = 0; 136 150 while (len >= 0) { 137 151 unsigned long second; 138 152 139 - err |= __get_user_u(second, src+1); 153 + if (__get_word(ldq_u, second, src+1)) 154 + return 0; 140 155 extql(first, soff, word); 141 156 len -= 8; 142 157 src++; ··· 155 168 if (len) { 156 169 unsigned long tmp; 157 170 unsigned long second; 158 - err |= __get_user_u(second, lastsrc); 171 + if (__get_word(ldq_u, second, lastsrc)) 172 + return 0; 159 173 tmp = *dst; 160 174 extql(first, soff, word); 161 175 extqh(second, soff, first); ··· 168 180 *dst = word | tmp; 169 181 checksum += carry; 170 182 } 171 - if (err && errp) *errp = err; 172 183 return checksum; 173 184 } 174 185 ··· 178 191 csum_partial_cfu_src_aligned(const unsigned long __user *src, 179 192 unsigned long *dst, 180 193 unsigned long doff, 181 - long len, unsigned long checksum, 182 - unsigned long partial_dest, 183 - int *errp) 194 + long len, 195 + unsigned long partial_dest) 184 196 { 185 197 unsigned long carry = 0; 186 198 unsigned long word; 187 199 unsigned long second_dest; 188 - int err = 0; 200 + unsigned long checksum = ~0U; 189 201 190 202 mskql(partial_dest, doff, partial_dest); 191 203 while (len >= 0) { 192 - err |= __get_user(word, src); 204 + if (__get_word(ldq, word, src)) 205 + return 0; 193 206 len -= 8; 194 207 insql(word, doff, second_dest); 195 208 checksum += carry; ··· 203 216 len += 8; 204 217 if (len) { 205 218 checksum += carry; 206 - err |= __get_user(word, src); 219 + if (__get_word(ldq, word, src)) 220 + return 0; 207 221 mskql(word, len, word); 208 222 len -= 8; 209 223 checksum += word; ··· 225 237 stq_u(partial_dest | second_dest, dst); 226 238 out: 227 239 checksum += carry; 228 - if (err && errp) *errp = err; 229 240 return checksum; 230 241 } 231 242 ··· 236 249 csum_partial_cfu_unaligned(const unsigned long __user * src, 237 250 unsigned long * dst, 238 251 unsigned long soff, unsigned long doff, 239 - long len, unsigned long checksum, 240 - unsigned long partial_dest, 241 - int *errp) 252 + long len, unsigned long partial_dest) 242 253 { 243 254 unsigned long carry = 0; 244 255 unsigned long first; 245 256 unsigned long lastsrc; 246 - int err = 0; 257 + unsigned long checksum = ~0U; 247 258 248 - err |= __get_user_u(first, src); 259 + if (__get_word(ldq_u, first, src)) 260 + return 0; 249 261 lastsrc = 7+len+(unsigned long)src; 250 262 mskql(partial_dest, doff, partial_dest); 251 263 while (len >= 0) { 252 264 unsigned long second, word; 253 265 unsigned long second_dest; 254 266 255 - err |= __get_user_u(second, src+1); 267 + if (__get_word(ldq_u, second, src+1)) 268 + return 0; 256 269 extql(first, soff, word); 257 270 checksum += carry; 258 271 len -= 8; ··· 273 286 unsigned long second, word; 274 287 unsigned long second_dest; 275 288 276 - err |= __get_user_u(second, lastsrc); 289 + if (__get_word(ldq_u, second, lastsrc)) 290 + return 0; 277 291 extql(first, soff, word); 278 292 extqh(second, soff, first); 279 293 word |= first; ··· 295 307 unsigned long second, word; 296 308 unsigned long second_dest; 297 309 298 - err |= __get_user_u(second, lastsrc); 310 + if (__get_word(ldq_u, second, lastsrc)) 311 + return 0; 299 312 extql(first, soff, word); 300 313 extqh(second, soff, first); 301 314 word |= first; ··· 309 320 stq_u(partial_dest | word | second_dest, dst); 310 321 checksum += carry; 311 322 } 312 - if (err && errp) *errp = err; 313 323 return checksum; 324 + } 325 + 326 + static __wsum __csum_and_copy(const void __user *src, void *dst, int len) 327 + { 328 + unsigned long soff = 7 & (unsigned long) src; 329 + unsigned long doff = 7 & (unsigned long) dst; 330 + unsigned long checksum; 331 + 332 + if (!doff) { 333 + if (!soff) 334 + checksum = csum_partial_cfu_aligned( 335 + (const unsigned long __user *) src, 336 + (unsigned long *) dst, len-8); 337 + else 338 + checksum = csum_partial_cfu_dest_aligned( 339 + (const unsigned long __user *) src, 340 + (unsigned long *) dst, 341 + soff, len-8); 342 + } else { 343 + unsigned long partial_dest; 344 + ldq_u(partial_dest, dst); 345 + if (!soff) 346 + checksum = csum_partial_cfu_src_aligned( 347 + (const unsigned long __user *) src, 348 + (unsigned long *) dst, 349 + doff, len-8, partial_dest); 350 + else 351 + checksum = csum_partial_cfu_unaligned( 352 + (const unsigned long __user *) src, 353 + (unsigned long *) dst, 354 + soff, doff, len-8, partial_dest); 355 + } 356 + return (__force __wsum)from64to16 (checksum); 314 357 } 315 358 316 359 __wsum 317 360 csum_and_copy_from_user(const void __user *src, void *dst, int len) 318 361 { 319 - unsigned long checksum = ~0U; 320 - unsigned long soff = 7 & (unsigned long) src; 321 - unsigned long doff = 7 & (unsigned long) dst; 322 - int err = 0; 323 - 324 - if (len) { 325 - if (!access_ok(src, len)) 326 - return 0; 327 - if (!doff) { 328 - if (!soff) 329 - checksum = csum_partial_cfu_aligned( 330 - (const unsigned long __user *) src, 331 - (unsigned long *) dst, 332 - len-8, checksum, &err); 333 - else 334 - checksum = csum_partial_cfu_dest_aligned( 335 - (const unsigned long __user *) src, 336 - (unsigned long *) dst, 337 - soff, len-8, checksum, &err); 338 - } else { 339 - unsigned long partial_dest; 340 - ldq_u(partial_dest, dst); 341 - if (!soff) 342 - checksum = csum_partial_cfu_src_aligned( 343 - (const unsigned long __user *) src, 344 - (unsigned long *) dst, 345 - doff, len-8, checksum, 346 - partial_dest, &err); 347 - else 348 - checksum = csum_partial_cfu_unaligned( 349 - (const unsigned long __user *) src, 350 - (unsigned long *) dst, 351 - soff, doff, len-8, checksum, 352 - partial_dest, &err); 353 - } 354 - checksum = err ? 0 : from64to16 (checksum); 355 - } 356 - return (__force __wsum)checksum; 362 + if (!access_ok(src, len)) 363 + return 0; 364 + return __csum_and_copy(src, dst, len); 357 365 } 358 366 EXPORT_SYMBOL(csum_and_copy_from_user); 359 367 360 368 __wsum 361 369 csum_partial_copy_nocheck(const void *src, void *dst, int len) 362 370 { 363 - __wsum checksum; 364 - mm_segment_t oldfs = get_fs(); 365 - set_fs(KERNEL_DS); 366 - checksum = csum_and_copy_from_user((__force const void __user *)src, 371 + return __csum_and_copy((__force const void __user *)src, 367 372 dst, len); 368 - set_fs(oldfs); 369 - return checksum; 370 373 } 371 374 EXPORT_SYMBOL(csum_partial_copy_nocheck);