diff options
author | Mark Rutland <mark.rutland@arm.com> | 2019-10-04 15:58:47 +0200 |
---|---|---|
committer | Will Deacon <will@kernel.org> | 2019-10-07 12:07:16 +0200 |
commit | 308c51561720547a90767a2f367f5390052c51da (patch) | |
tree | c5e7be82f4129fe1a8893e903fa3605f6bff5978 | |
parent | arm64: ftrace: Ensure synchronisation in PLT setup for Neoverse-N1 #1542419 (diff) | |
download | linux-308c51561720547a90767a2f367f5390052c51da.tar.xz linux-308c51561720547a90767a2f367f5390052c51da.zip |
arm64: mm: fix spurious fault detection
When detecting a spurious EL1 translation fault, we attempt to compare
ESR_EL1.DFSC with PAR_EL1.FST. We erroneously use FIELD_PREP() to
extract PAR_EL1.FST, when we should be using FIELD_GET().
In the wise words of Robin Murphy:
| FIELD_GET() is a UBFX, FIELD_PREP() is a BFI
Using FIELD_PREP() means that that dfsc & ESR_ELx_FSC_TYPE is always
zero, and hence not equal to ESR_ELx_FSC_FAULT. Thus we detect any
unhandled translation fault as spurious.
... so let's use FIELD_GET() to ensure we don't decide all translation
faults are spurious. ESR_EL1.DFSC occupies bits [5:0], and requires no
shifting.
Fixes: 42f91093b043332a ("arm64: mm: Ignore spurious translation faults taken from the kernel")
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reported-by: Robin Murphy <robin.murphy@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Will Deacon <will.deacon@kernel.org>
Signed-off-by: Will Deacon <will@kernel.org>
-rw-r--r-- | arch/arm64/mm/fault.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 6acd866f31fd..855f2a7954e6 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -275,7 +275,7 @@ static bool __kprobes is_spurious_el1_translation_fault(unsigned long addr, * If we got a different type of fault from the AT instruction, * treat the translation fault as spurious. */ - dfsc = FIELD_PREP(SYS_PAR_EL1_FST, par); + dfsc = FIELD_GET(SYS_PAR_EL1_FST, par); return (dfsc & ESR_ELx_FSC_TYPE) != ESR_ELx_FSC_FAULT; } |