diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-31 11:10:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-31 11:10:38 -0400 |
commit | 41ec793d2b9bdd6911d4ad8b7378165aba8424d5 (patch) | |
tree | fc08c6afb277280f0ec44c79696b3f63fdd50a82 | |
parent | 04ed7d9c78c7497146eb760377d031ffd1c91fb5 (diff) | |
parent | 6127d124ee4eb9c39983813cc9803f3654ab7e16 (diff) |
Merge branch 'fixes' of git://git.armlinux.org.uk/~rmk/linux-arm
Pull ARM fixes from Russell King:
"A fix for a regression on ARMv4T CPUs, and wiring up the new pkey
syscalls for ARM"
* 'fixes' of git://git.armlinux.org.uk/~rmk/linux-arm:
ARM: wire up new pkey syscalls
ARM: fix oops when using older ARMv4T CPUs
-rw-r--r-- | arch/arm/include/asm/unistd.h | 2 | ||||
-rw-r--r-- | arch/arm/include/uapi/asm/unistd.h | 3 | ||||
-rw-r--r-- | arch/arm/kernel/calls.S | 3 | ||||
-rw-r--r-- | arch/arm/mm/abort-lv4t.S | 34 |
4 files changed, 31 insertions, 11 deletions
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h index 194b69923389..ada0d29a660f 100644 --- a/arch/arm/include/asm/unistd.h +++ b/arch/arm/include/asm/unistd.h | |||
@@ -19,7 +19,7 @@ | |||
19 | * This may need to be greater than __NR_last_syscall+1 in order to | 19 | * This may need to be greater than __NR_last_syscall+1 in order to |
20 | * account for the padding in the syscall table | 20 | * account for the padding in the syscall table |
21 | */ | 21 | */ |
22 | #define __NR_syscalls (396) | 22 | #define __NR_syscalls (400) |
23 | 23 | ||
24 | #define __ARCH_WANT_STAT64 | 24 | #define __ARCH_WANT_STAT64 |
25 | #define __ARCH_WANT_SYS_GETHOSTNAME | 25 | #define __ARCH_WANT_SYS_GETHOSTNAME |
diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h index 2cb9dc770e1d..314100a06ccb 100644 --- a/arch/arm/include/uapi/asm/unistd.h +++ b/arch/arm/include/uapi/asm/unistd.h | |||
@@ -420,6 +420,9 @@ | |||
420 | #define __NR_copy_file_range (__NR_SYSCALL_BASE+391) | 420 | #define __NR_copy_file_range (__NR_SYSCALL_BASE+391) |
421 | #define __NR_preadv2 (__NR_SYSCALL_BASE+392) | 421 | #define __NR_preadv2 (__NR_SYSCALL_BASE+392) |
422 | #define __NR_pwritev2 (__NR_SYSCALL_BASE+393) | 422 | #define __NR_pwritev2 (__NR_SYSCALL_BASE+393) |
423 | #define __NR_pkey_mprotect (__NR_SYSCALL_BASE+394) | ||
424 | #define __NR_pkey_alloc (__NR_SYSCALL_BASE+395) | ||
425 | #define __NR_pkey_free (__NR_SYSCALL_BASE+396) | ||
423 | 426 | ||
424 | /* | 427 | /* |
425 | * The following SWIs are ARM private. | 428 | * The following SWIs are ARM private. |
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index 703fa0f3cd8f..08030b18f10a 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S | |||
@@ -403,6 +403,9 @@ | |||
403 | CALL(sys_copy_file_range) | 403 | CALL(sys_copy_file_range) |
404 | CALL(sys_preadv2) | 404 | CALL(sys_preadv2) |
405 | CALL(sys_pwritev2) | 405 | CALL(sys_pwritev2) |
406 | CALL(sys_pkey_mprotect) | ||
407 | /* 395 */ CALL(sys_pkey_alloc) | ||
408 | CALL(sys_pkey_free) | ||
406 | #ifndef syscalls_counted | 409 | #ifndef syscalls_counted |
407 | .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls | 410 | .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls |
408 | #define syscalls_counted | 411 | #define syscalls_counted |
diff --git a/arch/arm/mm/abort-lv4t.S b/arch/arm/mm/abort-lv4t.S index 6d8e8e3365d1..4cdfab31a0b6 100644 --- a/arch/arm/mm/abort-lv4t.S +++ b/arch/arm/mm/abort-lv4t.S | |||
@@ -7,7 +7,7 @@ | |||
7 | * : r4 = aborted context pc | 7 | * : r4 = aborted context pc |
8 | * : r5 = aborted context psr | 8 | * : r5 = aborted context psr |
9 | * | 9 | * |
10 | * Returns : r4-r5, r10-r11, r13 preserved | 10 | * Returns : r4-r5, r9-r11, r13 preserved |
11 | * | 11 | * |
12 | * Purpose : obtain information about current aborted instruction. | 12 | * Purpose : obtain information about current aborted instruction. |
13 | * Note: we read user space. This means we might cause a data | 13 | * Note: we read user space. This means we might cause a data |
@@ -48,7 +48,10 @@ ENTRY(v4t_late_abort) | |||
48 | /* c */ b do_DataAbort @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m | 48 | /* c */ b do_DataAbort @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m |
49 | /* d */ b do_DataAbort @ ldc rd, [rn, #m] | 49 | /* d */ b do_DataAbort @ ldc rd, [rn, #m] |
50 | /* e */ b .data_unknown | 50 | /* e */ b .data_unknown |
51 | /* f */ | 51 | /* f */ b .data_unknown |
52 | |||
53 | .data_unknown_r9: | ||
54 | ldr r9, [sp], #4 | ||
52 | .data_unknown: @ Part of jumptable | 55 | .data_unknown: @ Part of jumptable |
53 | mov r0, r4 | 56 | mov r0, r4 |
54 | mov r1, r8 | 57 | mov r1, r8 |
@@ -57,6 +60,7 @@ ENTRY(v4t_late_abort) | |||
57 | .data_arm_ldmstm: | 60 | .data_arm_ldmstm: |
58 | tst r8, #1 << 21 @ check writeback bit | 61 | tst r8, #1 << 21 @ check writeback bit |
59 | beq do_DataAbort @ no writeback -> no fixup | 62 | beq do_DataAbort @ no writeback -> no fixup |
63 | str r9, [sp, #-4]! | ||
60 | mov r7, #0x11 | 64 | mov r7, #0x11 |
61 | orr r7, r7, #0x1100 | 65 | orr r7, r7, #0x1100 |
62 | and r6, r8, r7 | 66 | and r6, r8, r7 |
@@ -75,12 +79,14 @@ ENTRY(v4t_late_abort) | |||
75 | subne r7, r7, r6, lsl #2 @ Undo increment | 79 | subne r7, r7, r6, lsl #2 @ Undo increment |
76 | addeq r7, r7, r6, lsl #2 @ Undo decrement | 80 | addeq r7, r7, r6, lsl #2 @ Undo decrement |
77 | str r7, [r2, r9, lsr #14] @ Put register 'Rn' | 81 | str r7, [r2, r9, lsr #14] @ Put register 'Rn' |
82 | ldr r9, [sp], #4 | ||
78 | b do_DataAbort | 83 | b do_DataAbort |
79 | 84 | ||
80 | .data_arm_lateldrhpre: | 85 | .data_arm_lateldrhpre: |
81 | tst r8, #1 << 21 @ Check writeback bit | 86 | tst r8, #1 << 21 @ Check writeback bit |
82 | beq do_DataAbort @ No writeback -> no fixup | 87 | beq do_DataAbort @ No writeback -> no fixup |
83 | .data_arm_lateldrhpost: | 88 | .data_arm_lateldrhpost: |
89 | str r9, [sp, #-4]! | ||
84 | and r9, r8, #0x00f @ get Rm / low nibble of immediate value | 90 | and r9, r8, #0x00f @ get Rm / low nibble of immediate value |
85 | tst r8, #1 << 22 @ if (immediate offset) | 91 | tst r8, #1 << 22 @ if (immediate offset) |
86 | andne r6, r8, #0xf00 @ { immediate high nibble | 92 | andne r6, r8, #0xf00 @ { immediate high nibble |
@@ -93,6 +99,7 @@ ENTRY(v4t_late_abort) | |||
93 | subne r7, r7, r6 @ Undo incrmenet | 99 | subne r7, r7, r6 @ Undo incrmenet |
94 | addeq r7, r7, r6 @ Undo decrement | 100 | addeq r7, r7, r6 @ Undo decrement |
95 | str r7, [r2, r9, lsr #14] @ Put register 'Rn' | 101 | str r7, [r2, r9, lsr #14] @ Put register 'Rn' |
102 | ldr r9, [sp], #4 | ||
96 | b do_DataAbort | 103 | b do_DataAbort |
97 | 104 | ||
98 | .data_arm_lateldrpreconst: | 105 | .data_arm_lateldrpreconst: |
@@ -101,12 +108,14 @@ ENTRY(v4t_late_abort) | |||
101 | .data_arm_lateldrpostconst: | 108 | .data_arm_lateldrpostconst: |
102 | movs r6, r8, lsl #20 @ Get offset | 109 | movs r6, r8, lsl #20 @ Get offset |
103 | beq do_DataAbort @ zero -> no fixup | 110 | beq do_DataAbort @ zero -> no fixup |
111 | str r9, [sp, #-4]! | ||
104 | and r9, r8, #15 << 16 @ Extract 'n' from instruction | 112 | and r9, r8, #15 << 16 @ Extract 'n' from instruction |
105 | ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' | 113 | ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' |
106 | tst r8, #1 << 23 @ Check U bit | 114 | tst r8, #1 << 23 @ Check U bit |
107 | subne r7, r7, r6, lsr #20 @ Undo increment | 115 | subne r7, r7, r6, lsr #20 @ Undo increment |
108 | addeq r7, r7, r6, lsr #20 @ Undo decrement | 116 | addeq r7, r7, r6, lsr #20 @ Undo decrement |
109 | str r7, [r2, r9, lsr #14] @ Put register 'Rn' | 117 | str r7, [r2, r9, lsr #14] @ Put register 'Rn' |
118 | ldr r9, [sp], #4 | ||
110 | b do_DataAbort | 119 | b do_DataAbort |
111 | 120 | ||
112 | .data_arm_lateldrprereg: | 121 | .data_arm_lateldrprereg: |
@@ -115,6 +124,7 @@ ENTRY(v4t_late_abort) | |||
115 | .data_arm_lateldrpostreg: | 124 | .data_arm_lateldrpostreg: |
116 | and r7, r8, #15 @ Extract 'm' from instruction | 125 | and r7, r8, #15 @ Extract 'm' from instruction |
117 | ldr r6, [r2, r7, lsl #2] @ Get register 'Rm' | 126 | ldr r6, [r2, r7, lsl #2] @ Get register 'Rm' |
127 | str r9, [sp, #-4]! | ||
118 | mov r9, r8, lsr #7 @ get shift count | 128 | mov r9, r8, lsr #7 @ get shift count |
119 | ands r9, r9, #31 | 129 | ands r9, r9, #31 |
120 | and r7, r8, #0x70 @ get shift type | 130 | and r7, r8, #0x70 @ get shift type |
@@ -126,33 +136,33 @@ ENTRY(v4t_late_abort) | |||
126 | b .data_arm_apply_r6_and_rn | 136 | b .data_arm_apply_r6_and_rn |
127 | b .data_arm_apply_r6_and_rn @ 1: LSL #0 | 137 | b .data_arm_apply_r6_and_rn @ 1: LSL #0 |
128 | nop | 138 | nop |
129 | b .data_unknown @ 2: MUL? | 139 | b .data_unknown_r9 @ 2: MUL? |
130 | nop | 140 | nop |
131 | b .data_unknown @ 3: MUL? | 141 | b .data_unknown_r9 @ 3: MUL? |
132 | nop | 142 | nop |
133 | mov r6, r6, lsr r9 @ 4: LSR #!0 | 143 | mov r6, r6, lsr r9 @ 4: LSR #!0 |
134 | b .data_arm_apply_r6_and_rn | 144 | b .data_arm_apply_r6_and_rn |
135 | mov r6, r6, lsr #32 @ 5: LSR #32 | 145 | mov r6, r6, lsr #32 @ 5: LSR #32 |
136 | b .data_arm_apply_r6_and_rn | 146 | b .data_arm_apply_r6_and_rn |
137 | b .data_unknown @ 6: MUL? | 147 | b .data_unknown_r9 @ 6: MUL? |
138 | nop | 148 | nop |
139 | b .data_unknown @ 7: MUL? | 149 | b .data_unknown_r9 @ 7: MUL? |
140 | nop | 150 | nop |
141 | mov r6, r6, asr r9 @ 8: ASR #!0 | 151 | mov r6, r6, asr r9 @ 8: ASR #!0 |
142 | b .data_arm_apply_r6_and_rn | 152 | b .data_arm_apply_r6_and_rn |
143 | mov r6, r6, asr #32 @ 9: ASR #32 | 153 | mov r6, r6, asr #32 @ 9: ASR #32 |
144 | b .data_arm_apply_r6_and_rn | 154 | b .data_arm_apply_r6_and_rn |
145 | b .data_unknown @ A: MUL? | 155 | b .data_unknown_r9 @ A: MUL? |
146 | nop | 156 | nop |
147 | b .data_unknown @ B: MUL? | 157 | b .data_unknown_r9 @ B: MUL? |
148 | nop | 158 | nop |
149 | mov r6, r6, ror r9 @ C: ROR #!0 | 159 | mov r6, r6, ror r9 @ C: ROR #!0 |
150 | b .data_arm_apply_r6_and_rn | 160 | b .data_arm_apply_r6_and_rn |
151 | mov r6, r6, rrx @ D: RRX | 161 | mov r6, r6, rrx @ D: RRX |
152 | b .data_arm_apply_r6_and_rn | 162 | b .data_arm_apply_r6_and_rn |
153 | b .data_unknown @ E: MUL? | 163 | b .data_unknown_r9 @ E: MUL? |
154 | nop | 164 | nop |
155 | b .data_unknown @ F: MUL? | 165 | b .data_unknown_r9 @ F: MUL? |
156 | 166 | ||
157 | .data_thumb_abort: | 167 | .data_thumb_abort: |
158 | ldrh r8, [r4] @ read instruction | 168 | ldrh r8, [r4] @ read instruction |
@@ -190,6 +200,7 @@ ENTRY(v4t_late_abort) | |||
190 | .data_thumb_pushpop: | 200 | .data_thumb_pushpop: |
191 | tst r8, #1 << 10 | 201 | tst r8, #1 << 10 |
192 | beq .data_unknown | 202 | beq .data_unknown |
203 | str r9, [sp, #-4]! | ||
193 | and r6, r8, #0x55 @ hweight8(r8) + R bit | 204 | and r6, r8, #0x55 @ hweight8(r8) + R bit |
194 | and r9, r8, #0xaa | 205 | and r9, r8, #0xaa |
195 | add r6, r6, r9, lsr #1 | 206 | add r6, r6, r9, lsr #1 |
@@ -204,9 +215,11 @@ ENTRY(v4t_late_abort) | |||
204 | addeq r7, r7, r6, lsl #2 @ increment SP if PUSH | 215 | addeq r7, r7, r6, lsl #2 @ increment SP if PUSH |
205 | subne r7, r7, r6, lsl #2 @ decrement SP if POP | 216 | subne r7, r7, r6, lsl #2 @ decrement SP if POP |
206 | str r7, [r2, #13 << 2] | 217 | str r7, [r2, #13 << 2] |
218 | ldr r9, [sp], #4 | ||
207 | b do_DataAbort | 219 | b do_DataAbort |
208 | 220 | ||
209 | .data_thumb_ldmstm: | 221 | .data_thumb_ldmstm: |
222 | str r9, [sp, #-4]! | ||
210 | and r6, r8, #0x55 @ hweight8(r8) | 223 | and r6, r8, #0x55 @ hweight8(r8) |
211 | and r9, r8, #0xaa | 224 | and r9, r8, #0xaa |
212 | add r6, r6, r9, lsr #1 | 225 | add r6, r6, r9, lsr #1 |
@@ -219,4 +232,5 @@ ENTRY(v4t_late_abort) | |||
219 | and r6, r6, #15 @ number of regs to transfer | 232 | and r6, r6, #15 @ number of regs to transfer |
220 | sub r7, r7, r6, lsl #2 @ always decrement | 233 | sub r7, r7, r6, lsl #2 @ always decrement |
221 | str r7, [r2, r9, lsr #6] | 234 | str r7, [r2, r9, lsr #6] |
235 | ldr r9, [sp], #4 | ||
222 | b do_DataAbort | 236 | b do_DataAbort |