1

I am using the following code to flush a cache line on a raspberry pi 2:

 static inline void flush(void addr)
 {
     asm volatile("mcr p15, 0, %0, c7, c6, 1"::"r"(addr));                                              
 } 

I am getting an error that this is a privileged instruction when I run this. Is this code correct? Is there any way to flush the cache line from user space on this machine? On x86 clflush works without any modification.

pranith
  • 869
  • 9
  • 24
  • Related: [Flush cache to DRAM](http://stackoverflow.com/questions/18896812/flush-cache-to-dram). There are two levels of cache, the L1 and L2 and both need different mechanisms to flush (and invalidate). Typically, the are only allowed from a supervisor mode so your OS must provide a mechanism. – artless noise May 20 '16 at 12:45

1 Answers1

4

Is this code correct?

As a matter of fact, no. That's some bogus non-existent system register encoding - cache maintenance operations live in the c7 space, not c12.

What's more incorrect, though, is the assumption that you can do this. Prior to ARMv8, all cache maintenance operations can only be executed in privileged modes. From userspace, you'd need support from the OS to allow you to request it; Linux, for example, has an ARM-specific syscall which GCC provides an interface to via __clear_cache() - there might be some permission-related caveats, although I don't see any reference to VMA permissions in the current mainline kernel code, so maybe it was a quirk of older kernels.

Either way, the only cache maintenance concern which really applies to userspace code is coherency between the instruction and data caches, to cater for JITs or self-modifying code. Things like data cache coherency with main memory should never be relevant to userspace code (which would normally be calling into driver code within the OS in situations where such things did matter), and on many systems require separate outer cache maintenance which only the OS is in a position to manage anyway.

Community
  • 1
  • 1
Notlikethat
  • 20,095
  • 3
  • 40
  • 77
  • You are right. c12 is supposed to be c7. Is the code correct if I change it to c7? – pranith May 19 '16 at 20:00
  • The given link mentions that you can clear the cache only if it is mmap'ed. So there is no equivalent to clflush on ARMv7? – pranith May 19 '16 at 20:02
  • You (should) need to `mmap` or `mprotect` pages to get them both writeable and executable, when coherency between instruction and data caches starts to matter; userspace cache maintenance is really only there for self-modifying code/JIT cases, (i.e. clean Dcache to point of unification, invalidate Icache). That corrected instruction would be _invalidating_ the data cache (i.e. potentially throwing away dirty data) which makes no sense for a userspace program to do, even if it could. – Notlikethat May 19 '16 at 21:05
  • Flushing the cache can also be required when profiling code. If a particular function always accesses cold data, profiling it with cold data is much more accurate. This would require flushing the cache between each call to ensure a consistent profiling scenario. – Nicholas Frechette Jan 08 '18 at 21:28