linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] arm64: errata: Workaround Neoverse-N1 #1542419
@ 2019-10-02  9:49 James Morse
  2019-10-02  9:49 ` [PATCH 1/4] arm64: errata: Hide CTR_EL0.DIC on systems affected by " James Morse
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: James Morse @ 2019-10-02  9:49 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: Catalin Marinas, Will Deacon

Hello!

Neoverse-N1 cores with the 'COHERENT_ICACHE' feature may fetch stale
instructions when software depends on prefetch-speculation-protection
instead of explicit synchronization. [0]

This concerns self modifying executables, like a JIT ... and the kernel.
The ARM-ARM has some fairly heavy rules for software that modifies
instructions that may be currently executing on another CPU.
There are some easier requirements if the instructions being modified
are just between Branches and NOP, (and a few others).

(See B2.2.5 "Concurrent modification and execution of instructions"
of DDI0487E.a for details).


A JIT can use all this to avoid synchronisation between threads. It
can generate new instructions at some new location, then update a
branch in the executable instructions to point at the new location.

Prefetch-speculation-protection guarantees that if another CPU sees
the new branch, it also sees the new instructions that were written
there.

On affected Neoverse-N1 cores, this goes wrong.


The workaround is to trap I-Cache maintenance and issue an
inner-shareable TLBI.

The affected cores have a Coherent I-Cache, so the I-Cache maintenance
isn't necessary. The core tells user-space it can skip it with
CTR_EL0.DIC. We also have to trap this register to hide the bit forcing
DIC-aware user-space to perform the maintenance.

Because the cache-maintenance wasn't needed, we can do the TLBI instead.
In fact, the I-Cache line-size isn't relevant anymore, we can reduce
the number of traps by produceing a fake value.

Unfortunately the bulk of user-space is not DIC-aware, it blindly does
the D-side and I-side cache maintenance. To make matters worse, the
kernel can only trap all cache maintenance from EL0 with SCTLR_EL1.UCI.
The normal-world can't trap Data/Instruction cache maintenance
independently, but EL3 firmware can.

To avoid trapping all cache-maintenance, this workaround depends on
a firmware component that only traps I-cache maintenance from EL0 and
performs the workaround.


For user-space, the kernel's work is now to trap CTR_EL0 to hide DIC,
and produce a fake IminLine. EL3 traps the now-necessary I-Cache
maintenance and performs the inner-shareable-TLBI that makes everything
better.

We can't yet detect whether EL3 has the workaround for any particular
erratum. We lamely print '(kernel portion)' as part of the CPU-feature
text.
If we get a mechanism to discover this stuff we can use SCTLR_EL1.UCI
on systems that have the interface, and don't workaround the issue.


While the kernel has some JIT like features, they don't rely on
prefetch-speculation-protection. In particular the module-loader
ends up calling kick_all_cpus_sync() as part of the 'heavy' rules
above. Patch 4 lists the cases the kernel modifies itself. Only one
of these depends on prefetch-speculation-protection, it is easy enough
to remove it.


... questions welcome ...

Thanks,

James

[0] https://developer.arm.com/docs/sden885747/latest/arm-neoverse-n1-mp050-software-developer-errata-notice

James Morse (4):
  arm64: errata: Hide CTR_EL0.DIC on systems affected by Neoverse-N1
    #1542419
  arm64: Fake the IminLine size on systems affected by Neoverse-N1
    #1542419
  arm64: compat: Workaround Neoverse-N1 #1542419 for compat user-space
  arm64: ftrace: Ensure synchronisation in PLT setup for Neoverse-N1
    #1542419

 arch/arm64/Kconfig               | 16 ++++++++++++++++
 arch/arm64/include/asm/cache.h   |  3 ++-
 arch/arm64/include/asm/cpucaps.h |  3 ++-
 arch/arm64/kernel/cpu_errata.c   | 30 ++++++++++++++++++++++++++++++
 arch/arm64/kernel/ftrace.c       | 12 +++++++++---
 arch/arm64/kernel/sys_compat.c   | 11 +++++++++++
 arch/arm64/kernel/traps.c        |  7 +++++++
 7 files changed, 77 insertions(+), 5 deletions(-)

-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2019-10-11 18:22 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-02  9:49 [PATCH 0/4] arm64: errata: Workaround Neoverse-N1 #1542419 James Morse
2019-10-02  9:49 ` [PATCH 1/4] arm64: errata: Hide CTR_EL0.DIC on systems affected by " James Morse
2019-10-07  9:38   ` Suzuki K Poulose
2019-10-11 18:22     ` James Morse
2019-10-02  9:49 ` [PATCH 2/4] arm64: Fake the IminLine size " James Morse
2019-10-07  9:48   ` Suzuki K Poulose
2019-10-11 18:22     ` James Morse
2019-10-02  9:49 ` [PATCH 3/4] arm64: compat: Workaround Neoverse-N1 #1542419 for compat user-space James Morse
2019-10-02  9:49 ` [PATCH 4/4] arm64: ftrace: Ensure synchronisation in PLT setup for Neoverse-N1 #1542419 James Morse
2019-10-04 10:33   ` Will Deacon
2019-10-04 14:21     ` James Morse
2019-10-04 10:31 ` [PATCH 0/4] arm64: errata: Workaround " Will Deacon
2019-10-04 14:19   ` James Morse

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).