Commit 276e9327 authored by Kristina Martsenko's avatar Kristina Martsenko Committed by Catalin Marinas

arm64: entry: improve data abort handling of tagged pointers

When handling a data abort from EL0, we currently zero the top byte of
the faulting address, as we assume the address is a TTBR0 address, which
may contain a non-zero address tag. However, the address may be a TTBR1
address, in which case we should not zero the top byte. This patch fixes
that. The effect is that the full TTBR1 address is passed to the task's
signal handler (or printed out in the kernel log).

When handling a data abort from EL1, we leave the faulting address
intact, as we assume it's either a TTBR1 address or a TTBR0 address with
tag 0x00. This is true as far as I'm aware, we don't seem to access a
tagged TTBR0 address anywhere in the kernel. Regardless, it's easy to
forget about address tags, and code added in the future may not always
remember to remove tags from addresses before accessing them. So add tag
handling to the EL1 data abort handler as well. This also makes it
consistent with the EL0 data abort handler.

Fixes: d50240a5 ("arm64: mm: permit use of tagged pointers at EL0")
Cc: <stable@vger.kernel.org> # 3.12.x-
Reviewed-by: default avatarDave Martin <Dave.Martin@arm.com>
Acked-by: default avatarWill Deacon <will.deacon@arm.com>
Signed-off-by: default avatarKristina Martsenko <kristina.martsenko@arm.com>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 7dcd9dd8
...@@ -62,4 +62,13 @@ alternative_if ARM64_ALT_PAN_NOT_UAO ...@@ -62,4 +62,13 @@ alternative_if ARM64_ALT_PAN_NOT_UAO
alternative_else_nop_endif alternative_else_nop_endif
.endm .endm
/*
* Remove the address tag from a virtual address, if present.
*/
.macro clear_address_tag, dst, addr
tst \addr, #(1 << 55)
bic \dst, \addr, #(0xff << 56)
csel \dst, \dst, \addr, eq
.endm
#endif #endif
...@@ -428,12 +428,13 @@ el1_da: ...@@ -428,12 +428,13 @@ el1_da:
/* /*
* Data abort handling * Data abort handling
*/ */
mrs x0, far_el1 mrs x3, far_el1
enable_dbg enable_dbg
// re-enable interrupts if they were enabled in the aborted context // re-enable interrupts if they were enabled in the aborted context
tbnz x23, #7, 1f // PSR_I_BIT tbnz x23, #7, 1f // PSR_I_BIT
enable_irq enable_irq
1: 1:
clear_address_tag x0, x3
mov x2, sp // struct pt_regs mov x2, sp // struct pt_regs
bl do_mem_abort bl do_mem_abort
...@@ -594,7 +595,7 @@ el0_da: ...@@ -594,7 +595,7 @@ el0_da:
// enable interrupts before calling the main handler // enable interrupts before calling the main handler
enable_dbg_and_irq enable_dbg_and_irq
ct_user_exit ct_user_exit
bic x0, x26, #(0xff << 56) clear_address_tag x0, x26
mov x1, x25 mov x1, x25
mov x2, sp mov x2, sp
bl do_mem_abort bl do_mem_abort
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment