Commit d703008e authored by He Chuyue's avatar He Chuyue Committed by guzitao
Browse files

sw64: perf: don't rely on layout of pt_regs to grab some registers

Sunway inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I6ILAC



--------------------------------

The layout of struct perf_event_sw64_regs and pt_regs is inconsistent,
and some integer registers cannot get correct value.

This patch checks these registers explicitly to return the appropriate
values.

Signed-off-by: default avatarHe Chuyue <hechuyue@wxiat.com>
Reviewed-by: default avatarHe Sheng <hesheng@wxiat.com>
Signed-off-by: default avatarGu Zitao <guzitao@wxiat.com>
parent 58b964b3
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
@@ -8,8 +8,25 @@ u64 perf_reg_value(struct pt_regs *regs, int idx)
	if (WARN_ON_ONCE((u32)idx >= PERF_REG_SW64_MAX))
		return 0;

	switch (idx) {
	case PERF_REG_SW64_R16:
		return regs->r16;
	case PERF_REG_SW64_R17:
		return regs->r17;
	case PERF_REG_SW64_R18:
		return regs->r18;
	case PERF_REG_SW64_R19 ... PERF_REG_SW64_R28:
		return ((unsigned long *)regs)[idx - 3];
	case PERF_REG_SW64_GP:
		return regs->gp;
	case PERF_REG_SW64_SP:
		return (u64)(user_mode(regs) ? rdusp() : (regs + 1));
	case PERF_REG_SW64_PC:
		return regs->pc;
	default:
		return ((unsigned long *)regs)[idx];
	}
}

#define REG_RESERVED (~((1ULL << PERF_REG_SW64_MAX) - 1))