How Clear and Invalidate Arm V7 Processor Cache from User Mode on Linux 2.6.35

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



Leave a reply



Submit