Merge tag 'm68knommu-for-v5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu

Pull m68knommu updates from Greg Ungerer:
"A collection of fixes for 5.10:

- switch to using asm-generic uaccess code

- fix sparse warnings in signal code

- fix compilation of ColdFire MMC support

- support sysrq in ColdFire serial driver"

* tag 'm68knommu-for-v5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu:
serial: mcf: add sysrq capability
m68knommu: include SDHC support only when hardware has it
m68knommu: fix sparse warnings in signal code
m68knommu: switch to using asm-generic/uaccess.h

+403 -560
+1
arch/m68k/Kconfig
··· 31 31 select NO_DMA if !MMU && !COLDFIRE 32 32 select OLD_SIGACTION 33 33 select OLD_SIGSUSPEND3 34 + select UACCESS_MEMCPY if !MMU 34 35 select VIRT_TO_BUS 35 36 36 37 config CPU_BIG_ENDIAN
+3 -3
arch/m68k/coldfire/device.c
··· 554 554 }; 555 555 #endif /* IS_ENABLED(CONFIG_MCF_EDMA) */ 556 556 557 - #if IS_ENABLED(CONFIG_MMC) 557 + #ifdef MCFSDHC_BASE 558 558 static struct mcf_esdhc_platform_data mcf_esdhc_data = { 559 559 .max_bus_width = 4, 560 560 .cd_type = ESDHC_CD_NONE, ··· 579 579 .resource = mcf_esdhc_resources, 580 580 .dev.platform_data = &mcf_esdhc_data, 581 581 }; 582 - #endif /* IS_ENABLED(CONFIG_MMC) */ 582 + #endif /* MCFSDHC_BASE */ 583 583 584 584 static struct platform_device *mcf_devices[] __initdata = { 585 585 &mcf_uart, ··· 613 613 #if IS_ENABLED(CONFIG_MCF_EDMA) 614 614 &mcf_edma, 615 615 #endif 616 - #if IS_ENABLED(CONFIG_MMC) 616 + #ifdef MCFSDHC_BASE 617 617 &mcf_esdhc, 618 618 #endif 619 619 };
+395 -5
arch/m68k/include/asm/uaccess.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 - #ifdef __uClinux__ 3 - #include <asm/uaccess_no.h> 4 - #else 5 - #include <asm/uaccess_mm.h> 6 - #endif 2 + #ifndef __M68K_UACCESS_H 3 + #define __M68K_UACCESS_H 4 + 5 + #ifdef CONFIG_MMU 6 + 7 + /* 8 + * User space memory access functions 9 + */ 10 + #include <linux/compiler.h> 11 + #include <linux/types.h> 12 + #include <asm/segment.h> 7 13 #include <asm/extable.h> 14 + 15 + /* We let the MMU do all checking */ 16 + static inline int access_ok(const void __user *addr, 17 + unsigned long size) 18 + { 19 + return 1; 20 + } 21 + 22 + /* 23 + * Not all varients of the 68k family support the notion of address spaces. 24 + * The traditional 680x0 parts do, and they use the sfc/dfc registers and 25 + * the "moves" instruction to access user space from kernel space. Other 26 + * family members like ColdFire don't support this, and only have a single 27 + * address space, and use the usual "move" instruction for user space access. 28 + * 29 + * Outside of this difference the user space access functions are the same. 30 + * So lets keep the code simple and just define in what we need to use. 31 + */ 32 + #ifdef CONFIG_CPU_HAS_ADDRESS_SPACES 33 + #define MOVES "moves" 34 + #else 35 + #define MOVES "move" 36 + #endif 37 + 38 + extern int __put_user_bad(void); 39 + extern int __get_user_bad(void); 40 + 41 + #define __put_user_asm(res, x, ptr, bwl, reg, err) \ 42 + asm volatile ("\n" \ 43 + "1: "MOVES"."#bwl" %2,%1\n" \ 44 + "2:\n" \ 45 + " .section .fixup,\"ax\"\n" \ 46 + " .even\n" \ 47 + "10: moveq.l %3,%0\n" \ 48 + " jra 2b\n" \ 49 + " .previous\n" \ 50 + "\n" \ 51 + " .section __ex_table,\"a\"\n" \ 52 + " .align 4\n" \ 53 + " .long 1b,10b\n" \ 54 + " .long 2b,10b\n" \ 55 + " .previous" \ 56 + : "+d" (res), "=m" (*(ptr)) \ 57 + : #reg (x), "i" (err)) 58 + 59 + /* 60 + * These are the main single-value transfer routines. They automatically 61 + * use the right size if we just have the right pointer type. 62 + */ 63 + 64 + #define __put_user(x, ptr) \ 65 + ({ \ 66 + typeof(*(ptr)) __pu_val = (x); \ 67 + int __pu_err = 0; \ 68 + __chk_user_ptr(ptr); \ 69 + switch (sizeof (*(ptr))) { \ 70 + case 1: \ 71 + __put_user_asm(__pu_err, __pu_val, ptr, b, d, -EFAULT); \ 72 + break; \ 73 + case 2: \ 74 + __put_user_asm(__pu_err, __pu_val, ptr, w, r, -EFAULT); \ 75 + break; \ 76 + case 4: \ 77 + __put_user_asm(__pu_err, __pu_val, ptr, l, r, -EFAULT); \ 78 + break; \ 79 + case 8: \ 80 + { \ 81 + const void __user *__pu_ptr = (ptr); \ 82 + asm volatile ("\n" \ 83 + "1: "MOVES".l %2,(%1)+\n" \ 84 + "2: "MOVES".l %R2,(%1)\n" \ 85 + "3:\n" \ 86 + " .section .fixup,\"ax\"\n" \ 87 + " .even\n" \ 88 + "10: movel %3,%0\n" \ 89 + " jra 3b\n" \ 90 + " .previous\n" \ 91 + "\n" \ 92 + " .section __ex_table,\"a\"\n" \ 93 + " .align 4\n" \ 94 + " .long 1b,10b\n" \ 95 + " .long 2b,10b\n" \ 96 + " .long 3b,10b\n" \ 97 + " .previous" \ 98 + : "+d" (__pu_err), "+a" (__pu_ptr) \ 99 + : "r" (__pu_val), "i" (-EFAULT) \ 100 + : "memory"); \ 101 + break; \ 102 + } \ 103 + default: \ 104 + __pu_err = __put_user_bad(); \ 105 + break; \ 106 + } \ 107 + __pu_err; \ 108 + }) 109 + #define put_user(x, ptr) __put_user(x, ptr) 110 + 111 + 112 + #define __get_user_asm(res, x, ptr, type, bwl, reg, err) ({ \ 113 + type __gu_val; \ 114 + asm volatile ("\n" \ 115 + "1: "MOVES"."#bwl" %2,%1\n" \ 116 + "2:\n" \ 117 + " .section .fixup,\"ax\"\n" \ 118 + " .even\n" \ 119 + "10: move.l %3,%0\n" \ 120 + " sub.l %1,%1\n" \ 121 + " jra 2b\n" \ 122 + " .previous\n" \ 123 + "\n" \ 124 + " .section __ex_table,\"a\"\n" \ 125 + " .align 4\n" \ 126 + " .long 1b,10b\n" \ 127 + " .previous" \ 128 + : "+d" (res), "=&" #reg (__gu_val) \ 129 + : "m" (*(ptr)), "i" (err)); \ 130 + (x) = (__force typeof(*(ptr)))(__force unsigned long)__gu_val; \ 131 + }) 132 + 133 + #define __get_user(x, ptr) \ 134 + ({ \ 135 + int __gu_err = 0; \ 136 + __chk_user_ptr(ptr); \ 137 + switch (sizeof(*(ptr))) { \ 138 + case 1: \ 139 + __get_user_asm(__gu_err, x, ptr, u8, b, d, -EFAULT); \ 140 + break; \ 141 + case 2: \ 142 + __get_user_asm(__gu_err, x, ptr, u16, w, r, -EFAULT); \ 143 + break; \ 144 + case 4: \ 145 + __get_user_asm(__gu_err, x, ptr, u32, l, r, -EFAULT); \ 146 + break; \ 147 + case 8: { \ 148 + const void __user *__gu_ptr = (ptr); \ 149 + union { \ 150 + u64 l; \ 151 + __typeof__(*(ptr)) t; \ 152 + } __gu_val; \ 153 + asm volatile ("\n" \ 154 + "1: "MOVES".l (%2)+,%1\n" \ 155 + "2: "MOVES".l (%2),%R1\n" \ 156 + "3:\n" \ 157 + " .section .fixup,\"ax\"\n" \ 158 + " .even\n" \ 159 + "10: move.l %3,%0\n" \ 160 + " sub.l %1,%1\n" \ 161 + " sub.l %R1,%R1\n" \ 162 + " jra 3b\n" \ 163 + " .previous\n" \ 164 + "\n" \ 165 + " .section __ex_table,\"a\"\n" \ 166 + " .align 4\n" \ 167 + " .long 1b,10b\n" \ 168 + " .long 2b,10b\n" \ 169 + " .previous" \ 170 + : "+d" (__gu_err), "=&r" (__gu_val.l), \ 171 + "+a" (__gu_ptr) \ 172 + : "i" (-EFAULT) \ 173 + : "memory"); \ 174 + (x) = __gu_val.t; \ 175 + break; \ 176 + } \ 177 + default: \ 178 + __gu_err = __get_user_bad(); \ 179 + break; \ 180 + } \ 181 + __gu_err; \ 182 + }) 183 + #define get_user(x, ptr) __get_user(x, ptr) 184 + 185 + unsigned long __generic_copy_from_user(void *to, const void __user *from, unsigned long n); 186 + unsigned long __generic_copy_to_user(void __user *to, const void *from, unsigned long n); 187 + 188 + #define __suffix0 189 + #define __suffix1 b 190 + #define __suffix2 w 191 + #define __suffix4 l 192 + 193 + #define ____constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, s1, s2, s3)\ 194 + asm volatile ("\n" \ 195 + "1: "MOVES"."#s1" (%2)+,%3\n" \ 196 + " move."#s1" %3,(%1)+\n" \ 197 + " .ifnc \""#s2"\",\"\"\n" \ 198 + "2: "MOVES"."#s2" (%2)+,%3\n" \ 199 + " move."#s2" %3,(%1)+\n" \ 200 + " .ifnc \""#s3"\",\"\"\n" \ 201 + "3: "MOVES"."#s3" (%2)+,%3\n" \ 202 + " move."#s3" %3,(%1)+\n" \ 203 + " .endif\n" \ 204 + " .endif\n" \ 205 + "4:\n" \ 206 + " .section __ex_table,\"a\"\n" \ 207 + " .align 4\n" \ 208 + " .long 1b,10f\n" \ 209 + " .ifnc \""#s2"\",\"\"\n" \ 210 + " .long 2b,20f\n" \ 211 + " .ifnc \""#s3"\",\"\"\n" \ 212 + " .long 3b,30f\n" \ 213 + " .endif\n" \ 214 + " .endif\n" \ 215 + " .previous\n" \ 216 + "\n" \ 217 + " .section .fixup,\"ax\"\n" \ 218 + " .even\n" \ 219 + "10: addq.l #"#n1",%0\n" \ 220 + " .ifnc \""#s2"\",\"\"\n" \ 221 + "20: addq.l #"#n2",%0\n" \ 222 + " .ifnc \""#s3"\",\"\"\n" \ 223 + "30: addq.l #"#n3",%0\n" \ 224 + " .endif\n" \ 225 + " .endif\n" \ 226 + " jra 4b\n" \ 227 + " .previous\n" \ 228 + : "+d" (res), "+&a" (to), "+a" (from), "=&d" (tmp) \ 229 + : : "memory") 230 + 231 + #define ___constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, s1, s2, s3)\ 232 + ____constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, s1, s2, s3) 233 + #define __constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3) \ 234 + ___constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, \ 235 + __suffix##n1, __suffix##n2, __suffix##n3) 236 + 237 + static __always_inline unsigned long 238 + __constant_copy_from_user(void *to, const void __user *from, unsigned long n) 239 + { 240 + unsigned long res = 0, tmp; 241 + 242 + switch (n) { 243 + case 1: 244 + __constant_copy_from_user_asm(res, to, from, tmp, 1, 0, 0); 245 + break; 246 + case 2: 247 + __constant_copy_from_user_asm(res, to, from, tmp, 2, 0, 0); 248 + break; 249 + case 3: 250 + __constant_copy_from_user_asm(res, to, from, tmp, 2, 1, 0); 251 + break; 252 + case 4: 253 + __constant_copy_from_user_asm(res, to, from, tmp, 4, 0, 0); 254 + break; 255 + case 5: 256 + __constant_copy_from_user_asm(res, to, from, tmp, 4, 1, 0); 257 + break; 258 + case 6: 259 + __constant_copy_from_user_asm(res, to, from, tmp, 4, 2, 0); 260 + break; 261 + case 7: 262 + __constant_copy_from_user_asm(res, to, from, tmp, 4, 2, 1); 263 + break; 264 + case 8: 265 + __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 0); 266 + break; 267 + case 9: 268 + __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 1); 269 + break; 270 + case 10: 271 + __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 2); 272 + break; 273 + case 12: 274 + __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 4); 275 + break; 276 + default: 277 + /* we limit the inlined version to 3 moves */ 278 + return __generic_copy_from_user(to, from, n); 279 + } 280 + 281 + return res; 282 + } 283 + 284 + #define __constant_copy_to_user_asm(res, to, from, tmp, n, s1, s2, s3) \ 285 + asm volatile ("\n" \ 286 + " move."#s1" (%2)+,%3\n" \ 287 + "11: "MOVES"."#s1" %3,(%1)+\n" \ 288 + "12: move."#s2" (%2)+,%3\n" \ 289 + "21: "MOVES"."#s2" %3,(%1)+\n" \ 290 + "22:\n" \ 291 + " .ifnc \""#s3"\",\"\"\n" \ 292 + " move."#s3" (%2)+,%3\n" \ 293 + "31: "MOVES"."#s3" %3,(%1)+\n" \ 294 + "32:\n" \ 295 + " .endif\n" \ 296 + "4:\n" \ 297 + "\n" \ 298 + " .section __ex_table,\"a\"\n" \ 299 + " .align 4\n" \ 300 + " .long 11b,5f\n" \ 301 + " .long 12b,5f\n" \ 302 + " .long 21b,5f\n" \ 303 + " .long 22b,5f\n" \ 304 + " .ifnc \""#s3"\",\"\"\n" \ 305 + " .long 31b,5f\n" \ 306 + " .long 32b,5f\n" \ 307 + " .endif\n" \ 308 + " .previous\n" \ 309 + "\n" \ 310 + " .section .fixup,\"ax\"\n" \ 311 + " .even\n" \ 312 + "5: moveq.l #"#n",%0\n" \ 313 + " jra 4b\n" \ 314 + " .previous\n" \ 315 + : "+d" (res), "+a" (to), "+a" (from), "=&d" (tmp) \ 316 + : : "memory") 317 + 318 + static __always_inline unsigned long 319 + __constant_copy_to_user(void __user *to, const void *from, unsigned long n) 320 + { 321 + unsigned long res = 0, tmp; 322 + 323 + switch (n) { 324 + case 1: 325 + __put_user_asm(res, *(u8 *)from, (u8 __user *)to, b, d, 1); 326 + break; 327 + case 2: 328 + __put_user_asm(res, *(u16 *)from, (u16 __user *)to, w, r, 2); 329 + break; 330 + case 3: 331 + __constant_copy_to_user_asm(res, to, from, tmp, 3, w, b,); 332 + break; 333 + case 4: 334 + __put_user_asm(res, *(u32 *)from, (u32 __user *)to, l, r, 4); 335 + break; 336 + case 5: 337 + __constant_copy_to_user_asm(res, to, from, tmp, 5, l, b,); 338 + break; 339 + case 6: 340 + __constant_copy_to_user_asm(res, to, from, tmp, 6, l, w,); 341 + break; 342 + case 7: 343 + __constant_copy_to_user_asm(res, to, from, tmp, 7, l, w, b); 344 + break; 345 + case 8: 346 + __constant_copy_to_user_asm(res, to, from, tmp, 8, l, l,); 347 + break; 348 + case 9: 349 + __constant_copy_to_user_asm(res, to, from, tmp, 9, l, l, b); 350 + break; 351 + case 10: 352 + __constant_copy_to_user_asm(res, to, from, tmp, 10, l, l, w); 353 + break; 354 + case 12: 355 + __constant_copy_to_user_asm(res, to, from, tmp, 12, l, l, l); 356 + break; 357 + default: 358 + /* limit the inlined version to 3 moves */ 359 + return __generic_copy_to_user(to, from, n); 360 + } 361 + 362 + return res; 363 + } 364 + 365 + static inline unsigned long 366 + raw_copy_from_user(void *to, const void __user *from, unsigned long n) 367 + { 368 + if (__builtin_constant_p(n)) 369 + return __constant_copy_from_user(to, from, n); 370 + return __generic_copy_from_user(to, from, n); 371 + } 372 + 373 + static inline unsigned long 374 + raw_copy_to_user(void __user *to, const void *from, unsigned long n) 375 + { 376 + if (__builtin_constant_p(n)) 377 + return __constant_copy_to_user(to, from, n); 378 + return __generic_copy_to_user(to, from, n); 379 + } 380 + #define INLINE_COPY_FROM_USER 381 + #define INLINE_COPY_TO_USER 382 + 383 + #define user_addr_max() \ 384 + (uaccess_kernel() ? ~0UL : TASK_SIZE) 385 + 386 + extern long strncpy_from_user(char *dst, const char __user *src, long count); 387 + extern __must_check long strnlen_user(const char __user *str, long n); 388 + 389 + unsigned long __clear_user(void __user *to, unsigned long n); 390 + 391 + #define clear_user __clear_user 392 + 393 + #else /* !CONFIG_MMU */ 394 + #include <asm-generic/uaccess.h> 395 + #endif 396 + 397 + #endif /* _M68K_UACCESS_H */
-390
arch/m68k/include/asm/uaccess_mm.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - #ifndef __M68K_UACCESS_H 3 - #define __M68K_UACCESS_H 4 - 5 - /* 6 - * User space memory access functions 7 - */ 8 - #include <linux/compiler.h> 9 - #include <linux/types.h> 10 - #include <asm/segment.h> 11 - 12 - /* We let the MMU do all checking */ 13 - static inline int access_ok(const void __user *addr, 14 - unsigned long size) 15 - { 16 - return 1; 17 - } 18 - 19 - /* 20 - * Not all varients of the 68k family support the notion of address spaces. 21 - * The traditional 680x0 parts do, and they use the sfc/dfc registers and 22 - * the "moves" instruction to access user space from kernel space. Other 23 - * family members like ColdFire don't support this, and only have a single 24 - * address space, and use the usual "move" instruction for user space access. 25 - * 26 - * Outside of this difference the user space access functions are the same. 27 - * So lets keep the code simple and just define in what we need to use. 28 - */ 29 - #ifdef CONFIG_CPU_HAS_ADDRESS_SPACES 30 - #define MOVES "moves" 31 - #else 32 - #define MOVES "move" 33 - #endif 34 - 35 - extern int __put_user_bad(void); 36 - extern int __get_user_bad(void); 37 - 38 - #define __put_user_asm(res, x, ptr, bwl, reg, err) \ 39 - asm volatile ("\n" \ 40 - "1: "MOVES"."#bwl" %2,%1\n" \ 41 - "2:\n" \ 42 - " .section .fixup,\"ax\"\n" \ 43 - " .even\n" \ 44 - "10: moveq.l %3,%0\n" \ 45 - " jra 2b\n" \ 46 - " .previous\n" \ 47 - "\n" \ 48 - " .section __ex_table,\"a\"\n" \ 49 - " .align 4\n" \ 50 - " .long 1b,10b\n" \ 51 - " .long 2b,10b\n" \ 52 - " .previous" \ 53 - : "+d" (res), "=m" (*(ptr)) \ 54 - : #reg (x), "i" (err)) 55 - 56 - /* 57 - * These are the main single-value transfer routines. They automatically 58 - * use the right size if we just have the right pointer type. 59 - */ 60 - 61 - #define __put_user(x, ptr) \ 62 - ({ \ 63 - typeof(*(ptr)) __pu_val = (x); \ 64 - int __pu_err = 0; \ 65 - __chk_user_ptr(ptr); \ 66 - switch (sizeof (*(ptr))) { \ 67 - case 1: \ 68 - __put_user_asm(__pu_err, __pu_val, ptr, b, d, -EFAULT); \ 69 - break; \ 70 - case 2: \ 71 - __put_user_asm(__pu_err, __pu_val, ptr, w, r, -EFAULT); \ 72 - break; \ 73 - case 4: \ 74 - __put_user_asm(__pu_err, __pu_val, ptr, l, r, -EFAULT); \ 75 - break; \ 76 - case 8: \ 77 - { \ 78 - const void __user *__pu_ptr = (ptr); \ 79 - asm volatile ("\n" \ 80 - "1: "MOVES".l %2,(%1)+\n" \ 81 - "2: "MOVES".l %R2,(%1)\n" \ 82 - "3:\n" \ 83 - " .section .fixup,\"ax\"\n" \ 84 - " .even\n" \ 85 - "10: movel %3,%0\n" \ 86 - " jra 3b\n" \ 87 - " .previous\n" \ 88 - "\n" \ 89 - " .section __ex_table,\"a\"\n" \ 90 - " .align 4\n" \ 91 - " .long 1b,10b\n" \ 92 - " .long 2b,10b\n" \ 93 - " .long 3b,10b\n" \ 94 - " .previous" \ 95 - : "+d" (__pu_err), "+a" (__pu_ptr) \ 96 - : "r" (__pu_val), "i" (-EFAULT) \ 97 - : "memory"); \ 98 - break; \ 99 - } \ 100 - default: \ 101 - __pu_err = __put_user_bad(); \ 102 - break; \ 103 - } \ 104 - __pu_err; \ 105 - }) 106 - #define put_user(x, ptr) __put_user(x, ptr) 107 - 108 - 109 - #define __get_user_asm(res, x, ptr, type, bwl, reg, err) ({ \ 110 - type __gu_val; \ 111 - asm volatile ("\n" \ 112 - "1: "MOVES"."#bwl" %2,%1\n" \ 113 - "2:\n" \ 114 - " .section .fixup,\"ax\"\n" \ 115 - " .even\n" \ 116 - "10: move.l %3,%0\n" \ 117 - " sub.l %1,%1\n" \ 118 - " jra 2b\n" \ 119 - " .previous\n" \ 120 - "\n" \ 121 - " .section __ex_table,\"a\"\n" \ 122 - " .align 4\n" \ 123 - " .long 1b,10b\n" \ 124 - " .previous" \ 125 - : "+d" (res), "=&" #reg (__gu_val) \ 126 - : "m" (*(ptr)), "i" (err)); \ 127 - (x) = (__force typeof(*(ptr)))(__force unsigned long)__gu_val; \ 128 - }) 129 - 130 - #define __get_user(x, ptr) \ 131 - ({ \ 132 - int __gu_err = 0; \ 133 - __chk_user_ptr(ptr); \ 134 - switch (sizeof(*(ptr))) { \ 135 - case 1: \ 136 - __get_user_asm(__gu_err, x, ptr, u8, b, d, -EFAULT); \ 137 - break; \ 138 - case 2: \ 139 - __get_user_asm(__gu_err, x, ptr, u16, w, r, -EFAULT); \ 140 - break; \ 141 - case 4: \ 142 - __get_user_asm(__gu_err, x, ptr, u32, l, r, -EFAULT); \ 143 - break; \ 144 - case 8: { \ 145 - const void __user *__gu_ptr = (ptr); \ 146 - union { \ 147 - u64 l; \ 148 - __typeof__(*(ptr)) t; \ 149 - } __gu_val; \ 150 - asm volatile ("\n" \ 151 - "1: "MOVES".l (%2)+,%1\n" \ 152 - "2: "MOVES".l (%2),%R1\n" \ 153 - "3:\n" \ 154 - " .section .fixup,\"ax\"\n" \ 155 - " .even\n" \ 156 - "10: move.l %3,%0\n" \ 157 - " sub.l %1,%1\n" \ 158 - " sub.l %R1,%R1\n" \ 159 - " jra 3b\n" \ 160 - " .previous\n" \ 161 - "\n" \ 162 - " .section __ex_table,\"a\"\n" \ 163 - " .align 4\n" \ 164 - " .long 1b,10b\n" \ 165 - " .long 2b,10b\n" \ 166 - " .previous" \ 167 - : "+d" (__gu_err), "=&r" (__gu_val.l), \ 168 - "+a" (__gu_ptr) \ 169 - : "i" (-EFAULT) \ 170 - : "memory"); \ 171 - (x) = __gu_val.t; \ 172 - break; \ 173 - } \ 174 - default: \ 175 - __gu_err = __get_user_bad(); \ 176 - break; \ 177 - } \ 178 - __gu_err; \ 179 - }) 180 - #define get_user(x, ptr) __get_user(x, ptr) 181 - 182 - unsigned long __generic_copy_from_user(void *to, const void __user *from, unsigned long n); 183 - unsigned long __generic_copy_to_user(void __user *to, const void *from, unsigned long n); 184 - 185 - #define __suffix0 186 - #define __suffix1 b 187 - #define __suffix2 w 188 - #define __suffix4 l 189 - 190 - #define ____constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, s1, s2, s3)\ 191 - asm volatile ("\n" \ 192 - "1: "MOVES"."#s1" (%2)+,%3\n" \ 193 - " move."#s1" %3,(%1)+\n" \ 194 - " .ifnc \""#s2"\",\"\"\n" \ 195 - "2: "MOVES"."#s2" (%2)+,%3\n" \ 196 - " move."#s2" %3,(%1)+\n" \ 197 - " .ifnc \""#s3"\",\"\"\n" \ 198 - "3: "MOVES"."#s3" (%2)+,%3\n" \ 199 - " move."#s3" %3,(%1)+\n" \ 200 - " .endif\n" \ 201 - " .endif\n" \ 202 - "4:\n" \ 203 - " .section __ex_table,\"a\"\n" \ 204 - " .align 4\n" \ 205 - " .long 1b,10f\n" \ 206 - " .ifnc \""#s2"\",\"\"\n" \ 207 - " .long 2b,20f\n" \ 208 - " .ifnc \""#s3"\",\"\"\n" \ 209 - " .long 3b,30f\n" \ 210 - " .endif\n" \ 211 - " .endif\n" \ 212 - " .previous\n" \ 213 - "\n" \ 214 - " .section .fixup,\"ax\"\n" \ 215 - " .even\n" \ 216 - "10: addq.l #"#n1",%0\n" \ 217 - " .ifnc \""#s2"\",\"\"\n" \ 218 - "20: addq.l #"#n2",%0\n" \ 219 - " .ifnc \""#s3"\",\"\"\n" \ 220 - "30: addq.l #"#n3",%0\n" \ 221 - " .endif\n" \ 222 - " .endif\n" \ 223 - " jra 4b\n" \ 224 - " .previous\n" \ 225 - : "+d" (res), "+&a" (to), "+a" (from), "=&d" (tmp) \ 226 - : : "memory") 227 - 228 - #define ___constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, s1, s2, s3)\ 229 - ____constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, s1, s2, s3) 230 - #define __constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3) \ 231 - ___constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, \ 232 - __suffix##n1, __suffix##n2, __suffix##n3) 233 - 234 - static __always_inline unsigned long 235 - __constant_copy_from_user(void *to, const void __user *from, unsigned long n) 236 - { 237 - unsigned long res = 0, tmp; 238 - 239 - switch (n) { 240 - case 1: 241 - __constant_copy_from_user_asm(res, to, from, tmp, 1, 0, 0); 242 - break; 243 - case 2: 244 - __constant_copy_from_user_asm(res, to, from, tmp, 2, 0, 0); 245 - break; 246 - case 3: 247 - __constant_copy_from_user_asm(res, to, from, tmp, 2, 1, 0); 248 - break; 249 - case 4: 250 - __constant_copy_from_user_asm(res, to, from, tmp, 4, 0, 0); 251 - break; 252 - case 5: 253 - __constant_copy_from_user_asm(res, to, from, tmp, 4, 1, 0); 254 - break; 255 - case 6: 256 - __constant_copy_from_user_asm(res, to, from, tmp, 4, 2, 0); 257 - break; 258 - case 7: 259 - __constant_copy_from_user_asm(res, to, from, tmp, 4, 2, 1); 260 - break; 261 - case 8: 262 - __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 0); 263 - break; 264 - case 9: 265 - __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 1); 266 - break; 267 - case 10: 268 - __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 2); 269 - break; 270 - case 12: 271 - __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 4); 272 - break; 273 - default: 274 - /* we limit the inlined version to 3 moves */ 275 - return __generic_copy_from_user(to, from, n); 276 - } 277 - 278 - return res; 279 - } 280 - 281 - #define __constant_copy_to_user_asm(res, to, from, tmp, n, s1, s2, s3) \ 282 - asm volatile ("\n" \ 283 - " move."#s1" (%2)+,%3\n" \ 284 - "11: "MOVES"."#s1" %3,(%1)+\n" \ 285 - "12: move."#s2" (%2)+,%3\n" \ 286 - "21: "MOVES"."#s2" %3,(%1)+\n" \ 287 - "22:\n" \ 288 - " .ifnc \""#s3"\",\"\"\n" \ 289 - " move."#s3" (%2)+,%3\n" \ 290 - "31: "MOVES"."#s3" %3,(%1)+\n" \ 291 - "32:\n" \ 292 - " .endif\n" \ 293 - "4:\n" \ 294 - "\n" \ 295 - " .section __ex_table,\"a\"\n" \ 296 - " .align 4\n" \ 297 - " .long 11b,5f\n" \ 298 - " .long 12b,5f\n" \ 299 - " .long 21b,5f\n" \ 300 - " .long 22b,5f\n" \ 301 - " .ifnc \""#s3"\",\"\"\n" \ 302 - " .long 31b,5f\n" \ 303 - " .long 32b,5f\n" \ 304 - " .endif\n" \ 305 - " .previous\n" \ 306 - "\n" \ 307 - " .section .fixup,\"ax\"\n" \ 308 - " .even\n" \ 309 - "5: moveq.l #"#n",%0\n" \ 310 - " jra 4b\n" \ 311 - " .previous\n" \ 312 - : "+d" (res), "+a" (to), "+a" (from), "=&d" (tmp) \ 313 - : : "memory") 314 - 315 - static __always_inline unsigned long 316 - __constant_copy_to_user(void __user *to, const void *from, unsigned long n) 317 - { 318 - unsigned long res = 0, tmp; 319 - 320 - switch (n) { 321 - case 1: 322 - __put_user_asm(res, *(u8 *)from, (u8 __user *)to, b, d, 1); 323 - break; 324 - case 2: 325 - __put_user_asm(res, *(u16 *)from, (u16 __user *)to, w, r, 2); 326 - break; 327 - case 3: 328 - __constant_copy_to_user_asm(res, to, from, tmp, 3, w, b,); 329 - break; 330 - case 4: 331 - __put_user_asm(res, *(u32 *)from, (u32 __user *)to, l, r, 4); 332 - break; 333 - case 5: 334 - __constant_copy_to_user_asm(res, to, from, tmp, 5, l, b,); 335 - break; 336 - case 6: 337 - __constant_copy_to_user_asm(res, to, from, tmp, 6, l, w,); 338 - break; 339 - case 7: 340 - __constant_copy_to_user_asm(res, to, from, tmp, 7, l, w, b); 341 - break; 342 - case 8: 343 - __constant_copy_to_user_asm(res, to, from, tmp, 8, l, l,); 344 - break; 345 - case 9: 346 - __constant_copy_to_user_asm(res, to, from, tmp, 9, l, l, b); 347 - break; 348 - case 10: 349 - __constant_copy_to_user_asm(res, to, from, tmp, 10, l, l, w); 350 - break; 351 - case 12: 352 - __constant_copy_to_user_asm(res, to, from, tmp, 12, l, l, l); 353 - break; 354 - default: 355 - /* limit the inlined version to 3 moves */ 356 - return __generic_copy_to_user(to, from, n); 357 - } 358 - 359 - return res; 360 - } 361 - 362 - static inline unsigned long 363 - raw_copy_from_user(void *to, const void __user *from, unsigned long n) 364 - { 365 - if (__builtin_constant_p(n)) 366 - return __constant_copy_from_user(to, from, n); 367 - return __generic_copy_from_user(to, from, n); 368 - } 369 - 370 - static inline unsigned long 371 - raw_copy_to_user(void __user *to, const void *from, unsigned long n) 372 - { 373 - if (__builtin_constant_p(n)) 374 - return __constant_copy_to_user(to, from, n); 375 - return __generic_copy_to_user(to, from, n); 376 - } 377 - #define INLINE_COPY_FROM_USER 378 - #define INLINE_COPY_TO_USER 379 - 380 - #define user_addr_max() \ 381 - (uaccess_kernel() ? ~0UL : TASK_SIZE) 382 - 383 - extern long strncpy_from_user(char *dst, const char __user *src, long count); 384 - extern __must_check long strnlen_user(const char __user *str, long n); 385 - 386 - unsigned long __clear_user(void __user *to, unsigned long n); 387 - 388 - #define clear_user __clear_user 389 - 390 - #endif /* _M68K_UACCESS_H */
-160
arch/m68k/include/asm/uaccess_no.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - #ifndef __M68KNOMMU_UACCESS_H 3 - #define __M68KNOMMU_UACCESS_H 4 - 5 - /* 6 - * User space memory access functions 7 - */ 8 - #include <linux/string.h> 9 - 10 - #include <asm/segment.h> 11 - 12 - #define access_ok(addr,size) _access_ok((unsigned long)(addr),(size)) 13 - 14 - /* 15 - * It is not enough to just have access_ok check for a real RAM address. 16 - * This would disallow the case of code/ro-data running XIP in flash/rom. 17 - * Ideally we would check the possible flash ranges too, but that is 18 - * currently not so easy. 19 - */ 20 - static inline int _access_ok(unsigned long addr, unsigned long size) 21 - { 22 - return 1; 23 - } 24 - 25 - /* 26 - * These are the main single-value transfer routines. They automatically 27 - * use the right size if we just have the right pointer type. 28 - */ 29 - 30 - #define put_user(x, ptr) \ 31 - ({ \ 32 - int __pu_err = 0; \ 33 - typeof(*(ptr)) __pu_val = (x); \ 34 - switch (sizeof (*(ptr))) { \ 35 - case 1: \ 36 - __put_user_asm(__pu_err, __pu_val, ptr, b); \ 37 - break; \ 38 - case 2: \ 39 - __put_user_asm(__pu_err, __pu_val, ptr, w); \ 40 - break; \ 41 - case 4: \ 42 - __put_user_asm(__pu_err, __pu_val, ptr, l); \ 43 - break; \ 44 - case 8: \ 45 - memcpy((void __force *)ptr, &__pu_val, sizeof(*(ptr))); \ 46 - break; \ 47 - default: \ 48 - __pu_err = __put_user_bad(); \ 49 - break; \ 50 - } \ 51 - __pu_err; \ 52 - }) 53 - #define __put_user(x, ptr) put_user(x, ptr) 54 - 55 - extern int __put_user_bad(void); 56 - 57 - /* 58 - * Tell gcc we read from memory instead of writing: this is because 59 - * we do not write to any memory gcc knows about, so there are no 60 - * aliasing issues. 61 - */ 62 - 63 - #define __ptr(x) ((unsigned long __user *)(x)) 64 - 65 - #define __put_user_asm(err,x,ptr,bwl) \ 66 - __asm__ ("move" #bwl " %0,%1" \ 67 - : /* no outputs */ \ 68 - :"d" (x),"m" (*__ptr(ptr)) : "memory") 69 - 70 - #define get_user(x, ptr) \ 71 - ({ \ 72 - int __gu_err = 0; \ 73 - switch (sizeof(*(ptr))) { \ 74 - case 1: \ 75 - __get_user_asm(__gu_err, x, ptr, b, "=d"); \ 76 - break; \ 77 - case 2: \ 78 - __get_user_asm(__gu_err, x, ptr, w, "=r"); \ 79 - break; \ 80 - case 4: \ 81 - __get_user_asm(__gu_err, x, ptr, l, "=r"); \ 82 - break; \ 83 - case 8: { \ 84 - union { \ 85 - u64 l; \ 86 - __typeof__(*(ptr)) t; \ 87 - } __gu_val; \ 88 - memcpy(&__gu_val.l, (const void __force *)ptr, sizeof(__gu_val.l)); \ 89 - (x) = __gu_val.t; \ 90 - break; \ 91 - } \ 92 - default: \ 93 - __gu_err = __get_user_bad(); \ 94 - break; \ 95 - } \ 96 - __gu_err; \ 97 - }) 98 - #define __get_user(x, ptr) get_user(x, ptr) 99 - 100 - extern int __get_user_bad(void); 101 - 102 - #define __get_user_asm(err,x,ptr,bwl,reg) \ 103 - __asm__ ("move" #bwl " %1,%0" \ 104 - : "=d" (x) \ 105 - : "m" (*__ptr(ptr))) 106 - 107 - static inline unsigned long 108 - raw_copy_from_user(void *to, const void __user *from, unsigned long n) 109 - { 110 - memcpy(to, (__force const void *)from, n); 111 - return 0; 112 - } 113 - 114 - static inline unsigned long 115 - raw_copy_to_user(void __user *to, const void *from, unsigned long n) 116 - { 117 - memcpy((__force void *)to, from, n); 118 - return 0; 119 - } 120 - #define INLINE_COPY_FROM_USER 121 - #define INLINE_COPY_TO_USER 122 - 123 - /* 124 - * Copy a null terminated string from userspace. 125 - */ 126 - 127 - static inline long 128 - strncpy_from_user(char *dst, const char *src, long count) 129 - { 130 - char *tmp; 131 - strncpy(dst, src, count); 132 - for (tmp = dst; *tmp && count > 0; tmp++, count--) 133 - ; 134 - return(tmp - dst); /* DAVIDM should we count a NUL ? check getname */ 135 - } 136 - 137 - /* 138 - * Return the size of a string (including the ending 0) 139 - * 140 - * Return 0 on exception, a value greater than N if too long 141 - */ 142 - static inline long strnlen_user(const char *src, long n) 143 - { 144 - return(strlen(src) + 1); /* DAVIDM make safer */ 145 - } 146 - 147 - /* 148 - * Zero Userspace 149 - */ 150 - 151 - static inline unsigned long 152 - __clear_user(void *to, unsigned long n) 153 - { 154 - memset(to, 0, n); 155 - return 0; 156 - } 157 - 158 - #define clear_user(to,n) __clear_user(to,n) 159 - 160 - #endif /* _M68KNOMMU_UACCESS_H */
+4 -2
arch/m68k/kernel/signal.c
··· 920 920 err |= __put_user(0x70004e40 + (__NR_sigreturn << 16), 921 921 (long __user *)(frame->retcode)); 922 922 #else 923 - err |= __put_user((void *) ret_from_user_signal, &frame->pretcode); 923 + err |= __put_user((long) ret_from_user_signal, 924 + (long __user *) &frame->pretcode); 924 925 #endif 925 926 926 927 if (err) ··· 1005 1004 err |= __put_user(0x4e40, (short __user *)(frame->retcode + 4)); 1006 1005 #endif 1007 1006 #else 1008 - err |= __put_user((void *) ret_from_user_rt_signal, &frame->pretcode); 1007 + err |= __put_user((long) ret_from_user_rt_signal, 1008 + (long __user *) &frame->pretcode); 1009 1009 #endif /* CONFIG_MMU */ 1010 1010 1011 1011 if (err)