From 600ba9bc4d4627300236fa1ff4ad133ee9d51149 Mon Sep 17 00:00:00 2001 From: Vincent Donnefort Date: Tue, 1 Oct 2024 15:42:13 +0100 Subject: [PATCH] ANDROID: KVM: arm64: Add func/func_ret pKVM hyp events Those events are raised for whenever a function is entered and exit at EL2. They rely on Ftrace in the pKVM hypervisor and the later must be enabled with CONFIG_PROTECTED_NVHE_FTRACE. Bug: 357781595 Change-Id: Ife7649fba88779ba3bb8bb7f11bbab244141200b Signed-off-by: Vincent Donnefort --- arch/arm64/include/asm/kvm_hypevents.h | 26 ++++++++++++++++++++++++++ arch/arm64/kvm/Kconfig | 12 ++++++++++++ arch/arm64/kvm/hyp/nvhe/ftrace.c | 7 ++++++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/kvm_hypevents.h b/arch/arm64/include/asm/kvm_hypevents.h index 2411436db9f9..d12c8c434f51 100644 --- a/arch/arm64/include/asm/kvm_hypevents.h +++ b/arch/arm64/include/asm/kvm_hypevents.h @@ -11,6 +11,32 @@ * Hypervisor events definitions. */ +#ifdef CONFIG_PROTECTED_NVHE_FTRACE +HYP_EVENT(func, + HE_PROTO(unsigned long ip, unsigned long parent), + HE_STRUCT( + he_field(unsigned long, ip) + he_field(unsigned long, parent) + ), + HE_ASSIGN( + __entry->ip = ip; + __entry->parent = parent; + ), + HE_PRINTK(" %ps <- %ps", (void *)__entry->ip, (void *)__entry->parent) +); + +HYP_EVENT(func_ret, + HE_PROTO(unsigned long ip), + HE_STRUCT( + he_field(unsigned long, ip) + ), + HE_ASSIGN( + __entry->ip = ip; + ), + HE_PRINTK("%ps", (void *)__entry->ip) +); +#endif + HYP_EVENT(hyp_enter, HE_PROTO(void), HE_STRUCT( diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig index 09bdcb32556b..df1a3592e4d5 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -92,6 +92,18 @@ config PROTECTED_NVHE_TESTING If unsure, say N. +config PROTECTED_NVHE_FTRACE + bool "Protected KVM hypervisor function tracing" + depends on KVM + depends on TRACING + default n + help + Say Y here to enable func and func_ret hypervisor tracing events. + Those events are raised whenever the hypervisor branch to a + function. + + If unsure, Say N. + config PKVM_MODULE_PATH string "Path to pKVM modules" default "" diff --git a/arch/arm64/kvm/hyp/nvhe/ftrace.c b/arch/arm64/kvm/hyp/nvhe/ftrace.c index 992b5a30e404..07840e031f25 100644 --- a/arch/arm64/kvm/hyp/nvhe/ftrace.c +++ b/arch/arm64/kvm/hyp/nvhe/ftrace.c @@ -97,6 +97,8 @@ unsigned long __hyp_ftrace_trace(unsigned long ip, unsigned long parent, /* When modules are called from core */ parent_offset_idx = parent > (unsigned long)__hyp_text_start ? 0 : offset_idx; + trace_func(func, __kern_addr(parent_offset_idx, parent)); + /* Only install the trampoline if we can revert to the original parent */ if (hyp_ftrace_func_push(func, parent)) return (unsigned long)__hyp_ftrace_ret_tramp; @@ -109,6 +111,7 @@ unsigned long __hyp_ftrace_ret_trace(void) struct hyp_ftrace_stack_frame *frame = hyp_ftrace_func_pop(); BUG_ON(!frame); + trace_func_ret(frame->func); return frame->ret; } @@ -117,8 +120,10 @@ void hyp_ftrace_ret_flush(void) { struct hyp_ftrace_stack_frame *frame = hyp_ftrace_func_pop(); - while (frame) + while (frame) { + trace_func_ret(frame->func); frame = hyp_ftrace_func_pop(); + } } static int __get_offset_idx_ins(unsigned long *func, unsigned long ip, u32 *insn,