s390/perf: add perf_regs support and user stack dump
Add s390 support to dump user stack to user space for DWARF stack unwinding. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Reviewed-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com> Reviewed-and-tested-by: Thomas Richter <tmricht@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
Родитель
9232c3c741
Коммит
c33eff6005
|
@ -159,6 +159,8 @@ config S390
|
|||
select HAVE_KRETPROBES
|
||||
select HAVE_KVM
|
||||
select HAVE_LIVEPATCH
|
||||
select HAVE_PERF_REGS
|
||||
select HAVE_PERF_USER_STACK_DUMP
|
||||
select HAVE_MEMBLOCK
|
||||
select HAVE_MEMBLOCK_NODE_MAP
|
||||
select HAVE_MEMBLOCK_PHYS_MAP
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef _ASM_S390_PERF_REGS_H
|
||||
#define _ASM_S390_PERF_REGS_H
|
||||
|
||||
enum perf_event_s390_regs {
|
||||
PERF_REG_S390_R0,
|
||||
PERF_REG_S390_R1,
|
||||
PERF_REG_S390_R2,
|
||||
PERF_REG_S390_R3,
|
||||
PERF_REG_S390_R4,
|
||||
PERF_REG_S390_R5,
|
||||
PERF_REG_S390_R6,
|
||||
PERF_REG_S390_R7,
|
||||
PERF_REG_S390_R8,
|
||||
PERF_REG_S390_R9,
|
||||
PERF_REG_S390_R10,
|
||||
PERF_REG_S390_R11,
|
||||
PERF_REG_S390_R12,
|
||||
PERF_REG_S390_R13,
|
||||
PERF_REG_S390_R14,
|
||||
PERF_REG_S390_R15,
|
||||
PERF_REG_S390_MASK,
|
||||
PERF_REG_S390_PC,
|
||||
|
||||
PERF_REG_S390_MAX
|
||||
};
|
||||
|
||||
#endif /* _ASM_S390_PERF_REGS_H */
|
|
@ -79,7 +79,7 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
|
|||
obj-$(CONFIG_UPROBES) += uprobes.o
|
||||
|
||||
obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_cpum_cf.o perf_cpum_sf.o
|
||||
obj-$(CONFIG_PERF_EVENTS) += perf_cpum_cf_events.o
|
||||
obj-$(CONFIG_PERF_EVENTS) += perf_cpum_cf_events.o perf_regs.o
|
||||
|
||||
obj-$(CONFIG_TRACEPOINTS) += trace.o
|
||||
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
#include <linux/perf_event.h>
|
||||
#include <linux/perf_regs.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/bug.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
u64 perf_reg_value(struct pt_regs *regs, int idx)
|
||||
{
|
||||
if (WARN_ON_ONCE((u32)idx >= PERF_REG_S390_MAX))
|
||||
return 0;
|
||||
|
||||
if (idx == PERF_REG_S390_MASK)
|
||||
return regs->psw.mask;
|
||||
if (idx == PERF_REG_S390_PC)
|
||||
return regs->psw.addr;
|
||||
|
||||
return regs->gprs[idx];
|
||||
}
|
||||
|
||||
#define REG_RESERVED (~((1UL << PERF_REG_S390_MAX) - 1))
|
||||
|
||||
int perf_reg_validate(u64 mask)
|
||||
{
|
||||
if (!mask || mask & REG_RESERVED)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 perf_reg_abi(struct task_struct *task)
|
||||
{
|
||||
if (test_tsk_thread_flag(task, TIF_31BIT))
|
||||
return PERF_SAMPLE_REGS_ABI_32;
|
||||
|
||||
return PERF_SAMPLE_REGS_ABI_64;
|
||||
}
|
||||
|
||||
void perf_get_regs_user(struct perf_regs *regs_user,
|
||||
struct pt_regs *regs,
|
||||
struct pt_regs *regs_user_copy)
|
||||
{
|
||||
/*
|
||||
* Use the regs from the first interruption and let
|
||||
* perf_sample_regs_intr() handle interrupts (regs == get_irq_regs()).
|
||||
*/
|
||||
regs_user->regs = task_pt_regs(current);
|
||||
regs_user->abi = perf_reg_abi(current);
|
||||
}
|
Загрузка…
Ссылка в новой задаче