Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags   |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) ============================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) Kernel-provided User Helpers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) ============================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) These are segment of kernel provided user code reachable from user space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) at a fixed address in kernel memory.  This is used to provide user space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) with some operations which require kernel help because of unimplemented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) native feature and/or instructions in many ARM CPUs. The idea is for this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) code to be executed directly in user mode for best efficiency but which is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) too intimate with the kernel counter part to be left to user libraries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) In fact this code might even differ from one CPU to another depending on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) the available instruction set, or whether it is a SMP systems. In other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) words, the kernel reserves the right to change this code as needed without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) warning. Only the entry points and their results as documented here are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) guaranteed to be stable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) This is different from (but doesn't preclude) a full blown VDSO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) implementation, however a VDSO would prevent some assembly tricks with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) constants that allows for efficient branching to those code segments. And
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) since those code segments only use a few cycles before returning to user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) code, the overhead of a VDSO indirect far call would add a measurable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) overhead to such minimalistic operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) User space is expected to bypass those helpers and implement those things
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) inline (either in the code emitted directly by the compiler, or part of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) the implementation of a library call) when optimizing for a recent enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) processor that has the necessary native support, but only if resulting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) binaries are already to be incompatible with earlier ARM processors due to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) usage of similar native instructions for other things.  In other words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) don't make binaries unable to run on earlier processors just for the sake
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) of not using these kernel helpers if your compiled code is not going to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) use new instructions for other purpose.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) New helpers may be added over time, so an older kernel may be missing some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) helpers present in a newer kernel.  For this reason, programs must check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) the value of __kuser_helper_version (see below) before assuming that it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) safe to call any particular helper.  This check should ideally be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) performed only once at process startup time, and execution aborted early
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) if the required helpers are not provided by the kernel version that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) process is running on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) kuser_helper_version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) --------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) Location:	0xffff0ffc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) Reference declaration::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)   extern int32_t __kuser_helper_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) Definition:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)   This field contains the number of helpers being implemented by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)   running kernel.  User space may read this to determine the availability
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)   of a particular helper.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) Usage example::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)   #define __kuser_helper_version (*(int32_t *)0xffff0ffc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)   void check_kuser_version(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)   {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	if (__kuser_helper_version < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		fprintf(stderr, "can't do atomic operations, kernel too old\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		abort();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)   }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)   User space may assume that the value of this field never changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)   during the lifetime of any single process.  This means that this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)   field can be read once during the initialisation of a library or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)   startup phase of a program.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) kuser_get_tls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) -------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) Location:	0xffff0fe0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) Reference prototype::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)   void * __kuser_get_tls(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)   lr = return address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) Output:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)   r0 = TLS value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) Clobbered registers:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)   none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) Definition:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)   Get the TLS value as previously set via the __ARM_NR_set_tls syscall.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) Usage example::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)   typedef void * (__kuser_get_tls_t)(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)   #define __kuser_get_tls (*(__kuser_get_tls_t *)0xffff0fe0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)   void foo()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)   {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	void *tls = __kuser_get_tls();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	printf("TLS = %p\n", tls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)   }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)   - Valid only if __kuser_helper_version >= 1 (from kernel version 2.6.12).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) kuser_cmpxchg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) -------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) Location:	0xffff0fc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) Reference prototype::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)   int __kuser_cmpxchg(int32_t oldval, int32_t newval, volatile int32_t *ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)   r0 = oldval
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)   r1 = newval
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)   r2 = ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)   lr = return address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) Output:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)   r0 = success code (zero or non-zero)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)   C flag = set if r0 == 0, clear if r0 != 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) Clobbered registers:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)   r3, ip, flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) Definition:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)   Atomically store newval in `*ptr` only if `*ptr` is equal to oldval.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)   Return zero if `*ptr` was changed or non-zero if no exchange happened.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)   The C flag is also set if `*ptr` was changed to allow for assembly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)   optimization in the calling code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) Usage example::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)   typedef int (__kuser_cmpxchg_t)(int oldval, int newval, volatile int *ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)   #define __kuser_cmpxchg (*(__kuser_cmpxchg_t *)0xffff0fc0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)   int atomic_add(volatile int *ptr, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)   {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	int old, new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		old = *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		new = old + val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	} while(__kuser_cmpxchg(old, new, ptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	return new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)   }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)   - This routine already includes memory barriers as needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)   - Valid only if __kuser_helper_version >= 2 (from kernel version 2.6.12).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) kuser_memory_barrier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) --------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) Location:	0xffff0fa0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) Reference prototype::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)   void __kuser_memory_barrier(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)   lr = return address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) Output:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)   none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) Clobbered registers:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)   none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) Definition:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)   Apply any needed memory barrier to preserve consistency with data modified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)   manually and __kuser_cmpxchg usage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) Usage example::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)   typedef void (__kuser_dmb_t)(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)   #define __kuser_dmb (*(__kuser_dmb_t *)0xffff0fa0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)   - Valid only if __kuser_helper_version >= 3 (from kernel version 2.6.15).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) kuser_cmpxchg64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ---------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) Location:	0xffff0f60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) Reference prototype::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)   int __kuser_cmpxchg64(const int64_t *oldval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)                         const int64_t *newval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)                         volatile int64_t *ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)   r0 = pointer to oldval
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)   r1 = pointer to newval
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)   r2 = pointer to target value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)   lr = return address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) Output:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)   r0 = success code (zero or non-zero)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)   C flag = set if r0 == 0, clear if r0 != 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) Clobbered registers:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)   r3, lr, flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) Definition:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)   Atomically store the 64-bit value pointed by `*newval` in `*ptr` only if `*ptr`
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)   is equal to the 64-bit value pointed by `*oldval`.  Return zero if `*ptr` was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)   changed or non-zero if no exchange happened.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)   The C flag is also set if `*ptr` was changed to allow for assembly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)   optimization in the calling code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) Usage example::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)   typedef int (__kuser_cmpxchg64_t)(const int64_t *oldval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)                                     const int64_t *newval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)                                     volatile int64_t *ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)   #define __kuser_cmpxchg64 (*(__kuser_cmpxchg64_t *)0xffff0f60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)   int64_t atomic_add64(volatile int64_t *ptr, int64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)   {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	int64_t old, new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		old = *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		new = old + val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	} while(__kuser_cmpxchg64(&old, &new, ptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	return new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)   }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)   - This routine already includes memory barriers as needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)   - Due to the length of this sequence, this spans 2 conventional kuser
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)     "slots", therefore 0xffff0f80 is not used as a valid entry point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)   - Valid only if __kuser_helper_version >= 5 (from kernel version 3.1).