@@ -98,7 +98,6 @@ config PERF_ARRAYS
---help---
Enables software performance counter array histograms.
-
config VERBOSE_DEBUG
bool "Verbose debug messages"
default DEBUG
@@ -114,6 +113,12 @@ config DEVICE_TREE_DEBUG
logged in the Xen ring buffer.
If unsure, say N here.
+config TRACE_PC
+ bool "Enable pc-tracing"
+ default false
+ ---help---
+ Adds tracing support to the hypervisor (needed for the trace_pc hypercall).
+
endif # DEBUG || EXPERT
endmenu
@@ -170,6 +170,10 @@ clean:: $(addprefix _clean_, $(subdir-all))
_clean_%/: FORCE
$(MAKE) -f $(BASEDIR)/Rules.mk -C $* clean
+ifeq ($(CONFIG_TRACE_PC),y)
+$(objs-need-tracing): CFLAGS += -fsanitize-coverage=trace-pc
+endif
+
%.o: %.c Makefile
$(CC) $(CFLAGS) -c $< -o $@
@@ -1419,6 +1419,7 @@ static arm_hypercall_t arm_hypercall_table[] = {
HYPERCALL(platform_op, 1),
HYPERCALL_ARM(vcpu_op, 3),
HYPERCALL(vm_assist, 2),
+ HYPERCALL(trace_pc, 4),
};
#ifndef NDEBUG
@@ -74,6 +74,8 @@ efi-y := $(shell if [ ! -r $(BASEDIR)/include/xen/compile.h -o \
-O $(BASEDIR)/include/xen/compile.h ]; then \
echo '$(TARGET).efi'; fi)
+objs-need-tracing := cpuid.o hypercall.o
+
ifneq ($(build_id_linker),)
notes_phdrs = --notes
else
@@ -132,6 +132,7 @@ static const hypercall_table_t hvm_hypercall_table[] = {
COMPAT_CALL(mmuext_op),
HYPERCALL(xenpmu_op),
COMPAT_CALL(dm_op),
+ HYPERCALL(trace_pc),
HYPERCALL(arch_1)
};
@@ -68,6 +68,7 @@ const hypercall_args_t hypercall_args_table[NR_hypercalls] =
ARGS(xenpmu_op, 2),
ARGS(dm_op, 3),
ARGS(mca, 1),
+ ARGS(trace_pc, 4),
ARGS(arch_1, 1),
};
@@ -11,3 +11,5 @@ obj-y += traps.o
obj-bin-y += dom0_build.init.o
obj-bin-y += gpr_switch.o
+
+objs-need-tracing += hypercall.o
@@ -80,6 +80,7 @@ static const hypercall_table_t pv_hypercall_table[] = {
HYPERCALL(xenpmu_op),
COMPAT_CALL(dm_op),
HYPERCALL(mca),
+ HYPERCALL(trace_pc),
HYPERCALL(arch_1),
};
@@ -55,6 +55,8 @@ obj-y += tasklet.o
obj-y += time.o
obj-y += timer.o
obj-y += trace.o
+obj-y += trace_pc.o
+obj-$(CONFIG_TRACE_PC) += trace_pc_stub.o
obj-y += version.o
obj-y += virtual_region.o
obj-y += vm_event.o
@@ -80,3 +82,14 @@ subdir-$(CONFIG_GCOV) += gcov
subdir-y += libelf
subdir-$(CONFIG_HAS_DEVICE_TREE) += libfdt
+
+objs-need-tracing := bsearch.o \
+ decompress.o device_tree.o domain.o domctl.o earlycpio.o grant_table.o \
+ guestcopy.o gunzip.o inflate.o kernel.o kexec.o keyhandler.o kimage.o \
+ lib.o livepatch.o lzo.o mem_access.o memory.o multicall.o notifier.o \
+ page_alloc.o pdx.o perfc.o radix_tree.o rangeset.o \
+ rbtree.o shutdown.o sort.o stop_machine.o \
+ symbols.o symbols-dummy.o sysctl.o time.o tmem.o \
+ tmem_control.o tmem_xen.o trace.o unlz4.o unlzo.o unxz.o version.o \
+ virtual_region.o vmap.o vm_event.o warning.o xenoprof.o \
+ xmalloc_tlsf.o
@@ -874,6 +874,10 @@ void domain_destroy(struct domain *d)
rcu_assign_pointer(*pd, d->next_in_hashbucket);
spin_unlock(&domlist_update_lock);
+#ifdef CONFIG_TRACE_PC
+ xfree(d->tracing_buffer);
+#endif
+
/* Schedule RCU asynchronous completion of domain destroy. */
call_rcu(&d->rcu, complete_domain_destroy);
}
new file mode 100644
@@ -0,0 +1,96 @@
+/******************************************************************************
+ * trace_pc.c
+ *
+ * Implementation of the program counter tracing hypercall.
+ *
+ * Copyright (c) 2017 Felix Schmoll <eggi.innovations@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms and conditions of the GNU General Public
+ * License, version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <xen/guest_access.h>
+#include <xen/sched.h>
+#include <xen/xmalloc.h>
+#include <public/trace_pc.h>
+
+long do_trace_pc(domid_t dom, int mode, unsigned int size,
+ XEN_GUEST_HANDLE_PARAM(uint64_t) buf)
+{
+#ifdef CONFIG_TRACE_PC
+ int ret = 0;
+ struct domain *d;
+
+ if ( dom == DOMID_SELF )
+ d = current->domain;
+ else
+ d = get_domain_by_id(dom);
+
+ if ( !d )
+ return -ESRCH; /* invalid domain */
+
+ switch ( mode )
+ {
+ case XEN_TRACE_PC_START:
+ {
+ if ( d->tracing_buffer )
+ {
+ ret = -EBUSY; /* domain already being traced */
+ break;
+ }
+
+ d->tracing_buffer_pos = 0;
+ d->tracing_buffer_size = size;
+ d->tracing_buffer = xmalloc_array(uint64_t, size);
+
+ if ( !d->tracing_buffer )
+ ret = -ENOMEM;
+ break;
+ }
+
+ case XEN_TRACE_PC_STOP:
+ {
+ uint64_t *temp = d->tracing_buffer;
+ d->tracing_buffer = NULL;
+
+ if ( copy_to_guest(buf, temp, d->tracing_buffer_pos) )
+ ret = -EFAULT;
+ else
+ ret = d->tracing_buffer_pos;
+
+ xfree(temp);
+
+ break;
+ }
+
+ default:
+ ret = -ENOSYS;
+ }
+
+ if ( dom != DOMID_SELF )
+ put_domain(d);
+
+ return ret;
+#else
+ return -EOPNOTSUPP;
+#endif
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
new file mode 100644
@@ -0,0 +1,39 @@
+/******************************************************************************
+ * trace_pc_stub.c
+ *
+ * Edge function/stub for the program counter tracing hypercall.
+ *
+ * Copyright (c) 2017 Felix Schmoll <eggi.innovations@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms and conditions of the GNU General Public
+ * License, version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <xen/trace_pc.h>
+#include <xen/kernel.h>
+
+void __sanitizer_cov_trace_pc(void)
+{
+ struct domain *d;
+
+ if ( system_state < SYS_STATE_active )
+ return;
+
+ d = current->domain;
+
+ if ( d->tracing_buffer &&
+ (d->tracing_buffer_pos < d->tracing_buffer_size) )
+ {
+ d->tracing_buffer[d->tracing_buffer_pos++] =
+ (uint64_t) __builtin_return_address(0);
+ }
+}
new file mode 100644
@@ -0,0 +1,38 @@
+/******************************************************************************
+ * trace_pc.h
+ *
+ * Macros for program counter tracing hypercall.
+ *
+ * Copyright (C) 2017 Felix Schmoll <eggi.innovations@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __XEN_PUBLIC_TRACE_PC_H__
+#define __XEN_PUBLIC_TRACE_PC_H__
+
+#if defined(__XEN__) || defined(__XEN_TOOLS__)
+
+#define XEN_TRACE_PC_START 0
+#define XEN_TRACE_PC_STOP 1
+
+#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */
+
+#endif /* __XEN_PUBLIC_TRACE_PC_H__ */
@@ -121,6 +121,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
#define __HYPERVISOR_xc_reserved_op 39 /* reserved for XenClient */
#define __HYPERVISOR_xenpmu_op 40
#define __HYPERVISOR_dm_op 41
+#define __HYPERVISOR_trace_pc 42
/* Architecture-specific hypercall definitions. */
#define __HYPERVISOR_arch_0 48
@@ -83,6 +83,13 @@ do_xen_version(
XEN_GUEST_HANDLE_PARAM(void) arg);
extern long
+do_trace_pc(
+ domid_t dom_id,
+ int mode,
+ unsigned int size,
+ XEN_GUEST_HANDLE_PARAM(uint64_t) buf);
+
+extern long
do_console_io(
int cmd,
int count,
@@ -483,6 +483,12 @@ struct domain
unsigned int guest_request_enabled : 1;
unsigned int guest_request_sync : 1;
} monitor;
+
+#ifdef CONFIG_TRACE_PC
+ uint64_t* tracing_buffer;
+ unsigned int tracing_buffer_pos;
+ unsigned int tracing_buffer_size;
+#endif
};
/* Protect updates/reads (resp.) of domain_list and domain_hash. */
new file mode 100644
@@ -0,0 +1,31 @@
+/******************************************************************************
+ * trace_pc.h
+ *
+ * Declarations for the program counter tracing hypercall
+ *
+ * Copyright (C) 2017 Felix Schmoll <eggi.innovations@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms and conditions of the GNU General Public
+ * License, version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __TRACE_PC_H__
+#define __TRACE_PC_H__
+
+#include <xen/sched.h>
+#include <xen/types.h>
+
+#include <asm/current.h>
+
+void __sanitizer_cov_trace_pc(void);
+
+#endif /* __TRACE_PC_H__ */
This commit makes the changes to the hypervisor, the build system as well as libxc necessary in order to facilitate tracing of program counters. A discussion of the design can be found in the mailing list: https://lists.xen.org/archives/html/xen-devel/2017-05/threads.html#02210 The list of files to be included for tracing might still be too extensive, resulting in indeterministic tracing output for some use cases. Signed-off-by: Felix Schmoll <eggi.innovations@gmail.com> --- Changed since v2: * Fix bug that hypercall wouldn't return -EFAULT * Adjust error return codes of hypercall * Add description to Kconfig * Move compile-option from Kconfig to Kconfig.debug * Formatting changes --- CC: Andrew Cooper <andrew.cooper3@citrix.com> CC: George Dunlap <George.Dunlap@eu.citrix.com> CC: Ian Jackson <ian.jackson@eu.citrix.com> CC: Jan Beulich <jbeulich@suse.com> CC: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> CC: Stefano Stabellini <sstabellini@kernel.org> CC: Tim Deegan <tim@xen.org> CC: Wei Liu <wei.liu2@citrix.com> CC: Julien Grall <julien.grall@arm.com> CC: xen-devel@lists.xen.org --- xen/Kconfig.debug | 7 +++- xen/Rules.mk | 4 ++ xen/arch/arm/traps.c | 1 + xen/arch/x86/Makefile | 2 + xen/arch/x86/hvm/hypercall.c | 1 + xen/arch/x86/hypercall.c | 1 + xen/arch/x86/pv/Makefile | 2 + xen/arch/x86/pv/hypercall.c | 1 + xen/common/Makefile | 13 ++++++ xen/common/domain.c | 4 ++ xen/common/trace_pc.c | 96 +++++++++++++++++++++++++++++++++++++++++++ xen/common/trace_pc_stub.c | 39 ++++++++++++++++++ xen/include/public/trace_pc.h | 38 +++++++++++++++++ xen/include/public/xen.h | 1 + xen/include/xen/hypercall.h | 7 ++++ xen/include/xen/sched.h | 6 +++ xen/include/xen/trace_pc.h | 31 ++++++++++++++ 17 files changed, 253 insertions(+), 1 deletion(-) create mode 100644 xen/common/trace_pc.c create mode 100644 xen/common/trace_pc_stub.c create mode 100644 xen/include/public/trace_pc.h create mode 100644 xen/include/xen/trace_pc.h