summaryrefslogtreecommitdiffstats
path: root/Documentation/arm/kernel_user_helpers.txt
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/arm/kernel_user_helpers.txt')
-rw-r--r--Documentation/arm/kernel_user_helpers.txt267
1 files changed, 0 insertions, 267 deletions
diff --git a/Documentation/arm/kernel_user_helpers.txt b/Documentation/arm/kernel_user_helpers.txt
deleted file mode 100644
index 5673594..0000000
--- a/Documentation/arm/kernel_user_helpers.txt
+++ /dev/null
@@ -1,267 +0,0 @@
-Kernel-provided User Helpers
-============================
-
-These are segment of kernel provided user code reachable from user space
-at a fixed address in kernel memory. This is used to provide user space
-with some operations which require kernel help because of unimplemented
-native feature and/or instructions in many ARM CPUs. The idea is for this
-code to be executed directly in user mode for best efficiency but which is
-too intimate with the kernel counter part to be left to user libraries.
-In fact this code might even differ from one CPU to another depending on
-the available instruction set, or whether it is a SMP systems. In other
-words, the kernel reserves the right to change this code as needed without
-warning. Only the entry points and their results as documented here are
-guaranteed to be stable.
-
-This is different from (but doesn't preclude) a full blown VDSO
-implementation, however a VDSO would prevent some assembly tricks with
-constants that allows for efficient branching to those code segments. And
-since those code segments only use a few cycles before returning to user
-code, the overhead of a VDSO indirect far call would add a measurable
-overhead to such minimalistic operations.
-
-User space is expected to bypass those helpers and implement those things
-inline (either in the code emitted directly by the compiler, or part of
-the implementation of a library call) when optimizing for a recent enough
-processor that has the necessary native support, but only if resulting
-binaries are already to be incompatible with earlier ARM processors due to
-usage of similar native instructions for other things. In other words
-don't make binaries unable to run on earlier processors just for the sake
-of not using these kernel helpers if your compiled code is not going to
-use new instructions for other purpose.
-
-New helpers may be added over time, so an older kernel may be missing some
-helpers present in a newer kernel. For this reason, programs must check
-the value of __kuser_helper_version (see below) before assuming that it is
-safe to call any particular helper. This check should ideally be
-performed only once at process startup time, and execution aborted early
-if the required helpers are not provided by the kernel version that
-process is running on.
-
-kuser_helper_version
---------------------
-
-Location: 0xffff0ffc
-
-Reference declaration:
-
- extern int32_t __kuser_helper_version;
-
-Definition:
-
- This field contains the number of helpers being implemented by the
- running kernel. User space may read this to determine the availability
- of a particular helper.
-
-Usage example:
-
-#define __kuser_helper_version (*(int32_t *)0xffff0ffc)
-
-void check_kuser_version(void)
-{
- if (__kuser_helper_version < 2) {
- fprintf(stderr, "can't do atomic operations, kernel too old\n");
- abort();
- }
-}
-
-Notes:
-
- User space may assume that the value of this field never changes
- during the lifetime of any single process. This means that this
- field can be read once during the initialisation of a library or
- startup phase of a program.
-
-kuser_get_tls
--------------
-
-Location: 0xffff0fe0
-
-Reference prototype:
-
- void * __kuser_get_tls(void);
-
-Input:
-
- lr = return address
-
-Output:
-
- r0 = TLS value
-
-Clobbered registers:
-
- none
-
-Definition:
-
- Get the TLS value as previously set via the __ARM_NR_set_tls syscall.
-
-Usage example:
-
-typedef void * (__kuser_get_tls_t)(void);
-#define __kuser_get_tls (*(__kuser_get_tls_t *)0xffff0fe0)
-
-void foo()
-{
- void *tls = __kuser_get_tls();
- printf("TLS = %p\n", tls);
-}
-
-Notes:
-
- - Valid only if __kuser_helper_version >= 1 (from kernel version 2.6.12).
-
-kuser_cmpxchg
--------------
-
-Location: 0xffff0fc0
-
-Reference prototype:
-
- int __kuser_cmpxchg(int32_t oldval, int32_t newval, volatile int32_t *ptr);
-
-Input:
-
- r0 = oldval
- r1 = newval
- r2 = ptr
- lr = return address
-
-Output:
-
- r0 = success code (zero or non-zero)
- C flag = set if r0 == 0, clear if r0 != 0
-
-Clobbered registers:
-
- r3, ip, flags
-
-Definition:
-
- Atomically store newval in *ptr only if *ptr is equal to oldval.
- Return zero if *ptr was changed or non-zero if no exchange happened.
- The C flag is also set if *ptr was changed to allow for assembly
- optimization in the calling code.
-
-Usage example:
-
-typedef int (__kuser_cmpxchg_t)(int oldval, int newval, volatile int *ptr);
-#define __kuser_cmpxchg (*(__kuser_cmpxchg_t *)0xffff0fc0)
-
-int atomic_add(volatile int *ptr, int val)
-{
- int old, new;
-
- do {
- old = *ptr;
- new = old + val;
- } while(__kuser_cmpxchg(old, new, ptr));
-
- return new;
-}
-
-Notes:
-
- - This routine already includes memory barriers as needed.
-
- - Valid only if __kuser_helper_version >= 2 (from kernel version 2.6.12).
-
-kuser_memory_barrier
---------------------
-
-Location: 0xffff0fa0
-
-Reference prototype:
-
- void __kuser_memory_barrier(void);
-
-Input:
-
- lr = return address
-
-Output:
-
- none
-
-Clobbered registers:
-
- none
-
-Definition:
-
- Apply any needed memory barrier to preserve consistency with data modified
- manually and __kuser_cmpxchg usage.
-
-Usage example:
-
-typedef void (__kuser_dmb_t)(void);
-#define __kuser_dmb (*(__kuser_dmb_t *)0xffff0fa0)
-
-Notes:
-
- - Valid only if __kuser_helper_version >= 3 (from kernel version 2.6.15).
-
-kuser_cmpxchg64
----------------
-
-Location: 0xffff0f60
-
-Reference prototype:
-
- int __kuser_cmpxchg64(const int64_t *oldval,
- const int64_t *newval,
- volatile int64_t *ptr);
-
-Input:
-
- r0 = pointer to oldval
- r1 = pointer to newval
- r2 = pointer to target value
- lr = return address
-
-Output:
-
- r0 = success code (zero or non-zero)
- C flag = set if r0 == 0, clear if r0 != 0
-
-Clobbered registers:
-
- r3, lr, flags
-
-Definition:
-
- Atomically store the 64-bit value pointed by *newval in *ptr only if *ptr
- is equal to the 64-bit value pointed by *oldval. Return zero if *ptr was
- changed or non-zero if no exchange happened.
-
- The C flag is also set if *ptr was changed to allow for assembly
- optimization in the calling code.
-
-Usage example:
-
-typedef int (__kuser_cmpxchg64_t)(const int64_t *oldval,
- const int64_t *newval,
- volatile int64_t *ptr);
-#define __kuser_cmpxchg64 (*(__kuser_cmpxchg64_t *)0xffff0f60)
-
-int64_t atomic_add64(volatile int64_t *ptr, int64_t val)
-{
- int64_t old, new;
-
- do {
- old = *ptr;
- new = old + val;
- } while(__kuser_cmpxchg64(&old, &new, ptr));
-
- return new;
-}
-
-Notes:
-
- - This routine already includes memory barriers as needed.
-
- - Due to the length of this sequence, this spans 2 conventional kuser
- "slots", therefore 0xffff0f80 is not used as a valid entry point.
-
- - Valid only if __kuser_helper_version >= 5 (from kernel version 3.1).