diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2015-08-20 05:32:02 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2015-08-26 15:27:02 -0400 |
commit | 2190fed67ba6f3e8129513929f2395843645e928 (patch) | |
tree | 45a4db5061c12e2926f7a1c89d56c7bbf47f0e61 | |
parent | aa06e5c1f9c2b466712be904cc5b56a813e24cfd (diff) |
ARM: entry: provide uaccess assembly macro hooks
Provide hooks into the kernel entry and exit paths to permit control
of userspace visibility to the kernel. The intended use is:
- on entry to kernel from user, uaccess_disable will be called to
disable userspace visibility
- on exit from kernel to user, uaccess_enable will be called to
enable userspace visibility
- on entry from a kernel exception, uaccess_save_and_disable will be
called to save the current userspace visibility setting, and disable
access
- on exit from a kernel exception, uaccess_restore will be called to
restore the userspace visibility as it was before the exception
occurred.
These hooks allows us to keep userspace visibility disabled for the
vast majority of the kernel, except for localised regions where we
want to explicitly access userspace.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | arch/arm/include/asm/assembler.h | 17 | ||||
-rw-r--r-- | arch/arm/kernel/entry-armv.S | 30 | ||||
-rw-r--r-- | arch/arm/kernel/entry-common.S | 2 | ||||
-rw-r--r-- | arch/arm/kernel/entry-header.S | 3 | ||||
-rw-r--r-- | arch/arm/mm/abort-ev4.S | 1 | ||||
-rw-r--r-- | arch/arm/mm/abort-ev5t.S | 1 | ||||
-rw-r--r-- | arch/arm/mm/abort-ev5tj.S | 1 | ||||
-rw-r--r-- | arch/arm/mm/abort-ev6.S | 7 | ||||
-rw-r--r-- | arch/arm/mm/abort-ev7.S | 1 | ||||
-rw-r--r-- | arch/arm/mm/abort-lv4t.S | 2 | ||||
-rw-r--r-- | arch/arm/mm/abort-macro.S | 1 |
11 files changed, 55 insertions, 11 deletions
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 4abe57279c66..a91177043467 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h | |||
@@ -445,6 +445,23 @@ THUMB( orr \reg , \reg , #PSR_T_BIT ) | |||
445 | #endif | 445 | #endif |
446 | .endm | 446 | .endm |
447 | 447 | ||
448 | .macro uaccess_disable, tmp, isb=1 | ||
449 | .endm | ||
450 | |||
451 | .macro uaccess_enable, tmp, isb=1 | ||
452 | .endm | ||
453 | |||
454 | .macro uaccess_save, tmp | ||
455 | .endm | ||
456 | |||
457 | .macro uaccess_restore | ||
458 | .endm | ||
459 | |||
460 | .macro uaccess_save_and_disable, tmp | ||
461 | uaccess_save \tmp | ||
462 | uaccess_disable \tmp | ||
463 | .endm | ||
464 | |||
448 | .irp c,,eq,ne,cs,cc,mi,pl,vs,vc,hi,ls,ge,lt,gt,le,hs,lo | 465 | .irp c,,eq,ne,cs,cc,mi,pl,vs,vc,hi,ls,ge,lt,gt,le,hs,lo |
449 | .macro ret\c, reg | 466 | .macro ret\c, reg |
450 | #if __LINUX_ARM_ARCH__ < 6 | 467 | #if __LINUX_ARM_ARCH__ < 6 |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index d19adcf6c580..61f00a3f3047 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -149,10 +149,10 @@ ENDPROC(__und_invalid) | |||
149 | #define SPFIX(code...) | 149 | #define SPFIX(code...) |
150 | #endif | 150 | #endif |
151 | 151 | ||
152 | .macro svc_entry, stack_hole=0, trace=1 | 152 | .macro svc_entry, stack_hole=0, trace=1, uaccess=1 |
153 | UNWIND(.fnstart ) | 153 | UNWIND(.fnstart ) |
154 | UNWIND(.save {r0 - pc} ) | 154 | UNWIND(.save {r0 - pc} ) |
155 | sub sp, sp, #(S_FRAME_SIZE + \stack_hole - 4) | 155 | sub sp, sp, #(S_FRAME_SIZE + 8 + \stack_hole - 4) |
156 | #ifdef CONFIG_THUMB2_KERNEL | 156 | #ifdef CONFIG_THUMB2_KERNEL |
157 | SPFIX( str r0, [sp] ) @ temporarily saved | 157 | SPFIX( str r0, [sp] ) @ temporarily saved |
158 | SPFIX( mov r0, sp ) | 158 | SPFIX( mov r0, sp ) |
@@ -167,7 +167,7 @@ ENDPROC(__und_invalid) | |||
167 | ldmia r0, {r3 - r5} | 167 | ldmia r0, {r3 - r5} |
168 | add r7, sp, #S_SP - 4 @ here for interlock avoidance | 168 | add r7, sp, #S_SP - 4 @ here for interlock avoidance |
169 | mov r6, #-1 @ "" "" "" "" | 169 | mov r6, #-1 @ "" "" "" "" |
170 | add r2, sp, #(S_FRAME_SIZE + \stack_hole - 4) | 170 | add r2, sp, #(S_FRAME_SIZE + 8 + \stack_hole - 4) |
171 | SPFIX( addeq r2, r2, #4 ) | 171 | SPFIX( addeq r2, r2, #4 ) |
172 | str r3, [sp, #-4]! @ save the "real" r0 copied | 172 | str r3, [sp, #-4]! @ save the "real" r0 copied |
173 | @ from the exception stack | 173 | @ from the exception stack |
@@ -185,6 +185,11 @@ ENDPROC(__und_invalid) | |||
185 | @ | 185 | @ |
186 | stmia r7, {r2 - r6} | 186 | stmia r7, {r2 - r6} |
187 | 187 | ||
188 | uaccess_save r0 | ||
189 | .if \uaccess | ||
190 | uaccess_disable r0 | ||
191 | .endif | ||
192 | |||
188 | .if \trace | 193 | .if \trace |
189 | #ifdef CONFIG_TRACE_IRQFLAGS | 194 | #ifdef CONFIG_TRACE_IRQFLAGS |
190 | bl trace_hardirqs_off | 195 | bl trace_hardirqs_off |
@@ -194,7 +199,7 @@ ENDPROC(__und_invalid) | |||
194 | 199 | ||
195 | .align 5 | 200 | .align 5 |
196 | __dabt_svc: | 201 | __dabt_svc: |
197 | svc_entry | 202 | svc_entry uaccess=0 |
198 | mov r2, sp | 203 | mov r2, sp |
199 | dabt_helper | 204 | dabt_helper |
200 | THUMB( ldr r5, [sp, #S_PSR] ) @ potentially updated CPSR | 205 | THUMB( ldr r5, [sp, #S_PSR] ) @ potentially updated CPSR |
@@ -368,7 +373,7 @@ ENDPROC(__fiq_abt) | |||
368 | #error "sizeof(struct pt_regs) must be a multiple of 8" | 373 | #error "sizeof(struct pt_regs) must be a multiple of 8" |
369 | #endif | 374 | #endif |
370 | 375 | ||
371 | .macro usr_entry, trace=1 | 376 | .macro usr_entry, trace=1, uaccess=1 |
372 | UNWIND(.fnstart ) | 377 | UNWIND(.fnstart ) |
373 | UNWIND(.cantunwind ) @ don't unwind the user space | 378 | UNWIND(.cantunwind ) @ don't unwind the user space |
374 | sub sp, sp, #S_FRAME_SIZE | 379 | sub sp, sp, #S_FRAME_SIZE |
@@ -400,6 +405,10 @@ ENDPROC(__fiq_abt) | |||
400 | ARM( stmdb r0, {sp, lr}^ ) | 405 | ARM( stmdb r0, {sp, lr}^ ) |
401 | THUMB( store_user_sp_lr r0, r1, S_SP - S_PC ) | 406 | THUMB( store_user_sp_lr r0, r1, S_SP - S_PC ) |
402 | 407 | ||
408 | .if \uaccess | ||
409 | uaccess_disable ip | ||
410 | .endif | ||
411 | |||
403 | @ Enable the alignment trap while in kernel mode | 412 | @ Enable the alignment trap while in kernel mode |
404 | ATRAP( teq r8, r7) | 413 | ATRAP( teq r8, r7) |
405 | ATRAP( mcrne p15, 0, r8, c1, c0, 0) | 414 | ATRAP( mcrne p15, 0, r8, c1, c0, 0) |
@@ -435,7 +444,7 @@ ENDPROC(__fiq_abt) | |||
435 | 444 | ||
436 | .align 5 | 445 | .align 5 |
437 | __dabt_usr: | 446 | __dabt_usr: |
438 | usr_entry | 447 | usr_entry uaccess=0 |
439 | kuser_cmpxchg_check | 448 | kuser_cmpxchg_check |
440 | mov r2, sp | 449 | mov r2, sp |
441 | dabt_helper | 450 | dabt_helper |
@@ -458,7 +467,7 @@ ENDPROC(__irq_usr) | |||
458 | 467 | ||
459 | .align 5 | 468 | .align 5 |
460 | __und_usr: | 469 | __und_usr: |
461 | usr_entry | 470 | usr_entry uaccess=0 |
462 | 471 | ||
463 | mov r2, r4 | 472 | mov r2, r4 |
464 | mov r3, r5 | 473 | mov r3, r5 |
@@ -484,6 +493,8 @@ __und_usr: | |||
484 | 1: ldrt r0, [r4] | 493 | 1: ldrt r0, [r4] |
485 | ARM_BE8(rev r0, r0) @ little endian instruction | 494 | ARM_BE8(rev r0, r0) @ little endian instruction |
486 | 495 | ||
496 | uaccess_disable ip | ||
497 | |||
487 | @ r0 = 32-bit ARM instruction which caused the exception | 498 | @ r0 = 32-bit ARM instruction which caused the exception |
488 | @ r2 = PC value for the following instruction (:= regs->ARM_pc) | 499 | @ r2 = PC value for the following instruction (:= regs->ARM_pc) |
489 | @ r4 = PC value for the faulting instruction | 500 | @ r4 = PC value for the faulting instruction |
@@ -518,9 +529,10 @@ __und_usr_thumb: | |||
518 | 2: ldrht r5, [r4] | 529 | 2: ldrht r5, [r4] |
519 | ARM_BE8(rev16 r5, r5) @ little endian instruction | 530 | ARM_BE8(rev16 r5, r5) @ little endian instruction |
520 | cmp r5, #0xe800 @ 32bit instruction if xx != 0 | 531 | cmp r5, #0xe800 @ 32bit instruction if xx != 0 |
521 | blo __und_usr_fault_16 @ 16bit undefined instruction | 532 | blo __und_usr_fault_16_pan @ 16bit undefined instruction |
522 | 3: ldrht r0, [r2] | 533 | 3: ldrht r0, [r2] |
523 | ARM_BE8(rev16 r0, r0) @ little endian instruction | 534 | ARM_BE8(rev16 r0, r0) @ little endian instruction |
535 | uaccess_disable ip | ||
524 | add r2, r2, #2 @ r2 is PC + 2, make it PC + 4 | 536 | add r2, r2, #2 @ r2 is PC + 2, make it PC + 4 |
525 | str r2, [sp, #S_PC] @ it's a 2x16bit instr, update | 537 | str r2, [sp, #S_PC] @ it's a 2x16bit instr, update |
526 | orr r0, r0, r5, lsl #16 | 538 | orr r0, r0, r5, lsl #16 |
@@ -715,6 +727,8 @@ ENDPROC(no_fp) | |||
715 | __und_usr_fault_32: | 727 | __und_usr_fault_32: |
716 | mov r1, #4 | 728 | mov r1, #4 |
717 | b 1f | 729 | b 1f |
730 | __und_usr_fault_16_pan: | ||
731 | uaccess_disable ip | ||
718 | __und_usr_fault_16: | 732 | __und_usr_fault_16: |
719 | mov r1, #2 | 733 | mov r1, #2 |
720 | 1: mov r0, sp | 734 | 1: mov r0, sp |
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 92828a1dec80..189154980703 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
@@ -173,6 +173,8 @@ ENTRY(vector_swi) | |||
173 | USER( ldr scno, [lr, #-4] ) @ get SWI instruction | 173 | USER( ldr scno, [lr, #-4] ) @ get SWI instruction |
174 | #endif | 174 | #endif |
175 | 175 | ||
176 | uaccess_disable tbl | ||
177 | |||
176 | adr tbl, sys_call_table @ load syscall table pointer | 178 | adr tbl, sys_call_table @ load syscall table pointer |
177 | 179 | ||
178 | #if defined(CONFIG_OABI_COMPAT) | 180 | #if defined(CONFIG_OABI_COMPAT) |
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index d47b5161b029..0d22ad206d52 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S | |||
@@ -215,6 +215,7 @@ | |||
215 | blne trace_hardirqs_off | 215 | blne trace_hardirqs_off |
216 | #endif | 216 | #endif |
217 | .endif | 217 | .endif |
218 | uaccess_restore | ||
218 | 219 | ||
219 | #ifndef CONFIG_THUMB2_KERNEL | 220 | #ifndef CONFIG_THUMB2_KERNEL |
220 | @ ARM mode SVC restore | 221 | @ ARM mode SVC restore |
@@ -258,6 +259,7 @@ | |||
258 | @ on the stack remains correct). | 259 | @ on the stack remains correct). |
259 | @ | 260 | @ |
260 | .macro svc_exit_via_fiq | 261 | .macro svc_exit_via_fiq |
262 | uaccess_restore | ||
261 | #ifndef CONFIG_THUMB2_KERNEL | 263 | #ifndef CONFIG_THUMB2_KERNEL |
262 | @ ARM mode restore | 264 | @ ARM mode restore |
263 | mov r0, sp | 265 | mov r0, sp |
@@ -287,6 +289,7 @@ | |||
287 | 289 | ||
288 | 290 | ||
289 | .macro restore_user_regs, fast = 0, offset = 0 | 291 | .macro restore_user_regs, fast = 0, offset = 0 |
292 | uaccess_enable r1, isb=0 | ||
290 | #ifndef CONFIG_THUMB2_KERNEL | 293 | #ifndef CONFIG_THUMB2_KERNEL |
291 | @ ARM mode restore | 294 | @ ARM mode restore |
292 | mov r2, sp | 295 | mov r2, sp |
diff --git a/arch/arm/mm/abort-ev4.S b/arch/arm/mm/abort-ev4.S index 54473cd4aba9..b3b31e30cadd 100644 --- a/arch/arm/mm/abort-ev4.S +++ b/arch/arm/mm/abort-ev4.S | |||
@@ -19,6 +19,7 @@ ENTRY(v4_early_abort) | |||
19 | mrc p15, 0, r1, c5, c0, 0 @ get FSR | 19 | mrc p15, 0, r1, c5, c0, 0 @ get FSR |
20 | mrc p15, 0, r0, c6, c0, 0 @ get FAR | 20 | mrc p15, 0, r0, c6, c0, 0 @ get FAR |
21 | ldr r3, [r4] @ read aborted ARM instruction | 21 | ldr r3, [r4] @ read aborted ARM instruction |
22 | uaccess_disable ip @ disable userspace access | ||
22 | bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR | 23 | bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR |
23 | tst r3, #1 << 20 @ L = 1 -> write? | 24 | tst r3, #1 << 20 @ L = 1 -> write? |
24 | orreq r1, r1, #1 << 11 @ yes. | 25 | orreq r1, r1, #1 << 11 @ yes. |
diff --git a/arch/arm/mm/abort-ev5t.S b/arch/arm/mm/abort-ev5t.S index c913031b79cc..a6a381a6caa5 100644 --- a/arch/arm/mm/abort-ev5t.S +++ b/arch/arm/mm/abort-ev5t.S | |||
@@ -21,6 +21,7 @@ ENTRY(v5t_early_abort) | |||
21 | mrc p15, 0, r0, c6, c0, 0 @ get FAR | 21 | mrc p15, 0, r0, c6, c0, 0 @ get FAR |
22 | do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3 | 22 | do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3 |
23 | ldreq r3, [r4] @ read aborted ARM instruction | 23 | ldreq r3, [r4] @ read aborted ARM instruction |
24 | uaccess_disable ip @ disable user access | ||
24 | bic r1, r1, #1 << 11 @ clear bits 11 of FSR | 25 | bic r1, r1, #1 << 11 @ clear bits 11 of FSR |
25 | teq_ldrd tmp=ip, insn=r3 @ insn was LDRD? | 26 | teq_ldrd tmp=ip, insn=r3 @ insn was LDRD? |
26 | beq do_DataAbort @ yes | 27 | beq do_DataAbort @ yes |
diff --git a/arch/arm/mm/abort-ev5tj.S b/arch/arm/mm/abort-ev5tj.S index 1b80d71adb0f..00ab011bef58 100644 --- a/arch/arm/mm/abort-ev5tj.S +++ b/arch/arm/mm/abort-ev5tj.S | |||
@@ -24,6 +24,7 @@ ENTRY(v5tj_early_abort) | |||
24 | bne do_DataAbort | 24 | bne do_DataAbort |
25 | do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3 | 25 | do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3 |
26 | ldreq r3, [r4] @ read aborted ARM instruction | 26 | ldreq r3, [r4] @ read aborted ARM instruction |
27 | uaccess_disable ip @ disable userspace access | ||
27 | teq_ldrd tmp=ip, insn=r3 @ insn was LDRD? | 28 | teq_ldrd tmp=ip, insn=r3 @ insn was LDRD? |
28 | beq do_DataAbort @ yes | 29 | beq do_DataAbort @ yes |
29 | tst r3, #1 << 20 @ L = 0 -> write | 30 | tst r3, #1 << 20 @ L = 0 -> write |
diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S index 113704f30e9f..8801a15aa105 100644 --- a/arch/arm/mm/abort-ev6.S +++ b/arch/arm/mm/abort-ev6.S | |||
@@ -26,17 +26,18 @@ ENTRY(v6_early_abort) | |||
26 | ldr ip, =0x4107b36 | 26 | ldr ip, =0x4107b36 |
27 | mrc p15, 0, r3, c0, c0, 0 @ get processor id | 27 | mrc p15, 0, r3, c0, c0, 0 @ get processor id |
28 | teq ip, r3, lsr #4 @ r0 ARM1136? | 28 | teq ip, r3, lsr #4 @ r0 ARM1136? |
29 | bne do_DataAbort | 29 | bne 1f |
30 | tst r5, #PSR_J_BIT @ Java? | 30 | tst r5, #PSR_J_BIT @ Java? |
31 | tsteq r5, #PSR_T_BIT @ Thumb? | 31 | tsteq r5, #PSR_T_BIT @ Thumb? |
32 | bne do_DataAbort | 32 | bne 1f |
33 | bic r1, r1, #1 << 11 @ clear bit 11 of FSR | 33 | bic r1, r1, #1 << 11 @ clear bit 11 of FSR |
34 | ldr r3, [r4] @ read aborted ARM instruction | 34 | ldr r3, [r4] @ read aborted ARM instruction |
35 | ARM_BE8(rev r3, r3) | 35 | ARM_BE8(rev r3, r3) |
36 | 36 | ||
37 | teq_ldrd tmp=ip, insn=r3 @ insn was LDRD? | 37 | teq_ldrd tmp=ip, insn=r3 @ insn was LDRD? |
38 | beq do_DataAbort @ yes | 38 | beq 1f @ yes |
39 | tst r3, #1 << 20 @ L = 0 -> write | 39 | tst r3, #1 << 20 @ L = 0 -> write |
40 | orreq r1, r1, #1 << 11 @ yes. | 40 | orreq r1, r1, #1 << 11 @ yes. |
41 | #endif | 41 | #endif |
42 | 1: uaccess_disable ip @ disable userspace access | ||
42 | b do_DataAbort | 43 | b do_DataAbort |
diff --git a/arch/arm/mm/abort-ev7.S b/arch/arm/mm/abort-ev7.S index 4812ad054214..e8d0e08c227f 100644 --- a/arch/arm/mm/abort-ev7.S +++ b/arch/arm/mm/abort-ev7.S | |||
@@ -15,6 +15,7 @@ | |||
15 | ENTRY(v7_early_abort) | 15 | ENTRY(v7_early_abort) |
16 | mrc p15, 0, r1, c5, c0, 0 @ get FSR | 16 | mrc p15, 0, r1, c5, c0, 0 @ get FSR |
17 | mrc p15, 0, r0, c6, c0, 0 @ get FAR | 17 | mrc p15, 0, r0, c6, c0, 0 @ get FAR |
18 | uaccess_disable ip @ disable userspace access | ||
18 | 19 | ||
19 | /* | 20 | /* |
20 | * V6 code adjusts the returned DFSR. | 21 | * V6 code adjusts the returned DFSR. |
diff --git a/arch/arm/mm/abort-lv4t.S b/arch/arm/mm/abort-lv4t.S index f3982580c273..6d8e8e3365d1 100644 --- a/arch/arm/mm/abort-lv4t.S +++ b/arch/arm/mm/abort-lv4t.S | |||
@@ -26,6 +26,7 @@ ENTRY(v4t_late_abort) | |||
26 | #endif | 26 | #endif |
27 | bne .data_thumb_abort | 27 | bne .data_thumb_abort |
28 | ldr r8, [r4] @ read arm instruction | 28 | ldr r8, [r4] @ read arm instruction |
29 | uaccess_disable ip @ disable userspace access | ||
29 | tst r8, #1 << 20 @ L = 1 -> write? | 30 | tst r8, #1 << 20 @ L = 1 -> write? |
30 | orreq r1, r1, #1 << 11 @ yes. | 31 | orreq r1, r1, #1 << 11 @ yes. |
31 | and r7, r8, #15 << 24 | 32 | and r7, r8, #15 << 24 |
@@ -155,6 +156,7 @@ ENTRY(v4t_late_abort) | |||
155 | 156 | ||
156 | .data_thumb_abort: | 157 | .data_thumb_abort: |
157 | ldrh r8, [r4] @ read instruction | 158 | ldrh r8, [r4] @ read instruction |
159 | uaccess_disable ip @ disable userspace access | ||
158 | tst r8, #1 << 11 @ L = 1 -> write? | 160 | tst r8, #1 << 11 @ L = 1 -> write? |
159 | orreq r1, r1, #1 << 8 @ yes | 161 | orreq r1, r1, #1 << 8 @ yes |
160 | and r7, r8, #15 << 12 | 162 | and r7, r8, #15 << 12 |
diff --git a/arch/arm/mm/abort-macro.S b/arch/arm/mm/abort-macro.S index 50d6c0a900b1..4509bee4e081 100644 --- a/arch/arm/mm/abort-macro.S +++ b/arch/arm/mm/abort-macro.S | |||
@@ -13,6 +13,7 @@ | |||
13 | tst \psr, #PSR_T_BIT | 13 | tst \psr, #PSR_T_BIT |
14 | beq not_thumb | 14 | beq not_thumb |
15 | ldrh \tmp, [\pc] @ Read aborted Thumb instruction | 15 | ldrh \tmp, [\pc] @ Read aborted Thumb instruction |
16 | uaccess_disable ip @ disable userspace access | ||
16 | and \tmp, \tmp, # 0xfe00 @ Mask opcode field | 17 | and \tmp, \tmp, # 0xfe00 @ Mask opcode field |
17 | cmp \tmp, # 0x5600 @ Is it ldrsb? | 18 | cmp \tmp, # 0x5600 @ Is it ldrsb? |
18 | orreq \tmp, \tmp, #1 << 11 @ Set L-bit if yes | 19 | orreq \tmp, \tmp, #1 << 11 @ Set L-bit if yes |