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

Merge branch 'cmpxchg64' of git://git.linaro.org/people/nico/linux into devel-stable

+361 -152
+267
Documentation/arm/kernel_user_helpers.txt
··· 1 + Kernel-provided User Helpers 2 + ============================ 3 + 4 + These are segment of kernel provided user code reachable from user space 5 + at a fixed address in kernel memory. This is used to provide user space 6 + with some operations which require kernel help because of unimplemented 7 + native feature and/or instructions in many ARM CPUs. The idea is for this 8 + code to be executed directly in user mode for best efficiency but which is 9 + too intimate with the kernel counter part to be left to user libraries. 10 + In fact this code might even differ from one CPU to another depending on 11 + the available instruction set, or whether it is a SMP systems. In other 12 + words, the kernel reserves the right to change this code as needed without 13 + warning. Only the entry points and their results as documented here are 14 + guaranteed to be stable. 15 + 16 + This is different from (but doesn't preclude) a full blown VDSO 17 + implementation, however a VDSO would prevent some assembly tricks with 18 + constants that allows for efficient branching to those code segments. And 19 + since those code segments only use a few cycles before returning to user 20 + code, the overhead of a VDSO indirect far call would add a measurable 21 + overhead to such minimalistic operations. 22 + 23 + User space is expected to bypass those helpers and implement those things 24 + inline (either in the code emitted directly by the compiler, or part of 25 + the implementation of a library call) when optimizing for a recent enough 26 + processor that has the necessary native support, but only if resulting 27 + binaries are already to be incompatible with earlier ARM processors due to 28 + useage of similar native instructions for other things. In other words 29 + don't make binaries unable to run on earlier processors just for the sake 30 + of not using these kernel helpers if your compiled code is not going to 31 + use new instructions for other purpose. 32 + 33 + New helpers may be added over time, so an older kernel may be missing some 34 + helpers present in a newer kernel. For this reason, programs must check 35 + the value of __kuser_helper_version (see below) before assuming that it is 36 + safe to call any particular helper. This check should ideally be 37 + performed only once at process startup time, and execution aborted early 38 + if the required helpers are not provided by the kernel version that 39 + process is running on. 40 + 41 + kuser_helper_version 42 + -------------------- 43 + 44 + Location: 0xffff0ffc 45 + 46 + Reference declaration: 47 + 48 + extern int32_t __kuser_helper_version; 49 + 50 + Definition: 51 + 52 + This field contains the number of helpers being implemented by the 53 + running kernel. User space may read this to determine the availability 54 + of a particular helper. 55 + 56 + Usage example: 57 + 58 + #define __kuser_helper_version (*(int32_t *)0xffff0ffc) 59 + 60 + void check_kuser_version(void) 61 + { 62 + if (__kuser_helper_version < 2) { 63 + fprintf(stderr, "can't do atomic operations, kernel too old\n"); 64 + abort(); 65 + } 66 + } 67 + 68 + Notes: 69 + 70 + User space may assume that the value of this field never changes 71 + during the lifetime of any single process. This means that this 72 + field can be read once during the initialisation of a library or 73 + startup phase of a program. 74 + 75 + kuser_get_tls 76 + ------------- 77 + 78 + Location: 0xffff0fe0 79 + 80 + Reference prototype: 81 + 82 + void * __kuser_get_tls(void); 83 + 84 + Input: 85 + 86 + lr = return address 87 + 88 + Output: 89 + 90 + r0 = TLS value 91 + 92 + Clobbered registers: 93 + 94 + none 95 + 96 + Definition: 97 + 98 + Get the TLS value as previously set via the __ARM_NR_set_tls syscall. 99 + 100 + Usage example: 101 + 102 + typedef void * (__kuser_get_tls_t)(void); 103 + #define __kuser_get_tls (*(__kuser_get_tls_t *)0xffff0fe0) 104 + 105 + void foo() 106 + { 107 + void *tls = __kuser_get_tls(); 108 + printf("TLS = %p\n", tls); 109 + } 110 + 111 + Notes: 112 + 113 + - Valid only if __kuser_helper_version >= 1 (from kernel version 2.6.12). 114 + 115 + kuser_cmpxchg 116 + ------------- 117 + 118 + Location: 0xffff0fc0 119 + 120 + Reference prototype: 121 + 122 + int __kuser_cmpxchg(int32_t oldval, int32_t newval, volatile int32_t *ptr); 123 + 124 + Input: 125 + 126 + r0 = oldval 127 + r1 = newval 128 + r2 = ptr 129 + lr = return address 130 + 131 + Output: 132 + 133 + r0 = success code (zero or non-zero) 134 + C flag = set if r0 == 0, clear if r0 != 0 135 + 136 + Clobbered registers: 137 + 138 + r3, ip, flags 139 + 140 + Definition: 141 + 142 + Atomically store newval in *ptr only if *ptr is equal to oldval. 143 + Return zero if *ptr was changed or non-zero if no exchange happened. 144 + The C flag is also set if *ptr was changed to allow for assembly 145 + optimization in the calling code. 146 + 147 + Usage example: 148 + 149 + typedef int (__kuser_cmpxchg_t)(int oldval, int newval, volatile int *ptr); 150 + #define __kuser_cmpxchg (*(__kuser_cmpxchg_t *)0xffff0fc0) 151 + 152 + int atomic_add(volatile int *ptr, int val) 153 + { 154 + int old, new; 155 + 156 + do { 157 + old = *ptr; 158 + new = old + val; 159 + } while(__kuser_cmpxchg(old, new, ptr)); 160 + 161 + return new; 162 + } 163 + 164 + Notes: 165 + 166 + - This routine already includes memory barriers as needed. 167 + 168 + - Valid only if __kuser_helper_version >= 2 (from kernel version 2.6.12). 169 + 170 + kuser_memory_barrier 171 + -------------------- 172 + 173 + Location: 0xffff0fa0 174 + 175 + Reference prototype: 176 + 177 + void __kuser_memory_barrier(void); 178 + 179 + Input: 180 + 181 + lr = return address 182 + 183 + Output: 184 + 185 + none 186 + 187 + Clobbered registers: 188 + 189 + none 190 + 191 + Definition: 192 + 193 + Apply any needed memory barrier to preserve consistency with data modified 194 + manually and __kuser_cmpxchg usage. 195 + 196 + Usage example: 197 + 198 + typedef void (__kuser_dmb_t)(void); 199 + #define __kuser_dmb (*(__kuser_dmb_t *)0xffff0fa0) 200 + 201 + Notes: 202 + 203 + - Valid only if __kuser_helper_version >= 3 (from kernel version 2.6.15). 204 + 205 + kuser_cmpxchg64 206 + --------------- 207 + 208 + Location: 0xffff0f60 209 + 210 + Reference prototype: 211 + 212 + int __kuser_cmpxchg64(const int64_t *oldval, 213 + const int64_t *newval, 214 + volatile int64_t *ptr); 215 + 216 + Input: 217 + 218 + r0 = pointer to oldval 219 + r1 = pointer to newval 220 + r2 = pointer to target value 221 + lr = return address 222 + 223 + Output: 224 + 225 + r0 = success code (zero or non-zero) 226 + C flag = set if r0 == 0, clear if r0 != 0 227 + 228 + Clobbered registers: 229 + 230 + r3, lr, flags 231 + 232 + Definition: 233 + 234 + Atomically store the 64-bit value pointed by *newval in *ptr only if *ptr 235 + is equal to the 64-bit value pointed by *oldval. Return zero if *ptr was 236 + changed or non-zero if no exchange happened. 237 + 238 + The C flag is also set if *ptr was changed to allow for assembly 239 + optimization in the calling code. 240 + 241 + Usage example: 242 + 243 + typedef int (__kuser_cmpxchg64_t)(const int64_t *oldval, 244 + const int64_t *newval, 245 + volatile int64_t *ptr); 246 + #define __kuser_cmpxchg64 (*(__kuser_cmpxchg64_t *)0xffff0f60) 247 + 248 + int64_t atomic_add64(volatile int64_t *ptr, int64_t val) 249 + { 250 + int64_t old, new; 251 + 252 + do { 253 + old = *ptr; 254 + new = old + val; 255 + } while(__kuser_cmpxchg64(&old, &new, ptr)); 256 + 257 + return new; 258 + } 259 + 260 + Notes: 261 + 262 + - This routine already includes memory barriers as needed. 263 + 264 + - Due to the length of this sequence, this spans 2 conventional kuser 265 + "slots", therefore 0xffff0f80 is not used as a valid entry point. 266 + 267 + - Valid only if __kuser_helper_version >= 5 (from kernel version 3.1).
+94 -152
arch/arm/kernel/entry-armv.S
··· 383 383 .endm 384 384 385 385 .macro kuser_cmpxchg_check 386 - #if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) 386 + #if !defined(CONFIG_CPU_32v6K) && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) 387 387 #ifndef CONFIG_MMU 388 388 #warning "NPTL on non MMU needs fixing" 389 389 #else ··· 392 392 @ perform a quick test inline since it should be false 393 393 @ 99.9999% of the time. The rest is done out of line. 394 394 cmp r2, #TASK_SIZE 395 - blhs kuser_cmpxchg_fixup 395 + blhs kuser_cmpxchg64_fixup 396 396 #endif 397 397 #endif 398 398 .endm ··· 758 758 /* 759 759 * User helpers. 760 760 * 761 - * These are segment of kernel provided user code reachable from user space 762 - * at a fixed address in kernel memory. This is used to provide user space 763 - * with some operations which require kernel help because of unimplemented 764 - * native feature and/or instructions in many ARM CPUs. The idea is for 765 - * this code to be executed directly in user mode for best efficiency but 766 - * which is too intimate with the kernel counter part to be left to user 767 - * libraries. In fact this code might even differ from one CPU to another 768 - * depending on the available instruction set and restrictions like on 769 - * SMP systems. In other words, the kernel reserves the right to change 770 - * this code as needed without warning. Only the entry points and their 771 - * results are guaranteed to be stable. 772 - * 773 761 * Each segment is 32-byte aligned and will be moved to the top of the high 774 762 * vector page. New segments (if ever needed) must be added in front of 775 763 * existing ones. This mechanism should be used only for things that are 776 764 * really small and justified, and not be abused freely. 777 765 * 778 - * User space is expected to implement those things inline when optimizing 779 - * for a processor that has the necessary native support, but only if such 780 - * resulting binaries are already to be incompatible with earlier ARM 781 - * processors due to the use of unsupported instructions other than what 782 - * is provided here. In other words don't make binaries unable to run on 783 - * earlier processors just for the sake of not using these kernel helpers 784 - * if your compiled code is not going to use the new instructions for other 785 - * purpose. 766 + * See Documentation/arm/kernel_user_helpers.txt for formal definitions. 786 767 */ 787 768 THUMB( .arm ) 788 769 ··· 780 799 __kuser_helper_start: 781 800 782 801 /* 783 - * Reference prototype: 784 - * 785 - * void __kernel_memory_barrier(void) 786 - * 787 - * Input: 788 - * 789 - * lr = return address 790 - * 791 - * Output: 792 - * 793 - * none 794 - * 795 - * Clobbered: 796 - * 797 - * none 798 - * 799 - * Definition and user space usage example: 800 - * 801 - * typedef void (__kernel_dmb_t)(void); 802 - * #define __kernel_dmb (*(__kernel_dmb_t *)0xffff0fa0) 803 - * 804 - * Apply any needed memory barrier to preserve consistency with data modified 805 - * manually and __kuser_cmpxchg usage. 806 - * 807 - * This could be used as follows: 808 - * 809 - * #define __kernel_dmb() \ 810 - * asm volatile ( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #95" \ 811 - * : : : "r0", "lr","cc" ) 802 + * Due to the length of some sequences, __kuser_cmpxchg64 spans 2 regular 803 + * kuser "slots", therefore 0xffff0f80 is not used as a valid entry point. 812 804 */ 805 + 806 + __kuser_cmpxchg64: @ 0xffff0f60 807 + 808 + #if defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) 809 + 810 + /* 811 + * Poor you. No fast solution possible... 812 + * The kernel itself must perform the operation. 813 + * A special ghost syscall is used for that (see traps.c). 814 + */ 815 + stmfd sp!, {r7, lr} 816 + ldr r7, 1f @ it's 20 bits 817 + swi __ARM_NR_cmpxchg64 818 + ldmfd sp!, {r7, pc} 819 + 1: .word __ARM_NR_cmpxchg64 820 + 821 + #elif defined(CONFIG_CPU_32v6K) 822 + 823 + stmfd sp!, {r4, r5, r6, r7} 824 + ldrd r4, r5, [r0] @ load old val 825 + ldrd r6, r7, [r1] @ load new val 826 + smp_dmb arm 827 + 1: ldrexd r0, r1, [r2] @ load current val 828 + eors r3, r0, r4 @ compare with oldval (1) 829 + eoreqs r3, r1, r5 @ compare with oldval (2) 830 + strexdeq r3, r6, r7, [r2] @ store newval if eq 831 + teqeq r3, #1 @ success? 832 + beq 1b @ if no then retry 833 + smp_dmb arm 834 + rsbs r0, r3, #0 @ set returned val and C flag 835 + ldmfd sp!, {r4, r5, r6, r7} 836 + bx lr 837 + 838 + #elif !defined(CONFIG_SMP) 839 + 840 + #ifdef CONFIG_MMU 841 + 842 + /* 843 + * The only thing that can break atomicity in this cmpxchg64 844 + * implementation is either an IRQ or a data abort exception 845 + * causing another process/thread to be scheduled in the middle of 846 + * the critical sequence. The same strategy as for cmpxchg is used. 847 + */ 848 + stmfd sp!, {r4, r5, r6, lr} 849 + ldmia r0, {r4, r5} @ load old val 850 + ldmia r1, {r6, lr} @ load new val 851 + 1: ldmia r2, {r0, r1} @ load current val 852 + eors r3, r0, r4 @ compare with oldval (1) 853 + eoreqs r3, r1, r5 @ compare with oldval (2) 854 + 2: stmeqia r2, {r6, lr} @ store newval if eq 855 + rsbs r0, r3, #0 @ set return val and C flag 856 + ldmfd sp!, {r4, r5, r6, pc} 857 + 858 + .text 859 + kuser_cmpxchg64_fixup: 860 + @ Called from kuser_cmpxchg_fixup. 861 + @ r2 = address of interrupted insn (must be preserved). 862 + @ sp = saved regs. r7 and r8 are clobbered. 863 + @ 1b = first critical insn, 2b = last critical insn. 864 + @ If r2 >= 1b and r2 <= 2b then saved pc_usr is set to 1b. 865 + mov r7, #0xffff0fff 866 + sub r7, r7, #(0xffff0fff - (0xffff0f60 + (1b - __kuser_cmpxchg64))) 867 + subs r8, r2, r7 868 + rsbcss r8, r8, #(2b - 1b) 869 + strcs r7, [sp, #S_PC] 870 + #if __LINUX_ARM_ARCH__ < 6 871 + bcc kuser_cmpxchg32_fixup 872 + #endif 873 + mov pc, lr 874 + .previous 875 + 876 + #else 877 + #warning "NPTL on non MMU needs fixing" 878 + mov r0, #-1 879 + adds r0, r0, #0 880 + usr_ret lr 881 + #endif 882 + 883 + #else 884 + #error "incoherent kernel configuration" 885 + #endif 886 + 887 + /* pad to next slot */ 888 + .rept (16 - (. - __kuser_cmpxchg64)/4) 889 + .word 0 890 + .endr 891 + 892 + .align 5 813 893 814 894 __kuser_memory_barrier: @ 0xffff0fa0 815 895 smp_dmb arm 816 896 usr_ret lr 817 897 818 898 .align 5 819 - 820 - /* 821 - * Reference prototype: 822 - * 823 - * int __kernel_cmpxchg(int oldval, int newval, int *ptr) 824 - * 825 - * Input: 826 - * 827 - * r0 = oldval 828 - * r1 = newval 829 - * r2 = ptr 830 - * lr = return address 831 - * 832 - * Output: 833 - * 834 - * r0 = returned value (zero or non-zero) 835 - * C flag = set if r0 == 0, clear if r0 != 0 836 - * 837 - * Clobbered: 838 - * 839 - * r3, ip, flags 840 - * 841 - * Definition and user space usage example: 842 - * 843 - * typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr); 844 - * #define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0) 845 - * 846 - * Atomically store newval in *ptr if *ptr is equal to oldval for user space. 847 - * Return zero if *ptr was changed or non-zero if no exchange happened. 848 - * The C flag is also set if *ptr was changed to allow for assembly 849 - * optimization in the calling code. 850 - * 851 - * Notes: 852 - * 853 - * - This routine already includes memory barriers as needed. 854 - * 855 - * For example, a user space atomic_add implementation could look like this: 856 - * 857 - * #define atomic_add(ptr, val) \ 858 - * ({ register unsigned int *__ptr asm("r2") = (ptr); \ 859 - * register unsigned int __result asm("r1"); \ 860 - * asm volatile ( \ 861 - * "1: @ atomic_add\n\t" \ 862 - * "ldr r0, [r2]\n\t" \ 863 - * "mov r3, #0xffff0fff\n\t" \ 864 - * "add lr, pc, #4\n\t" \ 865 - * "add r1, r0, %2\n\t" \ 866 - * "add pc, r3, #(0xffff0fc0 - 0xffff0fff)\n\t" \ 867 - * "bcc 1b" \ 868 - * : "=&r" (__result) \ 869 - * : "r" (__ptr), "rIL" (val) \ 870 - * : "r0","r3","ip","lr","cc","memory" ); \ 871 - * __result; }) 872 - */ 873 899 874 900 __kuser_cmpxchg: @ 0xffff0fc0 875 901 ··· 913 925 usr_ret lr 914 926 915 927 .text 916 - kuser_cmpxchg_fixup: 928 + kuser_cmpxchg32_fixup: 917 929 @ Called from kuser_cmpxchg_check macro. 918 930 @ r2 = address of interrupted insn (must be preserved). 919 931 @ sp = saved regs. r7 and r8 are clobbered. ··· 951 963 952 964 .align 5 953 965 954 - /* 955 - * Reference prototype: 956 - * 957 - * int __kernel_get_tls(void) 958 - * 959 - * Input: 960 - * 961 - * lr = return address 962 - * 963 - * Output: 964 - * 965 - * r0 = TLS value 966 - * 967 - * Clobbered: 968 - * 969 - * none 970 - * 971 - * Definition and user space usage example: 972 - * 973 - * typedef int (__kernel_get_tls_t)(void); 974 - * #define __kernel_get_tls (*(__kernel_get_tls_t *)0xffff0fe0) 975 - * 976 - * Get the TLS value as previously set via the __ARM_NR_set_tls syscall. 977 - * 978 - * This could be used as follows: 979 - * 980 - * #define __kernel_get_tls() \ 981 - * ({ register unsigned int __val asm("r0"); \ 982 - * asm( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #31" \ 983 - * : "=r" (__val) : : "lr","cc" ); \ 984 - * __val; }) 985 - */ 986 - 987 966 __kuser_get_tls: @ 0xffff0fe0 988 967 ldr r0, [pc, #(16 - 8)] @ read TLS, set in kuser_get_tls_init 989 968 usr_ret lr ··· 958 1003 .rep 4 959 1004 .word 0 @ 0xffff0ff0 software TLS value, then 960 1005 .endr @ pad up to __kuser_helper_version 961 - 962 - /* 963 - * Reference declaration: 964 - * 965 - * extern unsigned int __kernel_helper_version; 966 - * 967 - * Definition and user space usage example: 968 - * 969 - * #define __kernel_helper_version (*(unsigned int *)0xffff0ffc) 970 - * 971 - * User space may read this to determine the curent number of helpers 972 - * available. 973 - */ 974 1006 975 1007 __kuser_helper_version: @ 0xffff0ffc 976 1008 .word ((__kuser_helper_end - __kuser_helper_start) >> 5)