summaryrefslogtreecommitdiff
path: root/packages/linux/linux-handhelds-2.6-2.6.16/pitre-tls-2651.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packages/linux/linux-handhelds-2.6-2.6.16/pitre-tls-2651.patch')
-rw-r--r--packages/linux/linux-handhelds-2.6-2.6.16/pitre-tls-2651.patch294
1 files changed, 0 insertions, 294 deletions
diff --git a/packages/linux/linux-handhelds-2.6-2.6.16/pitre-tls-2651.patch b/packages/linux/linux-handhelds-2.6-2.6.16/pitre-tls-2651.patch
deleted file mode 100644
index 5ef318e4ac..0000000000
--- a/packages/linux/linux-handhelds-2.6-2.6.16/pitre-tls-2651.patch
+++ /dev/null
@@ -1,294 +0,0 @@
---- linux-2.6.orig/arch/arm/kernel/entry-armv.S
-+++ linux-2.6/arch/arm/kernel/entry-armv.S
-@@ -269,6 +269,12 @@
- add r5, sp, #S_PC
- ldmia r7, {r2 - r4} @ Get USR pc, cpsr
-
-+#if __LINUX_ARM_ARCH__ < 6
-+ @ make sure our user space atomic helper is aborted
-+ cmp r2, #VIRT_OFFSET
-+ bichs r3, r3, #PSR_Z_BIT
-+#endif
-+
- @
- @ We are now ready to fill in the remaining blanks on the stack:
- @
-@@ -499,8 +505,12 @@
- mra r4, r5, acc0
- stmia ip, {r4, r5}
- #endif
-+#ifdef CONFIG_HAS_TLS_REG
-+ mcr p15, 0, r3, c13, c0, 3 @ set TLS register
-+#else
- mov r4, #0xffff0fff
-- str r3, [r4, #-3] @ Set TLS ptr
-+ str r3, [r4, #-15] @ TLS val at 0xffff0ff0
-+#endif
- mcr p15, 0, r6, c3, c0, 0 @ Set domain register
- #ifdef CONFIG_VFP
- @ Always disable VFP so we can lazily save/restore the old
-@@ -519,6 +529,196 @@
- ldmib r2, {r4 - sl, fp, sp, pc} @ Load all regs saved previously
-
- __INIT
-+
-+/*
-+ * 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 and restrictions like on
-+ * 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 are guaranteed to be stable.
-+ *
-+ * Each segment is 32-byte aligned and will be moved to the top of the high
-+ * vector page. New segments (if ever needed) must be added in front of
-+ * existing ones. This mechanism should be used only for things that are
-+ * really small and justified, and not be abused freely.
-+ *
-+ * User space is expected to implement those things inline when optimizing
-+ * for a processor that has the necessary native support, but only if such
-+ * resulting binaries are already to be incompatible with earlier ARM
-+ * processors due to the use of unsupported instructions other than what
-+ * is provided here. 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 the new instructions for other
-+ * purpose.
-+ */
-+
-+ .align 5
-+__kuser_helper_start:
-+
-+/*
-+ * Reference prototype:
-+ *
-+ * int __kernel_cmpxchg(int oldval, int newval, int *ptr)
-+ *
-+ * Input:
-+ *
-+ * r0 = oldval
-+ * r1 = newval
-+ * r2 = ptr
-+ * lr = return address
-+ *
-+ * Output:
-+ *
-+ * r0 = returned value (zero or non-zero)
-+ * C flag = set if r0 == 0, clear if r0 != 0
-+ *
-+ * Clobbered:
-+ *
-+ * r3, ip, flags
-+ *
-+ * Definition and user space usage example:
-+ *
-+ * typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr);
-+ * #define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
-+ *
-+ * Atomically store newval in *ptr if *ptr is equal to oldval for user space.
-+ * 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.
-+ *
-+ * For example, a user space atomic_add implementation could look like this:
-+ *
-+ * #define atomic_add(ptr, val) \
-+ * ({ register unsigned int *__ptr asm("r2") = (ptr); \
-+ * register unsigned int __result asm("r1"); \
-+ * asm volatile ( \
-+ * "1: @ atomic_add\n\t" \
-+ * "ldr r0, [r2]\n\t" \
-+ * "mov r3, #0xffff0fff\n\t" \
-+ * "add lr, pc, #4\n\t" \
-+ * "add r1, r0, %2\n\t" \
-+ * "add pc, r3, #(0xffff0fc0 - 0xffff0fff)\n\t" \
-+ * "bcc 1b" \
-+ * : "=&r" (__result) \
-+ * : "r" (__ptr), "rIL" (val) \
-+ * : "r0","r3","ip","lr","cc","memory" ); \
-+ * __result; })
-+ */
-+
-+__kuser_cmpxchg: @ 0xffff0fc0
-+
-+#if __LINUX_ARM_ARCH__ < 6
-+
-+ /*
-+ * Theory of operation:
-+ *
-+ * We set the Z flag before loading oldval. If ever an exception
-+ * occurs we can not be sure the loaded value will still be the same
-+ * when the exception returns, therefore the user exception handler
-+ * will clear the Z flag whenever the interrupted user code was
-+ * actually from the kernel address space (see the usr_entry macro).
-+ *
-+ * The post-increment on the str is used to prevent a race with an
-+ * exception happening just after the str instruction which would
-+ * clear the Z flag although the exchange was done.
-+ */
-+ teq ip, ip @ set Z flag
-+ ldr ip, [r2] @ load current val
-+ add r3, r2, #1 @ prepare store ptr
-+ teqeq ip, r0 @ compare with oldval if still allowed
-+ streq r1, [r3, #-1]! @ store newval if still allowed
-+ subs r0, r2, r3 @ if r2 == r3 the str occured
-+ mov pc, lr
-+
-+#else
-+
-+ ldrex r3, [r2]
-+ subs r3, r3, r0
-+ strexeq r3, r1, [r2]
-+ rsbs r0, r3, #0
-+ mov pc, lr
-+
-+#endif
-+
-+ .align 5
-+
-+/*
-+ * Reference prototype:
-+ *
-+ * int __kernel_get_tls(void)
-+ *
-+ * Input:
-+ *
-+ * lr = return address
-+ *
-+ * Output:
-+ *
-+ * r0 = TLS value
-+ *
-+ * Clobbered:
-+ *
-+ * the Z flag might be lost
-+ *
-+ * Definition and user space usage example:
-+ *
-+ * typedef int (__kernel_get_tls_t)(void);
-+ * #define __kernel_get_tls (*(__kernel_get_tls_t *)0xffff0fe0)
-+ *
-+ * Get the TLS value as previously set via the __ARM_NR_set_tls syscall.
-+ *
-+ * This could be used as follows:
-+ *
-+ * #define __kernel_get_tls() \
-+ * ({ register unsigned int __val asm("r0"); \
-+ * asm( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #31" \
-+ * : "=r" (__val) : : "lr","cc" ); \
-+ * __val; })
-+ */
-+
-+__kuser_get_tls: @ 0xffff0fe0
-+
-+#ifndef CONFIG_HAS_TLS_REG
-+
-+ ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0
-+ mov pc, lr
-+
-+#else
-+
-+ mrc p15, 0, r0, c13, c0, 3 @ read TLS register
-+ mov pc, lr
-+
-+#endif
-+
-+ .rep 5
-+ .word 0 @ pad up to __kuser_helper_version
-+ .endr
-+
-+/*
-+ * Reference declaration:
-+ *
-+ * extern unsigned int __kernel_helper_version;
-+ *
-+ * Definition and user space usage example:
-+ *
-+ * #define __kernel_helper_version (*(unsigned int *)0xffff0ffc)
-+ *
-+ * User space may read this to determine the curent number of helpers
-+ * available.
-+ */
-+
-+__kuser_helper_version: @ 0xffff0ffc
-+ .word ((__kuser_helper_end - __kuser_helper_start) >> 5)
-+__kuser_helper_end:
-+
-+
- /*
- * Vector stubs.
- *
-@@ -710,12 +910,21 @@
- stmia r0, {r1, r2, r3, r4, r5, r6, ip, lr}
-
- add r2, r0, #0x200
-- adr r0, __stubs_start @ copy stubs to 0x200
-- adr r1, __stubs_end
--1: ldr r3, [r0], #4
-+ adr r1, __stubs_start @ copy stubs to 0x200
-+ adr r4, __stubs_end
-+1: ldr r3, [r1], #4
- str r3, [r2], #4
-- cmp r0, r1
-- blt 1b
-+ cmp r1, r4
-+ blo 1b
-+
-+ add r2, r0, #0x1000 @ top of high vector page
-+ adr r4, __kuser_helper_end @ user helpers to top of page
-+ adr r1, __kuser_helper_start @ going downwards.
-+1: ldr r3, [r4, #-4]!
-+ str r3, [r2, #-4]!
-+ cmp r4, r1
-+ bhi 1b
-+
- LOADREGS(fd, sp!, {r4 - r6, pc})
-
- .data
-Index: linux-2.6/arch/arm/kernel/traps.c
-===================================================================
---- linux-2.6.orig/arch/arm/kernel/traps.c
-+++ linux-2.6/arch/arm/kernel/traps.c
-@@ -454,13 +454,17 @@
-
- case NR(set_tls):
- thread->tp_value = regs->ARM_r0;
-+#ifdef CONFIG_HAS_TLS_REG
-+ asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) );
-+#else
- /*
-- * Our user accessible TLS ptr is located at 0xffff0ffc.
-- * On SMP read access to this address must raise a fault
-- * and be emulated from the data abort handler.
-- * m
-+ * User space must never try to access this directly.
-+ * Expect your app to break eventually if you do so.
-+ * The user helper at 0xffff0fe0 must be used instead.
-+ * (see entry-armv.S for details)
- */
-- *((unsigned long *)0xffff0ffc) = thread->tp_value;
-+ *((unsigned int *)0xffff0ff0) = regs->ARM_r0;
-+#endif
- return 0;
-
- default:
---- kernel26/include/asm-arm/unistd.h.old 2005-04-16 05:17:08.344899152 +0100
-+++ kernel26/include/asm-arm/unistd.h 2005-04-16 05:17:54.027954272 +0100
-@@ -315,10 +315,9 @@
- #define __ARM_NR_cacheflush (__ARM_NR_BASE+2)
- #define __ARM_NR_usr26 (__ARM_NR_BASE+3)
- #define __ARM_NR_usr32 (__ARM_NR_BASE+4)
-+#define __ARM_NR_set_tls (__ARM_NR_BASE+5)
- #define __ARM_NR_lbl (__ARM_NR_BASE+9)
-
--#define __ARM_NR_set_tls (__ARM_NR_BASE+0x800)
--
- #define __sys2(x) #x
- #define __sys1(x) __sys2(x)
-