9

I tried clear and invalidate ARM v7 processor cache for instruction line, because instruction codes can change in execution.

For reaching the effect, I tried 2 variants. Here they are:

  1. I used GCC __clear_cache() function but it didn't give a required result. Instruction codes in cache didn't change.

  2. I looked for a source codes for GCC and found the uclinux-eabi.h file where I found the next code for clearing cache:

    /* Clear the instruction cache from `beg' to `end'.  This makes an
       inline system call to SYS_cacheflush.  */
    #undef CLEAR_INSN_CACHE
    #define CLEAR_INSN_CACHE(BEG, END)                                    \
    {                                                                     \
        register unsigned long _beg __asm ("a1") = (unsigned long) (BEG); \
        register unsigned long _end __asm ("a2") = (unsigned long) (END); \
        register unsigned long _flg __asm ("a3") = 0;                     \
        register unsigned long _scno __asm ("r7") = 0xf0002;              \
        __asm __volatile                                                  \
        (                                                                 \
            "swi 0x0    @ sys_cacheflush"                                 \
            : "=r" (_beg)                                                 \
            : "0" (_beg), "r" (_end), "r" (_flg), "r" (_scno));           \
    }
    

This variant didn't give the result too.

Maybe someone knows what I do wrong ?

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Alex Kolesnyk
  • 153
  • 1
  • 1
  • 5
  • 1
    I would check that the compiler is actually honoring your request to use the specified register (a1, a2, a3, r7) by dumping the generated object file as assembly. You're probably ending up with the wrong registers being used for the kernel call (swi). – John Ripley May 20 '11 at 02:31
  • As I understand it, this is the recommend way to get asm inputs in specific register, because there aren't specific constraints for individual registers :( http://stackoverflow.com/q/37358451/224132 – Peter Cordes Sep 03 '16 at 15:26

1 Answers1

9

I had a similar problem myself. __clear_cache() works, but only if the memory area in question was allocated using mmap() with PROT_EXEC set. Linux will not flush the instruction cache if you provide it with a memory range that comes from regular malloc()ed memory, even if the processor seems to be happy to execute code from malloc()ed memory.

See https://community.arm.com/groups/processors/blog/2010/02/17/caches-and-self-modifying-code for example code on how to do this.

Notlikethat
  • 20,095
  • 3
  • 40
  • 77
Rune
  • 404
  • 2
  • 5