diff options
author | Nicolas Pitre <nico@org.rmk.(none)> | 2005-05-05 18:24:45 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-05-05 18:24:45 -0400 |
commit | 4b0e07a5566a4e3f141e52c1f17e683e4a5bba91 (patch) | |
tree | 4a2f67e6cb6ea665c6d45529a5b7c61ac255663d /arch/arm | |
parent | f7e68bbf405a45d6e7c5b8fc384ff1ba20dd7aa4 (diff) |
[PATCH] ARM: 2663/1: straightify TLS register emulation a bit more
Patch from Nicolas Pitre
This better express things, and should cover RMK's weird SMP toys.
Signed-off-by: Nicolas Pitre
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/kernel/entry-armv.S | 10 | ||||
-rw-r--r-- | arch/arm/kernel/traps.c | 11 | ||||
-rw-r--r-- | arch/arm/mm/Kconfig | 24 |
3 files changed, 25 insertions, 20 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 080df907f242..c6af1a03e081 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -505,9 +505,9 @@ ENTRY(__switch_to) | |||
505 | mra r4, r5, acc0 | 505 | mra r4, r5, acc0 |
506 | stmia ip, {r4, r5} | 506 | stmia ip, {r4, r5} |
507 | #endif | 507 | #endif |
508 | #ifdef CONFIG_HAS_TLS_REG | 508 | #if defined(CONFIG_HAS_TLS_REG) |
509 | mcr p15, 0, r3, c13, c0, 3 @ set TLS register | 509 | mcr p15, 0, r3, c13, c0, 3 @ set TLS register |
510 | #else | 510 | #elif !defined(CONFIG_TLS_REG_EMUL) |
511 | mov r4, #0xffff0fff | 511 | mov r4, #0xffff0fff |
512 | str r3, [r4, #-15] @ TLS val at 0xffff0ff0 | 512 | str r3, [r4, #-15] @ TLS val at 0xffff0ff0 |
513 | #endif | 513 | #endif |
@@ -690,11 +690,7 @@ __kuser_cmpxchg: @ 0xffff0fc0 | |||
690 | 690 | ||
691 | __kuser_get_tls: @ 0xffff0fe0 | 691 | __kuser_get_tls: @ 0xffff0fe0 |
692 | 692 | ||
693 | #ifndef CONFIG_HAS_TLS_REG | 693 | #if !defined(CONFIG_HAS_TLS_REG) && !defined(CONFIG_TLS_REG_EMUL) |
694 | |||
695 | #ifdef CONFIG_SMP /* sanity check */ | ||
696 | #error "CONFIG_SMP without CONFIG_HAS_TLS_REG is wrong" | ||
697 | #endif | ||
698 | 694 | ||
699 | ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0 | 695 | ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0 |
700 | mov pc, lr | 696 | mov pc, lr |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 8988c02119fd..14df16b983f4 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -451,9 +451,9 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) | |||
451 | 451 | ||
452 | case NR(set_tls): | 452 | case NR(set_tls): |
453 | thread->tp_value = regs->ARM_r0; | 453 | thread->tp_value = regs->ARM_r0; |
454 | #ifdef CONFIG_HAS_TLS_REG | 454 | #if defined(CONFIG_HAS_TLS_REG) |
455 | asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) ); | 455 | asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) ); |
456 | #else | 456 | #elif !defined(CONFIG_TLS_REG_EMUL) |
457 | /* | 457 | /* |
458 | * User space must never try to access this directly. | 458 | * User space must never try to access this directly. |
459 | * Expect your app to break eventually if you do so. | 459 | * Expect your app to break eventually if you do so. |
@@ -498,11 +498,14 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) | |||
498 | return 0; | 498 | return 0; |
499 | } | 499 | } |
500 | 500 | ||
501 | #if defined(CONFIG_CPU_32v6) && !defined(CONFIG_HAS_TLS_REG) | 501 | #ifdef CONFIG_TLS_REG_EMUL |
502 | 502 | ||
503 | /* | 503 | /* |
504 | * We might be running on an ARMv6+ processor which should have the TLS | 504 | * We might be running on an ARMv6+ processor which should have the TLS |
505 | * register, but for some reason we can't use it and have to emulate it. | 505 | * register but for some reason we can't use it, or maybe an SMP system |
506 | * using a pre-ARMv6 processor (there are apparently a few prototypes like | ||
507 | * that in existence) and therefore access to that register must be | ||
508 | * emulated. | ||
506 | */ | 509 | */ |
507 | 510 | ||
508 | static int get_tp_trap(struct pt_regs *regs, unsigned int instr) | 511 | static int get_tp_trap(struct pt_regs *regs, unsigned int instr) |
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 27892e34b060..c4fc6be629de 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
@@ -410,17 +410,23 @@ config CPU_BPREDICT_DISABLE | |||
410 | help | 410 | help |
411 | Say Y here to disable branch prediction. If unsure, say N. | 411 | Say Y here to disable branch prediction. If unsure, say N. |
412 | 412 | ||
413 | config TLS_REG_EMUL | ||
414 | bool | ||
415 | default y if (SMP || CPU_32v6) && (CPU_32v5 || CPU_32v4 || CPU_32v3) | ||
416 | help | ||
417 | We might be running on an ARMv6+ processor which should have the TLS | ||
418 | register but for some reason we can't use it, or maybe an SMP system | ||
419 | using a pre-ARMv6 processor (there are apparently a few prototypes | ||
420 | like that in existence) and therefore access to that register must | ||
421 | be emulated. | ||
422 | |||
413 | config HAS_TLS_REG | 423 | config HAS_TLS_REG |
414 | bool | 424 | bool |
415 | depends on CPU_32v6 && !CPU_32v5 && !CPU_32v4 && !CPU_32v3 | 425 | depends on CPU_32v6 |
416 | default y | 426 | default y if !TLS_REG_EMUL |
417 | help | 427 | help |
418 | This selects support for the CP15 thread register. | 428 | This selects support for the CP15 thread register. |
419 | It is defined to be available on ARMv6 or later. However | 429 | It is defined to be available on ARMv6 or later. If a particular |
420 | if the kernel is configured to support multiple CPUs including | 430 | ARMv6 or later CPU doesn't support it then it must omc;ide "select |
421 | a pre-ARMv6 processors, or if a given ARMv6 processor doesn't | 431 | TLS_REG_EMUL" along with its other caracteristics. |
422 | implement the thread register for some reason, then access to | ||
423 | this register from user space must be trapped and emulated. | ||
424 | If user space is relying on the __kuser_get_tls code then | ||
425 | there should not be any impact. | ||
426 | 432 | ||