From ace2dc7d12693545b67f15ab8cdb3d255c937713 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 13 Oct 2010 06:55:26 +0900 Subject: sh: wire up perf alignment and emulation faults. This plugs in the alignment and emulation fault reporting for perf sw events. Signed-off-by: Paul Mundt --- arch/sh/kernel/traps_32.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'arch/sh/kernel/traps_32.c') diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c index f5613529a6bf..3484c2f65aba 100644 --- a/arch/sh/kernel/traps_32.c +++ b/arch/sh/kernel/traps_32.c @@ -5,7 +5,7 @@ * SuperH version: Copyright (C) 1999 Niibe Yutaka * Copyright (C) 2000 Philipp Rumpf * Copyright (C) 2000 David Howells - * Copyright (C) 2002 - 2007 Paul Mundt + * Copyright (C) 2002 - 2010 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -369,7 +370,8 @@ static inline int handle_delayslot(struct pt_regs *regs, #define SH_PC_12BIT_OFFSET(instr) ((((signed short)(instr<<4))>>3) + 4) int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs, - struct mem_access *ma, int expected) + struct mem_access *ma, int expected, + unsigned long address) { u_int rm; int ret, index; @@ -383,9 +385,18 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs, index = (instruction>>8)&15; /* 0x0F00 */ rm = regs->regs[index]; - /* shout about fixups */ - if (!expected) + /* + * Log the unexpected fixups, and then pass them on to perf. + * + * We intentionally don't report the expected cases to perf as + * otherwise the trapped I/O case will skew the results too much + * to be useful. + */ + if (!expected) { unaligned_fixups_notify(current, instruction, regs); + perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, + regs, address); + } ret = -EFAULT; switch (instruction&0xF000) { @@ -574,7 +585,8 @@ fixup: set_fs(USER_DS); tmp = handle_unaligned_access(instruction, regs, - &user_mem_access, 0); + &user_mem_access, 0, + address); set_fs(oldfs); if (tmp == 0) @@ -607,8 +619,8 @@ uspace_segv: unaligned_fixups_notify(current, instruction, regs); - handle_unaligned_access(instruction, regs, - &user_mem_access, 0); + handle_unaligned_access(instruction, regs, &user_mem_access, + 0, address); set_fs(oldfs); } } -- cgit v1.2.3-55-g7522