uaccess.h (2b1333b80885b896807ffb6ccf4bc21d29aa65e0) | uaccess.h (4953fc3d3270b7466a3b334838b76308c75f7751) |
---|---|
1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * Based on arch/arm/include/asm/uaccess.h 4 * 5 * Copyright (C) 2012 ARM Ltd. 6 */ 7#ifndef __ASM_UACCESS_H 8#define __ASM_UACCESS_H --- 218 unchanged lines hidden (view full) --- 227/* 228 * The "__xxx" versions of the user access functions do not verify the address 229 * space - it must have been done previously with a separate "access_ok()" 230 * call. 231 * 232 * The "__xxx_error" versions set the third argument to -EFAULT if an error 233 * occurs, and leave it unchanged on success. 234 */ | 1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * Based on arch/arm/include/asm/uaccess.h 4 * 5 * Copyright (C) 2012 ARM Ltd. 6 */ 7#ifndef __ASM_UACCESS_H 8#define __ASM_UACCESS_H --- 218 unchanged lines hidden (view full) --- 227/* 228 * The "__xxx" versions of the user access functions do not verify the address 229 * space - it must have been done previously with a separate "access_ok()" 230 * call. 231 * 232 * The "__xxx_error" versions set the third argument to -EFAULT if an error 233 * occurs, and leave it unchanged on success. 234 */ |
235#define __get_mem_asm(load, reg, x, addr, err) \ | 235#define __get_mem_asm(load, reg, x, addr, err, type) \ |
236 asm volatile( \ 237 "1: " load " " reg "1, [%2]\n" \ 238 "2:\n" \ | 236 asm volatile( \ 237 "1: " load " " reg "1, [%2]\n" \ 238 "2:\n" \ |
239 _ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 2b, %w0, %w1) \ | 239 _ASM_EXTABLE_##type##ACCESS_ERR_ZERO(1b, 2b, %w0, %w1) \ |
240 : "+r" (err), "=&r" (x) \ 241 : "r" (addr)) 242 | 240 : "+r" (err), "=&r" (x) \ 241 : "r" (addr)) 242 |
243#define __raw_get_mem(ldr, x, ptr, err) \ 244do { \ 245 unsigned long __gu_val; \ 246 switch (sizeof(*(ptr))) { \ 247 case 1: \ 248 __get_mem_asm(ldr "b", "%w", __gu_val, (ptr), (err)); \ 249 break; \ 250 case 2: \ 251 __get_mem_asm(ldr "h", "%w", __gu_val, (ptr), (err)); \ 252 break; \ 253 case 4: \ 254 __get_mem_asm(ldr, "%w", __gu_val, (ptr), (err)); \ 255 break; \ 256 case 8: \ 257 __get_mem_asm(ldr, "%x", __gu_val, (ptr), (err)); \ 258 break; \ 259 default: \ 260 BUILD_BUG(); \ 261 } \ 262 (x) = (__force __typeof__(*(ptr)))__gu_val; \ | 243#define __raw_get_mem(ldr, x, ptr, err, type) \ 244do { \ 245 unsigned long __gu_val; \ 246 switch (sizeof(*(ptr))) { \ 247 case 1: \ 248 __get_mem_asm(ldr "b", "%w", __gu_val, (ptr), (err), type); \ 249 break; \ 250 case 2: \ 251 __get_mem_asm(ldr "h", "%w", __gu_val, (ptr), (err), type); \ 252 break; \ 253 case 4: \ 254 __get_mem_asm(ldr, "%w", __gu_val, (ptr), (err), type); \ 255 break; \ 256 case 8: \ 257 __get_mem_asm(ldr, "%x", __gu_val, (ptr), (err), type); \ 258 break; \ 259 default: \ 260 BUILD_BUG(); \ 261 } \ 262 (x) = (__force __typeof__(*(ptr)))__gu_val; \ |
263} while (0) 264 265/* 266 * We must not call into the scheduler between uaccess_ttbr0_enable() and 267 * uaccess_ttbr0_disable(). As `x` and `ptr` could contain blocking functions, 268 * we must evaluate these outside of the critical section. 269 */ 270#define __raw_get_user(x, ptr, err) \ 271do { \ 272 __typeof__(*(ptr)) __user *__rgu_ptr = (ptr); \ 273 __typeof__(x) __rgu_val; \ 274 __chk_user_ptr(ptr); \ 275 \ 276 uaccess_ttbr0_enable(); \ | 263} while (0) 264 265/* 266 * We must not call into the scheduler between uaccess_ttbr0_enable() and 267 * uaccess_ttbr0_disable(). As `x` and `ptr` could contain blocking functions, 268 * we must evaluate these outside of the critical section. 269 */ 270#define __raw_get_user(x, ptr, err) \ 271do { \ 272 __typeof__(*(ptr)) __user *__rgu_ptr = (ptr); \ 273 __typeof__(x) __rgu_val; \ 274 __chk_user_ptr(ptr); \ 275 \ 276 uaccess_ttbr0_enable(); \ |
277 __raw_get_mem("ldtr", __rgu_val, __rgu_ptr, err); \ | 277 __raw_get_mem("ldtr", __rgu_val, __rgu_ptr, err, U); \ |
278 uaccess_ttbr0_disable(); \ 279 \ 280 (x) = __rgu_val; \ 281} while (0) 282 283#define __get_user_error(x, ptr, err) \ 284do { \ 285 __typeof__(*(ptr)) __user *__p = (ptr); \ --- 23 unchanged lines hidden (view full) --- 309#define __get_kernel_nofault(dst, src, type, err_label) \ 310do { \ 311 __typeof__(dst) __gkn_dst = (dst); \ 312 __typeof__(src) __gkn_src = (src); \ 313 int __gkn_err = 0; \ 314 \ 315 __uaccess_enable_tco_async(); \ 316 __raw_get_mem("ldr", *((type *)(__gkn_dst)), \ | 278 uaccess_ttbr0_disable(); \ 279 \ 280 (x) = __rgu_val; \ 281} while (0) 282 283#define __get_user_error(x, ptr, err) \ 284do { \ 285 __typeof__(*(ptr)) __user *__p = (ptr); \ --- 23 unchanged lines hidden (view full) --- 309#define __get_kernel_nofault(dst, src, type, err_label) \ 310do { \ 311 __typeof__(dst) __gkn_dst = (dst); \ 312 __typeof__(src) __gkn_src = (src); \ 313 int __gkn_err = 0; \ 314 \ 315 __uaccess_enable_tco_async(); \ 316 __raw_get_mem("ldr", *((type *)(__gkn_dst)), \ |
317 (__force type *)(__gkn_src), __gkn_err); \ | 317 (__force type *)(__gkn_src), __gkn_err, K); \ |
318 __uaccess_disable_tco_async(); \ 319 \ 320 if (unlikely(__gkn_err)) \ 321 goto err_label; \ 322} while (0) 323 | 318 __uaccess_disable_tco_async(); \ 319 \ 320 if (unlikely(__gkn_err)) \ 321 goto err_label; \ 322} while (0) 323 |
324#define __put_mem_asm(store, reg, x, addr, err) \ | 324#define __put_mem_asm(store, reg, x, addr, err, type) \ |
325 asm volatile( \ 326 "1: " store " " reg "1, [%2]\n" \ 327 "2:\n" \ | 325 asm volatile( \ 326 "1: " store " " reg "1, [%2]\n" \ 327 "2:\n" \ |
328 _ASM_EXTABLE_UACCESS_ERR(1b, 2b, %w0) \ | 328 _ASM_EXTABLE_##type##ACCESS_ERR(1b, 2b, %w0) \ |
329 : "+r" (err) \ 330 : "r" (x), "r" (addr)) 331 | 329 : "+r" (err) \ 330 : "r" (x), "r" (addr)) 331 |
332#define __raw_put_mem(str, x, ptr, err) \ 333do { \ 334 __typeof__(*(ptr)) __pu_val = (x); \ 335 switch (sizeof(*(ptr))) { \ 336 case 1: \ 337 __put_mem_asm(str "b", "%w", __pu_val, (ptr), (err)); \ 338 break; \ 339 case 2: \ 340 __put_mem_asm(str "h", "%w", __pu_val, (ptr), (err)); \ 341 break; \ 342 case 4: \ 343 __put_mem_asm(str, "%w", __pu_val, (ptr), (err)); \ 344 break; \ 345 case 8: \ 346 __put_mem_asm(str, "%x", __pu_val, (ptr), (err)); \ 347 break; \ 348 default: \ 349 BUILD_BUG(); \ 350 } \ | 332#define __raw_put_mem(str, x, ptr, err, type) \ 333do { \ 334 __typeof__(*(ptr)) __pu_val = (x); \ 335 switch (sizeof(*(ptr))) { \ 336 case 1: \ 337 __put_mem_asm(str "b", "%w", __pu_val, (ptr), (err), type); \ 338 break; \ 339 case 2: \ 340 __put_mem_asm(str "h", "%w", __pu_val, (ptr), (err), type); \ 341 break; \ 342 case 4: \ 343 __put_mem_asm(str, "%w", __pu_val, (ptr), (err), type); \ 344 break; \ 345 case 8: \ 346 __put_mem_asm(str, "%x", __pu_val, (ptr), (err), type); \ 347 break; \ 348 default: \ 349 BUILD_BUG(); \ 350 } \ |
351} while (0) 352 353/* 354 * We must not call into the scheduler between uaccess_ttbr0_enable() and 355 * uaccess_ttbr0_disable(). As `x` and `ptr` could contain blocking functions, 356 * we must evaluate these outside of the critical section. 357 */ 358#define __raw_put_user(x, ptr, err) \ 359do { \ 360 __typeof__(*(ptr)) __user *__rpu_ptr = (ptr); \ 361 __typeof__(*(ptr)) __rpu_val = (x); \ 362 __chk_user_ptr(__rpu_ptr); \ 363 \ 364 uaccess_ttbr0_enable(); \ | 351} while (0) 352 353/* 354 * We must not call into the scheduler between uaccess_ttbr0_enable() and 355 * uaccess_ttbr0_disable(). As `x` and `ptr` could contain blocking functions, 356 * we must evaluate these outside of the critical section. 357 */ 358#define __raw_put_user(x, ptr, err) \ 359do { \ 360 __typeof__(*(ptr)) __user *__rpu_ptr = (ptr); \ 361 __typeof__(*(ptr)) __rpu_val = (x); \ 362 __chk_user_ptr(__rpu_ptr); \ 363 \ 364 uaccess_ttbr0_enable(); \ |
365 __raw_put_mem("sttr", __rpu_val, __rpu_ptr, err); \ | 365 __raw_put_mem("sttr", __rpu_val, __rpu_ptr, err, U); \ |
366 uaccess_ttbr0_disable(); \ 367} while (0) 368 369#define __put_user_error(x, ptr, err) \ 370do { \ 371 __typeof__(*(ptr)) __user *__p = (ptr); \ 372 might_fault(); \ 373 if (access_ok(__p, sizeof(*__p))) { \ --- 21 unchanged lines hidden (view full) --- 395#define __put_kernel_nofault(dst, src, type, err_label) \ 396do { \ 397 __typeof__(dst) __pkn_dst = (dst); \ 398 __typeof__(src) __pkn_src = (src); \ 399 int __pkn_err = 0; \ 400 \ 401 __uaccess_enable_tco_async(); \ 402 __raw_put_mem("str", *((type *)(__pkn_src)), \ | 366 uaccess_ttbr0_disable(); \ 367} while (0) 368 369#define __put_user_error(x, ptr, err) \ 370do { \ 371 __typeof__(*(ptr)) __user *__p = (ptr); \ 372 might_fault(); \ 373 if (access_ok(__p, sizeof(*__p))) { \ --- 21 unchanged lines hidden (view full) --- 395#define __put_kernel_nofault(dst, src, type, err_label) \ 396do { \ 397 __typeof__(dst) __pkn_dst = (dst); \ 398 __typeof__(src) __pkn_src = (src); \ 399 int __pkn_err = 0; \ 400 \ 401 __uaccess_enable_tco_async(); \ 402 __raw_put_mem("str", *((type *)(__pkn_src)), \ |
403 (__force type *)(__pkn_dst), __pkn_err); \ | 403 (__force type *)(__pkn_dst), __pkn_err, K); \ |
404 __uaccess_disable_tco_async(); \ 405 \ 406 if (unlikely(__pkn_err)) \ 407 goto err_label; \ 408} while(0) 409 410extern unsigned long __must_check __arch_copy_from_user(void *to, const void __user *from, unsigned long n); 411#define raw_copy_from_user(to, from, n) \ --- 67 unchanged lines hidden --- | 404 __uaccess_disable_tco_async(); \ 405 \ 406 if (unlikely(__pkn_err)) \ 407 goto err_label; \ 408} while(0) 409 410extern unsigned long __must_check __arch_copy_from_user(void *to, const void __user *from, unsigned long n); 411#define raw_copy_from_user(to, from, n) \ --- 67 unchanged lines hidden --- |