|
@@ -1331,6 +1331,11 @@ void perf_callchain_user(struct perf_callchain_entry *entry,
|
|
|
{
|
|
|
struct frame_tail __user *tail;
|
|
|
|
|
|
+ if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
|
|
|
+ /* We don't support guest os callchain now */
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
tail = (struct frame_tail __user *)regs->regs[29];
|
|
|
|
|
|
while (entry->nr < PERF_MAX_STACK_DEPTH &&
|
|
@@ -1355,8 +1360,40 @@ void perf_callchain_kernel(struct perf_callchain_entry *entry,
|
|
|
{
|
|
|
struct stackframe frame;
|
|
|
|
|
|
+ if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
|
|
|
+ /* We don't support guest os callchain now */
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
frame.fp = regs->regs[29];
|
|
|
frame.sp = regs->sp;
|
|
|
frame.pc = regs->pc;
|
|
|
walk_stackframe(&frame, callchain_trace, entry);
|
|
|
}
|
|
|
+
|
|
|
+unsigned long perf_instruction_pointer(struct pt_regs *regs)
|
|
|
+{
|
|
|
+ if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
|
|
|
+ return perf_guest_cbs->get_guest_ip();
|
|
|
+
|
|
|
+ return instruction_pointer(regs);
|
|
|
+}
|
|
|
+
|
|
|
+unsigned long perf_misc_flags(struct pt_regs *regs)
|
|
|
+{
|
|
|
+ int misc = 0;
|
|
|
+
|
|
|
+ if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
|
|
|
+ if (perf_guest_cbs->is_user_mode())
|
|
|
+ misc |= PERF_RECORD_MISC_GUEST_USER;
|
|
|
+ else
|
|
|
+ misc |= PERF_RECORD_MISC_GUEST_KERNEL;
|
|
|
+ } else {
|
|
|
+ if (user_mode(regs))
|
|
|
+ misc |= PERF_RECORD_MISC_USER;
|
|
|
+ else
|
|
|
+ misc |= PERF_RECORD_MISC_KERNEL;
|
|
|
+ }
|
|
|
+
|
|
|
+ return misc;
|
|
|
+}
|