Trying to build the kernel with CONFIG_INFINIBAND_USER_ACCESS enabled fails ERROR: "__get_user_unknown" [drivers/infiniband/core/ib_uverbs.ko] undefined! with on SH since the kernel misses a 64-bit implementation of get_user(). Implement the missing 64-bit get_user() as __get_user_u64(), matching the already existing __put_user_u64() which implements the 64-bit put_user().
Unified · Split
| @@ -26,6 +26,9 @@ do { \ · 25 unmodified lines | |||
| 26 | case 4: \ | 26 | case 4: \ |
| 27 | __get_user_asm(x, ptr, retval, "l"); \ | 27 | __get_user_asm(x, ptr, retval, "l"); \ |
| 28 | break; \ | 28 | break; \ |
| 29 | case 8: \ | ||
| 30 | __get_user_u64(x, ptr, retval); \ | ||
| 31 | break; \ | ||
| 29 | default: \ | 32 | default: \ |
| 30 | __get_user_unknown(); \ | 33 | __get_user_unknown(); \ |
| 31 | break; \ | 34 | break; \ |
| @@ -66,6 +69,56 @@ do { \ · 34 unmodified lines | |||
| 66 | 69 | ||
| 67 | extern void __get_user_unknown(void); | 70 | extern void __get_user_unknown(void); |
| 68 | 71 | ||
| 72 | #if defined(CONFIG_CPU_LITTLE_ENDIAN) | ||
| 73 | #define __get_user_u64(x, addr, err) \ | ||
| 74 | ({ \ | ||
| 75 | __asm__ __volatile__( \ | ||
| 76 | "1:\n\t" \ | ||
| 77 | "mov.l %2,%R1\n\t" \ | ||
| 78 | "mov.l %T2,%S1\n\t" \ | ||
| 79 | "2:\n" \ | ||
| 80 | ".section .fixup,\"ax\"\n" \ | ||
| 81 | "3:\n\t" \ | ||
| 82 | "mov #0,%R1\n\t" \ | ||
| 83 | "mov #0,%S1\n\t" \ | ||
| 84 | "mov.l 4f, %0\n\t" \ | ||
| 85 | "jmp @%0\n\t" \ | ||
| 86 | " mov %3, %0\n\t" \ | ||
| 87 | ".balign 4\n" \ | ||
| 88 | "4: .long 2b\n\t" \ | ||
| 89 | ".previous\n" \ | ||
| 90 | ".section __ex_table,\"a\"\n\t" \ | ||
| 91 | ".long 1b, 3b\n\t" \ | ||
| 92 | ".long 1b + 2, 3b\n\t" \ | ||
| 93 | ".previous" \ | ||
| 94 | :"=&r" (err), "=&r" (x) \ | ||
| 95 | :"m" (__m(addr)), "i" (-EFAULT), "0" (err)); }) | ||
| 96 | #else | ||
| 97 | #define __get_user_u64(x, addr, err) \ | ||
| 98 | ({ \ | ||
| 99 | __asm__ __volatile__( \ | ||
| 100 | "1:\n\t" \ | ||
| 101 | "mov.l %2,%S1\n\t" \ | ||
| 102 | "mov.l %T2,%R1\n\t" \ | ||
| 103 | "2:\n" \ | ||
| 104 | ".section .fixup,\"ax\"\n" \ | ||
| 105 | "3:\n\t" \ | ||
| 106 | "mov #0,%S1\n\t" \ | ||
| 107 | "mov #0,%R1\n\t" \ | ||
| 108 | "mov.l 4f, %0\n\t" \ | ||
| 109 | "jmp @%0\n\t" \ | ||
| 110 | " mov %3, %0\n\t" \ | ||
| 111 | ".balign 4\n" \ | ||
| 112 | "4: .long 2b\n\t" \ | ||
| 113 | ".previous\n" \ | ||
| 114 | ".section __ex_table,\"a\"\n\t" \ | ||
| 115 | ".long 1b, 3b\n\t" \ | ||
| 116 | ".long 1b + 2, 3b\n\t" \ | ||
| 117 | ".previous" \ | ||
| 118 | :"=&r" (err), "=&r" (x) \ | ||
| 119 | :"m" (__m(addr)), "i" (-EFAULT), "0" (err)); }) | ||
| 120 | #endif | ||
| 121 | |||
| 69 | #define __put_user_size(x,ptr,size,retval) \ | 122 | #define __put_user_size(x,ptr,size,retval) \ |
| 70 | do { \ | 123 | do { \ |
| 71 | retval = 0; \ | 124 | retval = 0; \ |