Disabling caches with MMU enabled
Nicolas Pitre
nico at fluxnic.net
Mon Aug 10 07:49:13 PDT 2015
On Mon, 10 Aug 2015, Russell King - ARM Linux wrote:
> There is an erratum for Cortex-A15 which contains this paragraph:
>
> 2) Do not issue write-back cacheable stores at any time when the cache
> is disabled (SCTLR.C=0) and the MMU is enabled (SCTLR.M=1). Because it
> is implementation defined whether cacheable stores update the cache when
> the cache is disabled it is not expected that any portable code will
> execute cacheable stores when the cache is disabled.
>
> The interesting part is the second sentence, which implies that having the
> MMU enabled with writeback mappings, but with the C bit clear is not an
> expected use case. Moreover, it reinforces the ARM ARM statment that a
> disabled cache may still be searched, and updated with written data.
>
> However, the v7_exit_coherency_flush() function creates exactly this
> scenario by clearing the C bit:
>
> #define v7_exit_coherency_flush(level) \
> asm volatile( \
> ".arch armv7-a \n\t" \
> "stmfd sp!, {fp, ip} \n\t" \
> "mrc p15, 0, r0, c1, c0, 0 @ get SCTLR \n\t" \
> "bic r0, r0, #"__stringify(CR_C)" \n\t" \
> "mcr p15, 0, r0, c1, c0, 0 @ set SCTLR \n\t" \
> "isb \n\t" \
>
> However, v7_exit_coherency_flush() is careful to disable caching, flush
> the cache and then disable coherency. Whether that's sufficient for all
> cases is open to question - and where we need this CA15 errata implemented,
> it implies that even this sequence is not permissible to use there.
Just for the record, v7_exit_coherency_flush() was created in the
context of the MCPM layer used by both the b.L switcher and cpuidle
driver. This was developed in collaboration with ARM Ltd people who had
direct access to the hardware designers when subtle issues like this
came up. And they did come up during those months it took to stabilize
test results indeed.
The v7_exit_coherency_flush() in itself is probably safe given that it
flushes the cache after disabling it with no writes to memory in
between. Subsequent writes won't hit the cache even if it happens to
still be searched, and it won't be allocated anymore by virtue of not
being enabled.
Where things becomes interesting is within the MCPM synchronization
primitives where we do have writes from CPUs with mixed cache states,
and even MMU states. This is why we also created sync_cache_w() and
sync_cache_r(). In the former case, we certainly do have some
occurrences of MMU enabled with writeback mappings and the C bit clear.
But the cache for those write is supposed to be clean and not allocated
when the C bit is clear given v7_exit_coherency_flush() is used
beforehand.
> The exynos implementation of v7_exit_coherency() is another instance.
This one I can't explain. It is for an A15 just like the A15 we used on
TC2 for development and we did not need special erratum handling like
they apparently do. When I asked for a justification from a deeper
investigation _other than_ some automatic citation of the errata
document I got no answer. At this point in time it appears to be
impossible for the right people to care.
> I think all places which clear the C bit need to be re-reviewed and at
> least some of them fixed, or converted to use a macro such as the
> v7_exit_coherency_flush macro - and they should get a notice placed
> on them to discourage copy-n-pasting it.
Agreed. At that level you really must know what you're doing and have
the validation infrastructure in place. Merely copying existing code
that was validated in a different context is not OK if it doesn't come
with a comprehensive justification.
Nicolas
More information about the linux-arm-kernel
mailing list