Skip to content

Commit

Permalink
arm64: Trace emulation of AArch32 legacy instructions
Browse files Browse the repository at this point in the history
Introduce an event to trace the usage of emulated instructions. The
trace event is intended to help identify and encourage the migration
of legacy software using the emulation features.

Use this event to trace usage of swp and CP15 barrier emulation.

Acked-by: Steven Rostedt <rostedt@goodmis.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Punit Agrawal <punit.agrawal@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
  • Loading branch information
Punit Agrawal authored and Will Deacon committed Nov 20, 2014
1 parent c852f32 commit d784e29
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 2 deletions.
1 change: 1 addition & 0 deletions arch/arm64/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET)
AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
CFLAGS_efi-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
CFLAGS_armv8_deprecated.o := -I$(src)

CFLAGS_REMOVE_ftrace.o = -pg
CFLAGS_REMOVE_insn.o = -pg
Expand Down
19 changes: 17 additions & 2 deletions arch/arm64/kernel/armv8_deprecated.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
#include <asm/traps.h>
#include <asm/uaccess.h>

#define CREATE_TRACE_POINTS
#include "trace-events-emulation.h"

/*
* The runtime support for deprecated instruction support can be in one of
* following three states -
Expand Down Expand Up @@ -358,6 +361,11 @@ static int swp_handler(struct pt_regs *regs, u32 instr)
regs->user_regs.regs[destreg] = data;

ret:
if (type == TYPE_SWPB)
trace_instruction_emulation("swpb", regs->pc);
else
trace_instruction_emulation("swp", regs->pc);

pr_warn_ratelimited("\"%s\" (%ld) uses obsolete SWP{B} instruction at 0x%llx\n",
current->comm, (unsigned long)current->pid, regs->pc);

Expand Down Expand Up @@ -415,10 +423,15 @@ static int cp15barrier_handler(struct pt_regs *regs, u32 instr)
* dmb - mcr p15, 0, Rt, c7, c10, 5
* dsb - mcr p15, 0, Rt, c7, c10, 4
*/
if (aarch32_insn_mcr_extract_opc2(instr) == 5)
if (aarch32_insn_mcr_extract_opc2(instr) == 5) {
dmb(sy);
else
trace_instruction_emulation(
"mcr p15, 0, Rt, c7, c10, 5 ; dmb", regs->pc);
} else {
dsb(sy);
trace_instruction_emulation(
"mcr p15, 0, Rt, c7, c10, 4 ; dsb", regs->pc);
}
break;
case 5:
/*
Expand All @@ -427,6 +440,8 @@ static int cp15barrier_handler(struct pt_regs *regs, u32 instr)
* Taking an exception or returning from one acts as an
* instruction barrier. So no explicit barrier needed here.
*/
trace_instruction_emulation(
"mcr p15, 0, Rt, c7, c5, 4 ; isb", regs->pc);
break;
}

Expand Down
35 changes: 35 additions & 0 deletions arch/arm64/kernel/trace-events-emulation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#undef TRACE_SYSTEM
#define TRACE_SYSTEM emulation

#if !defined(_TRACE_EMULATION_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_EMULATION_H

#include <linux/tracepoint.h>

TRACE_EVENT(instruction_emulation,

TP_PROTO(const char *instr, u64 addr),
TP_ARGS(instr, addr),

TP_STRUCT__entry(
__string(instr, instr)
__field(u64, addr)
),

TP_fast_assign(
__assign_str(instr, instr);
__entry->addr = addr;
),

TP_printk("instr=\"%s\" addr=0x%llx", __get_str(instr), __entry->addr)
);

#endif /* _TRACE_EMULATION_H */

/* This part must be outside protection */
#undef TRACE_INCLUDE_PATH
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_PATH .

#define TRACE_INCLUDE_FILE trace-events-emulation
#include <trace/define_trace.h>

0 comments on commit d784e29

Please sign in to comment.