Flush a cache line from user mode on ARMv7(rpi2)
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.
How to flush the CPU cache for a region of address space in Linux?
Check this page for list of available flushing methods in linux kernel: https://www.kernel.org/doc/Documentation/cachetlb.txt
Cache and TLB Flushing Under Linux. David S. Miller
There are set of range flushing functions
2) flush_cache_range(vma, start, end);
change_range_of_page_tables(mm, start, end);
flush_tlb_range(vma, start, end);
3) void flush_cache_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
Here we are flushing a specific range of (user) virtual
addresses from the cache. After running, there will be no
entries in the cache for 'vma->vm_mm' for virtual addresses in
the range 'start' to 'end-1'.
You can also check implementation of the function - http://lxr.free-electrons.com/ident?a=sh;i=flush_cache_range
For example, in arm - http://lxr.free-electrons.com/source/arch/arm/mm/flush.c?a=sh&v=3.13#L67
67 void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
68 {
69 if (cache_is_vivt()) {
70 vivt_flush_cache_range(vma, start, end);
71 return;
72 }
73
74 if (cache_is_vipt_aliasing()) {
75 asm( "mcr p15, 0, %0, c7, c14, 0\n"
76 " mcr p15, 0, %0, c7, c10, 4"
77 :
78 : "r" (0)
79 : "cc");
80 }
81
82 if (vma->vm_flags & VM_EXEC)
83 __flush_icache_all();
84 }
Related Topics
How to Search Contents of Multiple PDF Files
Install Mono and Monodevelop on Centos 5.X/6.X
How to Get the Start Time of a Long-Running Linux Process
Are There Standards for Linux Command Line Switches and Arguments
What Does "Ulimit -S Unlimited" Do
How to Create a Configure Script
How Is the Linux Kernel Tested
Insert Multiple Lines into a File After Specified Pattern Using Shell Script
Count Number of Files Within a Directory in Linux
Meaning of Tilde in Linux Bash (Not Home Directory)
How to Tell Linux Not to Swap Out a Particular Processes' Memory
How to Reference Files Relative to Application Root in Node.Js