aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPunit Agrawal <punit.agrawal@arm.com>2014-11-18 06:41:27 -0500
committerWill Deacon <will.deacon@arm.com>2014-11-20 11:35:02 -0500
commitd784e2988a3e70a6f1047e80e01465a903ea2eba (patch)
tree9647174faebefdcef4c714e4135439cb2da90e11
parentc852f320584600a372646055d8229e063949eee7 (diff)
arm64: Trace emulation of AArch32 legacy instructions
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>
-rw-r--r--arch/arm64/kernel/Makefile1
-rw-r--r--arch/arm64/kernel/armv8_deprecated.c19
-rw-r--r--arch/arm64/kernel/trace-events-emulation.h35
3 files changed, 53 insertions, 2 deletions
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 84e9e5153efe..b36ebd0aacbb 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -5,6 +5,7 @@
5CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET) 5CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET)
6AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET) 6AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
7CFLAGS_efi-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) 7CFLAGS_efi-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
8CFLAGS_armv8_deprecated.o := -I$(src)
8 9
9CFLAGS_REMOVE_ftrace.o = -pg 10CFLAGS_REMOVE_ftrace.o = -pg
10CFLAGS_REMOVE_insn.o = -pg 11CFLAGS_REMOVE_insn.o = -pg
diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c
index 401c2e544ede..529aad93336f 100644
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -20,6 +20,9 @@
20#include <asm/traps.h> 20#include <asm/traps.h>
21#include <asm/uaccess.h> 21#include <asm/uaccess.h>
22 22
23#define CREATE_TRACE_POINTS
24#include "trace-events-emulation.h"
25
23/* 26/*
24 * The runtime support for deprecated instruction support can be in one of 27 * The runtime support for deprecated instruction support can be in one of
25 * following three states - 28 * following three states -
@@ -358,6 +361,11 @@ static int swp_handler(struct pt_regs *regs, u32 instr)
358 regs->user_regs.regs[destreg] = data; 361 regs->user_regs.regs[destreg] = data;
359 362
360ret: 363ret:
364 if (type == TYPE_SWPB)
365 trace_instruction_emulation("swpb", regs->pc);
366 else
367 trace_instruction_emulation("swp", regs->pc);
368
361 pr_warn_ratelimited("\"%s\" (%ld) uses obsolete SWP{B} instruction at 0x%llx\n", 369 pr_warn_ratelimited("\"%s\" (%ld) uses obsolete SWP{B} instruction at 0x%llx\n",
362 current->comm, (unsigned long)current->pid, regs->pc); 370 current->comm, (unsigned long)current->pid, regs->pc);
363 371
@@ -415,10 +423,15 @@ static int cp15barrier_handler(struct pt_regs *regs, u32 instr)
415 * dmb - mcr p15, 0, Rt, c7, c10, 5 423 * dmb - mcr p15, 0, Rt, c7, c10, 5
416 * dsb - mcr p15, 0, Rt, c7, c10, 4 424 * dsb - mcr p15, 0, Rt, c7, c10, 4
417 */ 425 */
418 if (aarch32_insn_mcr_extract_opc2(instr) == 5) 426 if (aarch32_insn_mcr_extract_opc2(instr) == 5) {
419 dmb(sy); 427 dmb(sy);
420 else 428 trace_instruction_emulation(
429 "mcr p15, 0, Rt, c7, c10, 5 ; dmb", regs->pc);
430 } else {
421 dsb(sy); 431 dsb(sy);
432 trace_instruction_emulation(
433 "mcr p15, 0, Rt, c7, c10, 4 ; dsb", regs->pc);
434 }
422 break; 435 break;
423 case 5: 436 case 5:
424 /* 437 /*
@@ -427,6 +440,8 @@ static int cp15barrier_handler(struct pt_regs *regs, u32 instr)
427 * Taking an exception or returning from one acts as an 440 * Taking an exception or returning from one acts as an
428 * instruction barrier. So no explicit barrier needed here. 441 * instruction barrier. So no explicit barrier needed here.
429 */ 442 */
443 trace_instruction_emulation(
444 "mcr p15, 0, Rt, c7, c5, 4 ; isb", regs->pc);
430 break; 445 break;
431 } 446 }
432 447
diff --git a/arch/arm64/kernel/trace-events-emulation.h b/arch/arm64/kernel/trace-events-emulation.h
new file mode 100644
index 000000000000..ae1dd598ea65
--- /dev/null
+++ b/arch/arm64/kernel/trace-events-emulation.h
@@ -0,0 +1,35 @@
1#undef TRACE_SYSTEM
2#define TRACE_SYSTEM emulation
3
4#if !defined(_TRACE_EMULATION_H) || defined(TRACE_HEADER_MULTI_READ)
5#define _TRACE_EMULATION_H
6
7#include <linux/tracepoint.h>
8
9TRACE_EVENT(instruction_emulation,
10
11 TP_PROTO(const char *instr, u64 addr),
12 TP_ARGS(instr, addr),
13
14 TP_STRUCT__entry(
15 __string(instr, instr)
16 __field(u64, addr)
17 ),
18
19 TP_fast_assign(
20 __assign_str(instr, instr);
21 __entry->addr = addr;
22 ),
23
24 TP_printk("instr=\"%s\" addr=0x%llx", __get_str(instr), __entry->addr)
25);
26
27#endif /* _TRACE_EMULATION_H */
28
29/* This part must be outside protection */
30#undef TRACE_INCLUDE_PATH
31#undef TRACE_INCLUDE_FILE
32#define TRACE_INCLUDE_PATH .
33
34#define TRACE_INCLUDE_FILE trace-events-emulation
35#include <trace/define_trace.h>