Search code examples
linux-kernelcpu-registersperf

Recompile Linux Kernel not to use specific CPU register


I'm doing an experiment that write the index of loop into a CPU register R11, then building it with gcc -ffixed-r11 try to let compiler know do not use that reg, and finally using perf to measure it.

But when I check the report (using perf script), the R11 value of most record entry is not what I expected, it supposed to be the number sequence like 1..2..3 or 1..4..7, etc. But actually it just a few fixed value. (possibly affected by system call overwriting?)

How can I let perf records the value I set to the register in my program? Or I must to recompile the whole kernel with -ffixed-r11 to achieve?

Thanks everyone.


Solution

  • You should not try to recompile kernel when you just want to sample some register with perf. As I understand, kernel has its own set of registers and will not overwrite user R11. syscall interface uses some fixed registers which can't be changed (can you try different reg?) and there are often glibc gateways to syscall which may use some additional registers (they are not in kernel, they are user-space code; often generated or written in assembler). You may try using gdb to monitor the register to change to find who did it. It can do this (hmm, one more link to the same user on SO): gdb: breakpoint when register will have value 0xffaa like gdb ./program then gdb commands start; watch $r11; continue; where.

    Two weeks age there was question perf-report show value of CPU register about register value sampling with perf:

    I follow this document and using perf record with --intr-regs=ax,bx,r15, trying to log additional CPU register information with PEBS record.

    While there was x86 & PEBS, ARM may have --intr-regs implemented too. Check output of perf record --intr-regs=\? (man perf-record: "To list the available registers use --intr-regs=\?") to find support status and register names.

    To print registers, use perf script -F ip,sym,iregs command. There was example in some linux commits:

      # perf record --intr-regs=AX,SP usleep 1
      [ perf record: Woken up 1 times to write data ]
      [ perf record: Captured and wrote 0.016 MB perf.data (8 samples) ]
      # perf script -F ip,sym,iregs | tail -5
       ffffffff8105f42a native_write_msr_safe   AX:0xf    SP:0xffff8802629c3c00
       ffffffff8105f42a native_write_msr_safe   AX:0xf    SP:0xffff8802629c3c00
       ffffffff81761ac0 _raw_spin_lock   AX:0xffff8801bfcf8020    SP:0xffff8802629c3ce8
       ffffffff81202bf8 __vma_adjust_trans_huge   AX:0x7ffc75200000    SP:0xffff8802629c3b30
       ffffffff8122b089 dput   AX:0x101    SP:0xffff8802629c3c78
      #