|
12 | 12 |
|
13 | 13 | .macro switch_tls_v6k, base, tp, tpuser, tmp1, tmp2
|
14 | 14 | mrc p15, 0, \tmp2, c13, c0, 2 @ get the user r/w register
|
15 |
| - mcr p15, 0, \tp, c13, c0, 3 @ set TLS register |
16 |
| - mcr p15, 0, \tpuser, c13, c0, 2 @ and the user r/w register |
| 15 | + @ TLS register update is deferred until return to user space |
| 16 | + mcr p15, 0, \tpuser, c13, c0, 2 @ set the user r/w register |
17 | 17 | str \tmp2, [\base, #TI_TP_VALUE + 4] @ save it
|
18 | 18 | .endm
|
19 | 19 |
|
|
38 | 38 | #ifdef CONFIG_TLS_REG_EMUL
|
39 | 39 | #define tls_emu 1
|
40 | 40 | #define has_tls_reg 1
|
| 41 | +#define defer_tls_reg_update 0 |
41 | 42 | #define switch_tls switch_tls_none
|
42 | 43 | #elif defined(CONFIG_CPU_V6)
|
43 | 44 | #define tls_emu 0
|
44 | 45 | #define has_tls_reg (elf_hwcap & HWCAP_TLS)
|
| 46 | +#define defer_tls_reg_update 0 |
45 | 47 | #define switch_tls switch_tls_v6
|
46 | 48 | #elif defined(CONFIG_CPU_32v6K)
|
47 | 49 | #define tls_emu 0
|
48 | 50 | #define has_tls_reg 1
|
| 51 | +#define defer_tls_reg_update 1 |
49 | 52 | #define switch_tls switch_tls_v6k
|
50 | 53 | #else
|
51 | 54 | #define tls_emu 0
|
52 | 55 | #define has_tls_reg 0
|
| 56 | +#define defer_tls_reg_update 0 |
53 | 57 | #define switch_tls switch_tls_software
|
54 | 58 | #endif
|
55 | 59 |
|
@@ -77,7 +81,7 @@ static inline void set_tls(unsigned long val)
|
77 | 81 | */
|
78 | 82 | barrier();
|
79 | 83 |
|
80 |
| - if (!tls_emu) { |
| 84 | + if (!tls_emu && !defer_tls_reg_update) { |
81 | 85 | if (has_tls_reg) {
|
82 | 86 | asm("mcr p15, 0, %0, c13, c0, 3"
|
83 | 87 | : : "r" (val));
|
|
0 commit comments