All of lore.kernel.org
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: Linux Trace Devel <linux-trace-devel@vger.kernel.org>
Subject: [PATCH] libtracevent: Have kvm_exit/enter be able to show guest function
Date: Thu, 8 Sep 2022 18:07:58 -0400	[thread overview]
Message-ID: <20220908180758.50c94238@rorschach.local.home> (raw)

From: "Steven Rostedt (Google)" <rostedt@goodmis.org>

Add two weak functions tep_plugin_kvm_get_func() and
tep_plugin_kvm_put_func() to allow applications that are processing both
the host data as well as the guest data, and knows how to map the exit IP
address from the guest to an actual function name of the guest.

Instead of showing:

  kvm_exit:     reason EPT_VIOLATION rip 0xffffffffc01b1f39 info 181 0

show:

  kvm_exit:     reason EPT_VIOLATION rip 0xffffffffc01b1f39 ipt_do_table+0xe9 info 181 0

Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
 include/traceevent/event-parse.h | 29 +++++++++++++
 plugins/plugin_kvm.c             | 74 +++++++++++++++++++++++++++++---
 2 files changed, 98 insertions(+), 5 deletions(-)

diff --git a/include/traceevent/event-parse.h b/include/traceevent/event-parse.h
index 0b911e1caa7c..474586930bae 100644
--- a/include/traceevent/event-parse.h
+++ b/include/traceevent/event-parse.h
@@ -778,4 +778,33 @@ void tep_set_loglevel(enum tep_loglevel level);
 void tep_print_field(struct trace_seq *s, void *data,
 		     struct tep_format_field *field);
 
+
+/*
+ * Part of the KVM plugin. Will pass the current @event and @record
+ * as well as a pointer to the address to a guest kernel function.
+ * This is currently a weak function defined in the KVM plugin and
+ * should never be called. But a tool can override it, and this will
+ * be called when the kvm plugin has an address it needs the function
+ * name of.
+ *
+ * This function should return the function name for the given address
+ * and optionally, it can update @paddr to include the start of the function
+ * such that the kvm plugin can include an offset.
+ *
+ * For an application to be able to override the weak version in the
+ * plugin, it must be compiled with the gcc -rdynamic option that will
+ * allow the dynamic linker to use the application's function to
+ * override this callback.
+ */
+const char *tep_plugin_kvm_get_func(struct tep_event *event,
+				    struct tep_record *record,
+				    unsigned long long *paddr);
+
+/*
+ * tep_plugin_kvm_put_func() is another weak function that can be used
+ * to call back into the application if the function name returned by
+ * tep_plugin_kvm_get_func() needs to be freed.
+ */
+void tep_plugin_kvm_put_func(const char *func);
+
 #endif /* _PARSE_EVENTS_H */
diff --git a/plugins/plugin_kvm.c b/plugins/plugin_kvm.c
index 51ceeb9147eb..9852c35f4901 100644
--- a/plugins/plugin_kvm.c
+++ b/plugins/plugin_kvm.c
@@ -10,6 +10,8 @@
 #include "event-parse.h"
 #include "trace-seq.h"
 
+#define __weak __attribute__((weak))
+
 #ifdef HAVE_UDIS86
 
 #include <udis86.h>
@@ -273,15 +275,49 @@ static int print_exit_reason(struct trace_seq *s, struct tep_record *record,
 	return 0;
 }
 
+__weak const char *tep_plugin_kvm_get_func(struct tep_event *event,
+					   struct tep_record *record,
+					   unsigned long long *val)
+{
+	return NULL;
+}
+
+__weak void tep_plugin_kvm_put_func(const char *func)
+{
+}
+
+
+static void add_rip_function(struct trace_seq *s, struct tep_record *record,
+			     struct tep_event *event, unsigned long long rip)
+{
+	unsigned long long ip = rip;
+	const char *func;
+
+	func = tep_plugin_kvm_get_func(event, record, &ip);
+	if (func) {
+		trace_seq_printf(s, " %s", func);
+		/* The application may upate ip to the start of the function */
+		if (ip != rip)
+			trace_seq_printf(s, "+0x%0llx", rip - ip);
+		tep_plugin_kvm_put_func(func);
+	}
+}
+
 static int kvm_exit_handler(struct trace_seq *s, struct tep_record *record,
 			    struct tep_event *event, void *context)
 {
 	unsigned long long info1 = 0, info2 = 0;
+	unsigned long long rip;
 
 	if (print_exit_reason(s, record, event, "exit_reason") < 0)
 		return -1;
 
-	tep_print_num_field(s, " rip 0x%lx", event, "guest_rip", record, 1);
+	if (tep_get_field_val(s, event, "guest_rip", record, &rip, 1) < 0)
+		return -1;
+
+	trace_seq_printf(s, " rip 0x%llx", rip);
+
+	add_rip_function(s, record, event, rip);
 
 	if (tep_get_field_val(s, event, "info1", record, &info1, 0) >= 0
 	    && tep_get_field_val(s, event, "info2", record, &info2, 0) >= 0)
@@ -290,6 +326,22 @@ static int kvm_exit_handler(struct trace_seq *s, struct tep_record *record,
 	return 0;
 }
 
+static int kvm_entry_handler(struct trace_seq *s, struct tep_record *record,
+			    struct tep_event *event, void *context)
+{
+	unsigned long long rip;
+
+	tep_print_num_field(s, " vcpu %u", event, "vcpu_id", record, 1);
+
+	if (tep_get_field_val(s, event, "rip", record, &rip, 1) < 0)
+		return -1;
+
+	trace_seq_printf(s, " rip 0x%llx", rip);
+	add_rip_function(s, record, event, rip);
+
+	return 0;
+}
+
 #define KVM_EMUL_INSN_F_CR0_PE (1 << 0)
 #define KVM_EMUL_INSN_F_EFL_VM (1 << 1)
 #define KVM_EMUL_INSN_F_CS_D   (1 << 2)
@@ -329,12 +381,12 @@ static int kvm_emulate_insn_handler(struct trace_seq *s,
 			     flags & KVM_EMUL_INSN_F_CS_D,
 			     flags & KVM_EMUL_INSN_F_CS_L);
 
-	trace_seq_printf(s, "%llx:%llx: %s%s", csbase, rip, disasm,
-			 failed ? " FAIL" : "");
+	trace_seq_printf(s, "%llx:%llx", csbase, rip);
+	add_rip_function(s, record, event, rip);
+	trace_seq_printf(s, ": %s%s", disasm, failed ? " FAIL" : "");
 	return 0;
 }
 
-
 static int kvm_nested_vmexit_inject_handler(struct trace_seq *s, struct tep_record *record,
 					    struct tep_event *event, void *context)
 {
@@ -352,7 +404,13 @@ static int kvm_nested_vmexit_inject_handler(struct trace_seq *s, struct tep_reco
 static int kvm_nested_vmexit_handler(struct trace_seq *s, struct tep_record *record,
 				     struct tep_event *event, void *context)
 {
-	tep_print_num_field(s, "rip %llx ", event, "rip", record, 1);
+	unsigned long long rip;
+
+	if (tep_get_field_val(s, event, "rip", record, &rip, 1) < 0)
+		return -1;
+
+	trace_seq_printf(s, " rip %llx", rip);
+	add_rip_function(s, record, event, rip);
 
 	return kvm_nested_vmexit_inject_handler(s, record, event, context);
 }
@@ -456,6 +514,9 @@ int TEP_PLUGIN_LOADER(struct tep_handle *tep)
 	tep_register_event_handler(tep, -1, "kvm", "kvm_exit",
 				   kvm_exit_handler, NULL);
 
+	tep_register_event_handler(tep, -1, "kvm", "kvm_entry",
+				   kvm_entry_handler, NULL);
+
 	tep_register_event_handler(tep, -1, "kvm", "kvm_emulate_insn",
 				   kvm_emulate_insn_handler, NULL);
 
@@ -496,6 +557,9 @@ void TEP_PLUGIN_UNLOADER(struct tep_handle *tep)
 	tep_unregister_event_handler(tep, -1, "kvm", "kvm_exit",
 				     kvm_exit_handler, NULL);
 
+	tep_unregister_event_handler(tep, -1, "kvm", "kvm_entry",
+				     kvm_entry_handler, NULL);
+
 	tep_unregister_event_handler(tep, -1, "kvm", "kvm_emulate_insn",
 				     kvm_emulate_insn_handler, NULL);
 
-- 
2.35.1


                 reply	other threads:[~2022-09-08 22:08 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220908180758.50c94238@rorschach.local.home \
    --to=rostedt@goodmis.org \
    --cc=linux-trace-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.