Message ID | 20191004135847.39326-1-mark.rutland@arm.com (mailing list archive) |
---|---|
State | Mainlined |
Commit | 308c51561720547a90767a2f367f5390052c51da |
Headers | show |
Series | arm64: mm: fix spurious fault detection | expand |
[Correcting Will's address] On Fri, Oct 04, 2019 at 02:58:47PM +0100, Mark Rutland wrote: > 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> Whoops, that should be <will@kernel.org>. Mark. > --- > arch/arm64/mm/fault.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c > index 115d7a0e4b08..b0074b91913b 100644 > --- a/arch/arm64/mm/fault.c > +++ b/arch/arm64/mm/fault.c > @@ -266,7 +266,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; > } > > -- > 2.11.0 > > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On 10/04/2019 07:28 PM, Mark Rutland wrote: > 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> > --- > arch/arm64/mm/fault.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c > index 115d7a0e4b08..b0074b91913b 100644 > --- a/arch/arm64/mm/fault.c > +++ b/arch/arm64/mm/fault.c > @@ -266,7 +266,7 @@ static bool __kprobes is_spurious_el1_translation_fault(unsigned long addr, A small nit, pt_regs pointer argument is not required and can be dropped. > * 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); FIELD_* functions are not getting used any where other drivers. Though this patch did not add that but just wondering why there are no non-driver use cases for these helpers. > return (dfsc & ESR_ELx_FSC_TYPE) != ESR_ELx_FSC_FAULT; > } > >
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 115d7a0e4b08..b0074b91913b 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -266,7 +266,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; }
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> --- arch/arm64/mm/fault.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)