f51e2f1911
Currently instruction_pointer() returns pt_regs->ret and so return value is of type "long", which implicitly stands for "signed long". While that's perfectly fine when dealing with 32-bit values if return value of instruction_pointer() gets assigned to 64-bit variable sign extension may happen. And at least in one real use-case it happens already. In perf_prepare_sample() return value of perf_instruction_pointer() (which is an alias to instruction_pointer() in case of ARC) is assigned to (struct perf_sample_data)->ip (which type is "u64"). And what we see if instuction pointer points to user-space application that in case of ARC lays below 0x8000_0000 "ip" gets set properly with leading 32 zeros. But if instruction pointer points to kernel address space that starts from 0x8000_0000 then "ip" is set with 32 leadig "f"-s. I.e. id instruction_pointer() returns 0x8100_0000, "ip" will be assigned with 0xffff_ffff__8100_0000. Which is obviously wrong. In particular that issuse broke output of perf, because perf was unable to associate addresses like 0xffff_ffff__8100_0000 with anything from /proc/kallsyms. That's what we used to see: ----------->8---------- 6.27% ls [unknown] [k] 0xffffffff8046c5cc 2.96% ls libuClibc-0.9.34-git.so [.] memcpy 2.25% ls libuClibc-0.9.34-git.so [.] memset 1.66% ls [unknown] [k] 0xffffffff80666536 1.54% ls libuClibc-0.9.34-git.so [.] 0x000224d6 1.18% ls libuClibc-0.9.34-git.so [.] 0x00022472 ----------->8---------- With that change perf output looks much better now: ----------->8---------- 8.21% ls [kernel.kallsyms] [k] memset 3.52% ls libuClibc-0.9.34-git.so [.] memcpy 2.11% ls libuClibc-0.9.34-git.so [.] malloc 1.88% ls libuClibc-0.9.34-git.so [.] memset 1.64% ls [kernel.kallsyms] [k] _raw_spin_unlock_irqrestore 1.41% ls [kernel.kallsyms] [k] __d_lookup_rcu ----------->8---------- Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com> Cc: arc-linux-dev@synopsys.com Cc: stable@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Vineet Gupta <vgupta@synopsys.com> |
||
---|---|---|
.. | ||
arcregs.h | ||
asm-offsets.h | ||
atomic.h | ||
barrier.h | ||
bitops.h | ||
bug.h | ||
cache.h | ||
cacheflush.h | ||
checksum.h | ||
clk.h | ||
cmpxchg.h | ||
current.h | ||
delay.h | ||
disasm.h | ||
dma-mapping.h | ||
dma.h | ||
elf.h | ||
entry-arcv2.h | ||
entry-compact.h | ||
entry.h | ||
exec.h | ||
futex.h | ||
io.h | ||
irq.h | ||
irqflags-arcv2.h | ||
irqflags-compact.h | ||
irqflags.h | ||
Kbuild | ||
kdebug.h | ||
kgdb.h | ||
kprobes.h | ||
linkage.h | ||
mach_desc.h | ||
mcip.h | ||
mm-arch-hooks.h | ||
mmu_context.h | ||
mmu.h | ||
module.h | ||
mutex.h | ||
page.h | ||
perf_event.h | ||
pgalloc.h | ||
pgtable.h | ||
processor.h | ||
ptrace.h | ||
sections.h | ||
segment.h | ||
serial.h | ||
setup.h | ||
shmparam.h | ||
smp.h | ||
spinlock_types.h | ||
spinlock.h | ||
stacktrace.h | ||
string.h | ||
switch_to.h | ||
syscall.h | ||
syscalls.h | ||
thread_info.h | ||
timex.h | ||
tlb-mmu1.h | ||
tlb.h | ||
tlbflush.h | ||
uaccess.h | ||
unaligned.h | ||
unwind.h |