aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2018-06-08 04:20:42 -0400
committerJiri Kosina <jkosina@suse.cz>2018-06-08 04:20:42 -0400
commitc1144d29f405ce1f4e6ede6482beb3d0d09750c6 (patch)
tree0f9fe36a50005bae6ffe28a4f978e71273f5b1d1 /tools
parentd6c70a86bc72fabe7fc9d9533afdb46a56c16896 (diff)
parenta317e559574b2af62095b39792d168cb98cb2561 (diff)
Merge branch 'for-4.18/alps' into for-linus
hid-alps driver cleanups wrt. t4_read_write_register() handling from Christophe Jaillet
Diffstat (limited to 'tools')
-rw-r--r--tools/arch/x86/include/asm/cpufeatures.h2
-rw-r--r--tools/build/Build.include5
-rw-r--r--tools/include/linux/spinlock.h1
-rw-r--r--tools/include/tools/config.h34
-rw-r--r--tools/include/uapi/drm/i915_drm.h112
-rw-r--r--tools/include/uapi/linux/kvm.h2
-rwxr-xr-xtools/kvm/kvm_stat/kvm_stat11
-rw-r--r--tools/objtool/Makefile2
-rw-r--r--tools/perf/Documentation/perf-report.txt1
-rw-r--r--tools/perf/Documentation/perf-trace.txt3
-rw-r--r--tools/perf/Documentation/perf-version.txt24
-rw-r--r--tools/perf/Makefile.config8
-rw-r--r--tools/perf/Makefile.perf3
-rw-r--r--tools/perf/builtin-trace.c11
-rw-r--r--tools/perf/builtin-version.c82
-rw-r--r--tools/perf/perf.c6
-rw-r--r--tools/perf/perf.h1
-rw-r--r--tools/perf/ui/browser.c12
-rw-r--r--tools/perf/ui/browser.h2
-rw-r--r--tools/perf/ui/browsers/annotate.c33
-rw-r--r--tools/perf/ui/browsers/hists.c138
-rw-r--r--tools/perf/util/annotate.c51
-rw-r--r--tools/perf/util/annotate.h12
-rw-r--r--tools/perf/util/auxtrace.c72
-rw-r--r--tools/perf/util/c++/clang-test.cpp2
-rw-r--r--tools/perf/util/c++/clang.cpp11
-rw-r--r--tools/perf/util/dwarf-aux.c2
-rw-r--r--tools/perf/util/hist.c81
-rw-r--r--tools/perf/util/hist.h7
-rw-r--r--tools/perf/util/map.h4
-rw-r--r--tools/perf/util/session.c2
-rw-r--r--tools/perf/util/sort.c41
-rw-r--r--tools/perf/util/sort.h1
-rw-r--r--tools/perf/util/util.h4
-rw-r--r--tools/scripts/Makefile.include2
-rwxr-xr-xtools/testing/ktest/config-bisect.pl770
-rwxr-xr-xtools/testing/ktest/ktest.pl533
-rw-r--r--tools/testing/ktest/sample.conf60
-rw-r--r--tools/testing/nvdimm/test/nfit.c239
-rw-r--r--tools/testing/nvdimm/test/nfit_test.h16
-rw-r--r--tools/testing/radix-tree/linux/gfp.h1
-rw-r--r--tools/testing/selftests/Makefile13
-rw-r--r--tools/testing/selftests/android/ion/.gitignore1
-rw-r--r--tools/testing/selftests/android/ion/Makefile5
-rw-r--r--tools/testing/selftests/android/ion/config1
-rw-r--r--tools/testing/selftests/android/ion/ionmap_test.c136
-rw-r--r--tools/testing/selftests/android/ion/ionutils.c6
-rw-r--r--tools/testing/selftests/ftrace/test.d/functions7
-rw-r--r--tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-extended-error-support.tc39
-rw-r--r--tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-field-variable-support.tc54
-rw-r--r--tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-inter-event-combined-hist.tc58
-rw-r--r--tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmatch-action-hist.tc50
-rw-r--r--tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmatch-onmax-action-hist.tc50
-rw-r--r--tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmax-action-hist.tc48
-rw-r--r--tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-event-createremove.tc54
-rw-r--r--tools/testing/selftests/futex/Makefile4
-rw-r--r--tools/testing/selftests/intel_pstate/Makefile5
-rw-r--r--tools/testing/selftests/kselftest.h3
-rw-r--r--tools/testing/selftests/kselftest_harness.h26
-rw-r--r--tools/testing/selftests/kvm/Makefile40
-rw-r--r--tools/testing/selftests/kvm/include/kvm_util.h145
-rw-r--r--tools/testing/selftests/kvm/include/sparsebit.h75
-rw-r--r--tools/testing/selftests/kvm/include/test_util.h45
-rw-r--r--tools/testing/selftests/kvm/include/vmx.h494
-rw-r--r--tools/testing/selftests/kvm/include/x86.h1043
-rw-r--r--tools/testing/selftests/kvm/lib/assert.c87
-rw-r--r--tools/testing/selftests/kvm/lib/elf.c197
-rw-r--r--tools/testing/selftests/kvm/lib/io.c158
-rw-r--r--tools/testing/selftests/kvm/lib/kvm_util.c1486
-rw-r--r--tools/testing/selftests/kvm/lib/kvm_util_internal.h67
-rw-r--r--tools/testing/selftests/kvm/lib/sparsebit.c2087
-rw-r--r--tools/testing/selftests/kvm/lib/vmx.c243
-rw-r--r--tools/testing/selftests/kvm/lib/x86.c700
-rw-r--r--tools/testing/selftests/kvm/set_sregs_test.c54
-rw-r--r--tools/testing/selftests/kvm/sync_regs_test.c232
-rw-r--r--tools/testing/selftests/kvm/vmx_tsc_adjust_test.c231
-rw-r--r--tools/testing/selftests/lib.mk1
-rw-r--r--tools/testing/selftests/powerpc/benchmarks/.gitignore2
-rw-r--r--tools/testing/selftests/powerpc/benchmarks/Makefile7
-rw-r--r--tools/testing/selftests/powerpc/benchmarks/exec_target.c13
-rw-r--r--tools/testing/selftests/powerpc/benchmarks/fork.c325
-rw-r--r--tools/testing/selftests/powerpc/copyloops/Makefile4
-rw-r--r--tools/testing/selftests/powerpc/tm/Makefile2
-rw-r--r--tools/testing/selftests/powerpc/tm/tm-sigreturn.c92
-rw-r--r--tools/testing/selftests/powerpc/tm/tm-unavailable.c24
-rw-r--r--tools/testing/selftests/proc/.gitignore8
-rw-r--r--tools/testing/selftests/proc/Makefile13
-rw-r--r--tools/testing/selftests/proc/config1
-rw-r--r--tools/testing/selftests/proc/proc-loadavg-001.c83
-rw-r--r--tools/testing/selftests/proc/proc-self-map-files-001.c82
-rw-r--r--tools/testing/selftests/proc/proc-self-map-files-002.c85
-rw-r--r--tools/testing/selftests/proc/proc-self-syscall.c60
-rw-r--r--tools/testing/selftests/proc/proc-self-wchan.c40
-rw-r--r--tools/testing/selftests/proc/proc-uptime-001.c45
-rw-r--r--tools/testing/selftests/proc/proc-uptime-002.c79
-rw-r--r--tools/testing/selftests/proc/proc-uptime.h74
-rw-r--r--tools/testing/selftests/proc/read.c147
-rw-r--r--tools/testing/selftests/seccomp/seccomp_bpf.c15
-rw-r--r--tools/thermal/tmon/sysfs.c12
-rw-r--r--tools/thermal/tmon/tmon.c1
-rw-r--r--tools/virtio/ringtest/ptr_ring.c5
101 files changed, 10999 insertions, 569 deletions
diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h
index f41079da38c5..d554c11e01ff 100644
--- a/tools/arch/x86/include/asm/cpufeatures.h
+++ b/tools/arch/x86/include/asm/cpufeatures.h
@@ -316,6 +316,7 @@
316#define X86_FEATURE_VPCLMULQDQ (16*32+10) /* Carry-Less Multiplication Double Quadword */ 316#define X86_FEATURE_VPCLMULQDQ (16*32+10) /* Carry-Less Multiplication Double Quadword */
317#define X86_FEATURE_AVX512_VNNI (16*32+11) /* Vector Neural Network Instructions */ 317#define X86_FEATURE_AVX512_VNNI (16*32+11) /* Vector Neural Network Instructions */
318#define X86_FEATURE_AVX512_BITALG (16*32+12) /* Support for VPOPCNT[B,W] and VPSHUF-BITQMB instructions */ 318#define X86_FEATURE_AVX512_BITALG (16*32+12) /* Support for VPOPCNT[B,W] and VPSHUF-BITQMB instructions */
319#define X86_FEATURE_TME (16*32+13) /* Intel Total Memory Encryption */
319#define X86_FEATURE_AVX512_VPOPCNTDQ (16*32+14) /* POPCNT for vectors of DW/QW */ 320#define X86_FEATURE_AVX512_VPOPCNTDQ (16*32+14) /* POPCNT for vectors of DW/QW */
320#define X86_FEATURE_LA57 (16*32+16) /* 5-level page tables */ 321#define X86_FEATURE_LA57 (16*32+16) /* 5-level page tables */
321#define X86_FEATURE_RDPID (16*32+22) /* RDPID instruction */ 322#define X86_FEATURE_RDPID (16*32+22) /* RDPID instruction */
@@ -328,6 +329,7 @@
328/* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */ 329/* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */
329#define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* AVX-512 Neural Network Instructions */ 330#define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* AVX-512 Neural Network Instructions */
330#define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */ 331#define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */
332#define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */
331#define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */ 333#define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */
332#define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */ 334#define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */
333#define X86_FEATURE_ARCH_CAPABILITIES (18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */ 335#define X86_FEATURE_ARCH_CAPABILITIES (18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */
diff --git a/tools/build/Build.include b/tools/build/Build.include
index 418871d02ebf..a4bbb984941d 100644
--- a/tools/build/Build.include
+++ b/tools/build/Build.include
@@ -12,6 +12,7 @@
12# Convenient variables 12# Convenient variables
13comma := , 13comma := ,
14squote := ' 14squote := '
15pound := \#
15 16
16### 17###
17# Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o 18# Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o
@@ -43,11 +44,11 @@ echo-cmd = $(if $($(quiet)cmd_$(1)),\
43### 44###
44# Replace >$< with >$$< to preserve $ when reloading the .cmd file 45# Replace >$< with >$$< to preserve $ when reloading the .cmd file
45# (needed for make) 46# (needed for make)
46# Replace >#< with >\#< to avoid starting a comment in the .cmd file 47# Replace >#< with >$(pound)< to avoid starting a comment in the .cmd file
47# (needed for make) 48# (needed for make)
48# Replace >'< with >'\''< to be able to enclose the whole string in '...' 49# Replace >'< with >'\''< to be able to enclose the whole string in '...'
49# (needed for the shell) 50# (needed for the shell)
50make-cmd = $(call escsq,$(subst \#,\\\#,$(subst $$,$$$$,$(cmd_$(1))))) 51make-cmd = $(call escsq,$(subst $(pound),$$(pound),$(subst $$,$$$$,$(cmd_$(1)))))
51 52
52### 53###
53# Find any prerequisites that is newer than target or that does not exist. 54# Find any prerequisites that is newer than target or that does not exist.
diff --git a/tools/include/linux/spinlock.h b/tools/include/linux/spinlock.h
index 4ed569fcb139..b21b586b9854 100644
--- a/tools/include/linux/spinlock.h
+++ b/tools/include/linux/spinlock.h
@@ -7,6 +7,7 @@
7 7
8#define spinlock_t pthread_mutex_t 8#define spinlock_t pthread_mutex_t
9#define DEFINE_SPINLOCK(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER; 9#define DEFINE_SPINLOCK(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER;
10#define __SPIN_LOCK_UNLOCKED(x) (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER
10 11
11#define spin_lock_irqsave(x, f) (void)f, pthread_mutex_lock(x) 12#define spin_lock_irqsave(x, f) (void)f, pthread_mutex_lock(x)
12#define spin_unlock_irqrestore(x, f) (void)f, pthread_mutex_unlock(x) 13#define spin_unlock_irqrestore(x, f) (void)f, pthread_mutex_unlock(x)
diff --git a/tools/include/tools/config.h b/tools/include/tools/config.h
new file mode 100644
index 000000000000..08ade7df8132
--- /dev/null
+++ b/tools/include/tools/config.h
@@ -0,0 +1,34 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _TOOLS_CONFIG_H
3#define _TOOLS_CONFIG_H
4
5/* Subset of include/linux/kconfig.h */
6
7#define __ARG_PLACEHOLDER_1 0,
8#define __take_second_arg(__ignored, val, ...) val
9
10/*
11 * Helper macros to use CONFIG_ options in C/CPP expressions. Note that
12 * these only work with boolean and tristate options.
13 */
14
15/*
16 * Getting something that works in C and CPP for an arg that may or may
17 * not be defined is tricky. Here, if we have "#define CONFIG_BOOGER 1"
18 * we match on the placeholder define, insert the "0," for arg1 and generate
19 * the triplet (0, 1, 0). Then the last step cherry picks the 2nd arg (a one).
20 * When CONFIG_BOOGER is not defined, we generate a (... 1, 0) pair, and when
21 * the last step cherry picks the 2nd arg, we get a zero.
22 */
23#define __is_defined(x) ___is_defined(x)
24#define ___is_defined(val) ____is_defined(__ARG_PLACEHOLDER_##val)
25#define ____is_defined(arg1_or_junk) __take_second_arg(arg1_or_junk 1, 0)
26
27/*
28 * IS_BUILTIN(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y', 0
29 * otherwise. For boolean options, this is equivalent to
30 * IS_ENABLED(CONFIG_FOO).
31 */
32#define IS_BUILTIN(option) __is_defined(option)
33
34#endif /* _TOOLS_CONFIG_H */
diff --git a/tools/include/uapi/drm/i915_drm.h b/tools/include/uapi/drm/i915_drm.h
index 536ee4febd74..7f5634ce8e88 100644
--- a/tools/include/uapi/drm/i915_drm.h
+++ b/tools/include/uapi/drm/i915_drm.h
@@ -318,6 +318,7 @@ typedef struct _drm_i915_sarea {
318#define DRM_I915_PERF_OPEN 0x36 318#define DRM_I915_PERF_OPEN 0x36
319#define DRM_I915_PERF_ADD_CONFIG 0x37 319#define DRM_I915_PERF_ADD_CONFIG 0x37
320#define DRM_I915_PERF_REMOVE_CONFIG 0x38 320#define DRM_I915_PERF_REMOVE_CONFIG 0x38
321#define DRM_I915_QUERY 0x39
321 322
322#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) 323#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
323#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) 324#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -375,6 +376,7 @@ typedef struct _drm_i915_sarea {
375#define DRM_IOCTL_I915_PERF_OPEN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_OPEN, struct drm_i915_perf_open_param) 376#define DRM_IOCTL_I915_PERF_OPEN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_OPEN, struct drm_i915_perf_open_param)
376#define DRM_IOCTL_I915_PERF_ADD_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_ADD_CONFIG, struct drm_i915_perf_oa_config) 377#define DRM_IOCTL_I915_PERF_ADD_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_ADD_CONFIG, struct drm_i915_perf_oa_config)
377#define DRM_IOCTL_I915_PERF_REMOVE_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_REMOVE_CONFIG, __u64) 378#define DRM_IOCTL_I915_PERF_REMOVE_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_REMOVE_CONFIG, __u64)
379#define DRM_IOCTL_I915_QUERY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_QUERY, struct drm_i915_query)
378 380
379/* Allow drivers to submit batchbuffers directly to hardware, relying 381/* Allow drivers to submit batchbuffers directly to hardware, relying
380 * on the security mechanisms provided by hardware. 382 * on the security mechanisms provided by hardware.
@@ -1358,7 +1360,9 @@ struct drm_intel_overlay_attrs {
1358 * active on a given plane. 1360 * active on a given plane.
1359 */ 1361 */
1360 1362
1361#define I915_SET_COLORKEY_NONE (1<<0) /* disable color key matching */ 1363#define I915_SET_COLORKEY_NONE (1<<0) /* Deprecated. Instead set
1364 * flags==0 to disable colorkeying.
1365 */
1362#define I915_SET_COLORKEY_DESTINATION (1<<1) 1366#define I915_SET_COLORKEY_DESTINATION (1<<1)
1363#define I915_SET_COLORKEY_SOURCE (1<<2) 1367#define I915_SET_COLORKEY_SOURCE (1<<2)
1364struct drm_intel_sprite_colorkey { 1368struct drm_intel_sprite_colorkey {
@@ -1604,15 +1608,115 @@ struct drm_i915_perf_oa_config {
1604 __u32 n_flex_regs; 1608 __u32 n_flex_regs;
1605 1609
1606 /* 1610 /*
1607 * These fields are pointers to tuples of u32 values (register 1611 * These fields are pointers to tuples of u32 values (register address,
1608 * address, value). For example the expected length of the buffer 1612 * value). For example the expected length of the buffer pointed by
1609 * pointed by mux_regs_ptr is (2 * sizeof(u32) * n_mux_regs). 1613 * mux_regs_ptr is (2 * sizeof(u32) * n_mux_regs).
1610 */ 1614 */
1611 __u64 mux_regs_ptr; 1615 __u64 mux_regs_ptr;
1612 __u64 boolean_regs_ptr; 1616 __u64 boolean_regs_ptr;
1613 __u64 flex_regs_ptr; 1617 __u64 flex_regs_ptr;
1614}; 1618};
1615 1619
1620struct drm_i915_query_item {
1621 __u64 query_id;
1622#define DRM_I915_QUERY_TOPOLOGY_INFO 1
1623
1624 /*
1625 * When set to zero by userspace, this is filled with the size of the
1626 * data to be written at the data_ptr pointer. The kernel sets this
1627 * value to a negative value to signal an error on a particular query
1628 * item.
1629 */
1630 __s32 length;
1631
1632 /*
1633 * Unused for now. Must be cleared to zero.
1634 */
1635 __u32 flags;
1636
1637 /*
1638 * Data will be written at the location pointed by data_ptr when the
1639 * value of length matches the length of the data to be written by the
1640 * kernel.
1641 */
1642 __u64 data_ptr;
1643};
1644
1645struct drm_i915_query {
1646 __u32 num_items;
1647
1648 /*
1649 * Unused for now. Must be cleared to zero.
1650 */
1651 __u32 flags;
1652
1653 /*
1654 * This points to an array of num_items drm_i915_query_item structures.
1655 */
1656 __u64 items_ptr;
1657};
1658
1659/*
1660 * Data written by the kernel with query DRM_I915_QUERY_TOPOLOGY_INFO :
1661 *
1662 * data: contains the 3 pieces of information :
1663 *
1664 * - the slice mask with one bit per slice telling whether a slice is
1665 * available. The availability of slice X can be queried with the following
1666 * formula :
1667 *
1668 * (data[X / 8] >> (X % 8)) & 1
1669 *
1670 * - the subslice mask for each slice with one bit per subslice telling
1671 * whether a subslice is available. The availability of subslice Y in slice
1672 * X can be queried with the following formula :
1673 *
1674 * (data[subslice_offset +
1675 * X * subslice_stride +
1676 * Y / 8] >> (Y % 8)) & 1
1677 *
1678 * - the EU mask for each subslice in each slice with one bit per EU telling
1679 * whether an EU is available. The availability of EU Z in subslice Y in
1680 * slice X can be queried with the following formula :
1681 *
1682 * (data[eu_offset +
1683 * (X * max_subslices + Y) * eu_stride +
1684 * Z / 8] >> (Z % 8)) & 1
1685 */
1686struct drm_i915_query_topology_info {
1687 /*
1688 * Unused for now. Must be cleared to zero.
1689 */
1690 __u16 flags;
1691
1692 __u16 max_slices;
1693 __u16 max_subslices;
1694 __u16 max_eus_per_subslice;
1695
1696 /*
1697 * Offset in data[] at which the subslice masks are stored.
1698 */
1699 __u16 subslice_offset;
1700
1701 /*
1702 * Stride at which each of the subslice masks for each slice are
1703 * stored.
1704 */
1705 __u16 subslice_stride;
1706
1707 /*
1708 * Offset in data[] at which the EU masks are stored.
1709 */
1710 __u16 eu_offset;
1711
1712 /*
1713 * Stride at which each of the EU masks for each subslice are stored.
1714 */
1715 __u16 eu_stride;
1716
1717 __u8 data[];
1718};
1719
1616#if defined(__cplusplus) 1720#if defined(__cplusplus)
1617} 1721}
1618#endif 1722#endif
diff --git a/tools/include/uapi/linux/kvm.h b/tools/include/uapi/linux/kvm.h
index 7b26d4b0b052..6b89f87db200 100644
--- a/tools/include/uapi/linux/kvm.h
+++ b/tools/include/uapi/linux/kvm.h
@@ -925,7 +925,7 @@ struct kvm_ppc_resize_hpt {
925#define KVM_CAP_S390_GS 140 925#define KVM_CAP_S390_GS 140
926#define KVM_CAP_S390_AIS 141 926#define KVM_CAP_S390_AIS 141
927#define KVM_CAP_SPAPR_TCE_VFIO 142 927#define KVM_CAP_SPAPR_TCE_VFIO 142
928#define KVM_CAP_X86_GUEST_MWAIT 143 928#define KVM_CAP_X86_DISABLE_EXITS 143
929#define KVM_CAP_ARM_USER_IRQ 144 929#define KVM_CAP_ARM_USER_IRQ 144
930#define KVM_CAP_S390_CMMA_MIGRATION 145 930#define KVM_CAP_S390_CMMA_MIGRATION 145
931#define KVM_CAP_PPC_FWNMI 146 931#define KVM_CAP_PPC_FWNMI 146
diff --git a/tools/kvm/kvm_stat/kvm_stat b/tools/kvm/kvm_stat/kvm_stat
index 5898c22ba310..56c4b3f8a01b 100755
--- a/tools/kvm/kvm_stat/kvm_stat
+++ b/tools/kvm/kvm_stat/kvm_stat
@@ -1121,9 +1121,6 @@ class Tui(object):
1121 self.screen.refresh() 1121 self.screen.refresh()
1122 1122
1123 def _refresh_body(self, sleeptime): 1123 def _refresh_body(self, sleeptime):
1124 def is_child_field(field):
1125 return field.find('(') != -1
1126
1127 def insert_child(sorted_items, child, values, parent): 1124 def insert_child(sorted_items, child, values, parent):
1128 num = len(sorted_items) 1125 num = len(sorted_items)
1129 for i in range(0, num): 1126 for i in range(0, num):
@@ -1134,12 +1131,14 @@ class Tui(object):
1134 def get_sorted_events(self, stats): 1131 def get_sorted_events(self, stats):
1135 """ separate parent and child events """ 1132 """ separate parent and child events """
1136 if self._sorting == SORT_DEFAULT: 1133 if self._sorting == SORT_DEFAULT:
1137 def sortkey((_k, v)): 1134 def sortkey(pair):
1138 # sort by (delta value, overall value) 1135 # sort by (delta value, overall value)
1136 v = pair[1]
1139 return (v.delta, v.value) 1137 return (v.delta, v.value)
1140 else: 1138 else:
1141 def sortkey((_k, v)): 1139 def sortkey(pair):
1142 # sort by overall value 1140 # sort by overall value
1141 v = pair[1]
1143 return v.value 1142 return v.value
1144 1143
1145 childs = [] 1144 childs = []
@@ -1613,7 +1612,7 @@ def assign_globals():
1613 global PATH_DEBUGFS_TRACING 1612 global PATH_DEBUGFS_TRACING
1614 1613
1615 debugfs = '' 1614 debugfs = ''
1616 for line in file('/proc/mounts'): 1615 for line in open('/proc/mounts'):
1617 if line.split(' ')[0] == 'debugfs': 1616 if line.split(' ')[0] == 'debugfs':
1618 debugfs = line.split(' ')[1] 1617 debugfs = line.split(' ')[1]
1619 break 1618 break
diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
index e6acc281dd37..8ae824dbfca3 100644
--- a/tools/objtool/Makefile
+++ b/tools/objtool/Makefile
@@ -35,7 +35,7 @@ CFLAGS += -Wall -Werror $(WARNINGS) -fomit-frame-pointer -O2 -g $(INCLUDES)
35LDFLAGS += -lelf $(LIBSUBCMD) 35LDFLAGS += -lelf $(LIBSUBCMD)
36 36
37# Allow old libelf to be used: 37# Allow old libelf to be used:
38elfshdr := $(shell echo '\#include <libelf.h>' | $(CC) $(CFLAGS) -x c -E - | grep elf_getshdr) 38elfshdr := $(shell echo '$(pound)include <libelf.h>' | $(CC) $(CFLAGS) -x c -E - | grep elf_getshdr)
39CFLAGS += $(if $(elfshdr),,-DLIBELF_USE_DEPRECATED) 39CFLAGS += $(if $(elfshdr),,-DLIBELF_USE_DEPRECATED)
40 40
41AWK = awk 41AWK = awk
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index e1a660e60849..917e36fde6d8 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -80,6 +80,7 @@ OPTIONS
80 - comm: command (name) of the task which can be read via /proc/<pid>/comm 80 - comm: command (name) of the task which can be read via /proc/<pid>/comm
81 - pid: command and tid of the task 81 - pid: command and tid of the task
82 - dso: name of library or module executed at the time of sample 82 - dso: name of library or module executed at the time of sample
83 - dso_size: size of library or module executed at the time of sample
83 - symbol: name of function executed at the time of sample 84 - symbol: name of function executed at the time of sample
84 - symbol_size: size of function executed at the time of sample 85 - symbol_size: size of function executed at the time of sample
85 - parent: name of function matched to the parent regex filter. Unmatched 86 - parent: name of function matched to the parent regex filter. Unmatched
diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt
index 5a7035c5c523..115db9e06ecd 100644
--- a/tools/perf/Documentation/perf-trace.txt
+++ b/tools/perf/Documentation/perf-trace.txt
@@ -117,6 +117,9 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs.
117--sched:: 117--sched::
118 Accrue thread runtime and provide a summary at the end of the session. 118 Accrue thread runtime and provide a summary at the end of the session.
119 119
120--failure::
121 Show only syscalls that failed, i.e. that returned < 0.
122
120-i:: 123-i::
121--input:: 124--input::
122 Process events from a given perf data file. 125 Process events from a given perf data file.
diff --git a/tools/perf/Documentation/perf-version.txt b/tools/perf/Documentation/perf-version.txt
new file mode 100644
index 000000000000..e207b7cfca26
--- /dev/null
+++ b/tools/perf/Documentation/perf-version.txt
@@ -0,0 +1,24 @@
1perf-version(1)
2===============
3
4NAME
5----
6perf-version - display the version of perf binary
7
8SYNOPSIS
9--------
10'perf version' [--build-options]
11
12DESCRIPTION
13-----------
14With no options given, the 'perf version' prints the perf version
15on the standard output.
16
17If the option '--build-options' is given, then the status of
18compiled-in libraries are printed on the standard output.
19
20OPTIONS
21-------
22--build-options::
23 Prints the status of compiled-in libraries on the
24 standard output.
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 98ff73648b51..c7abd83a8e19 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -346,12 +346,16 @@ else
346 ifneq ($(feature-dwarf_getlocations), 1) 346 ifneq ($(feature-dwarf_getlocations), 1)
347 msg := $(warning Old libdw.h, finding variables at given 'perf probe' point will not work, install elfutils-devel/libdw-dev >= 0.157); 347 msg := $(warning Old libdw.h, finding variables at given 'perf probe' point will not work, install elfutils-devel/libdw-dev >= 0.157);
348 else 348 else
349 CFLAGS += -DHAVE_DWARF_GETLOCATIONS 349 CFLAGS += -DHAVE_DWARF_GETLOCATIONS_SUPPORT
350 endif # dwarf_getlocations 350 endif # dwarf_getlocations
351 endif # Dwarf support 351 endif # Dwarf support
352 endif # libelf support 352 endif # libelf support
353endif # NO_LIBELF 353endif # NO_LIBELF
354 354
355ifeq ($(feature-glibc), 1)
356 CFLAGS += -DHAVE_GLIBC_SUPPORT
357endif
358
355ifdef NO_DWARF 359ifdef NO_DWARF
356 NO_LIBDW_DWARF_UNWIND := 1 360 NO_LIBDW_DWARF_UNWIND := 1
357endif 361endif
@@ -635,6 +639,7 @@ else
635 else 639 else
636 LDFLAGS += $(PERL_EMBED_LDFLAGS) 640 LDFLAGS += $(PERL_EMBED_LDFLAGS)
637 EXTLIBS += $(PERL_EMBED_LIBADD) 641 EXTLIBS += $(PERL_EMBED_LIBADD)
642 CFLAGS += -DHAVE_LIBPERL_SUPPORT
638 $(call detected,CONFIG_LIBPERL) 643 $(call detected,CONFIG_LIBPERL)
639 endif 644 endif
640endif 645endif
@@ -671,6 +676,7 @@ else
671 LDFLAGS += $(PYTHON_EMBED_LDFLAGS) 676 LDFLAGS += $(PYTHON_EMBED_LDFLAGS)
672 EXTLIBS += $(PYTHON_EMBED_LIBADD) 677 EXTLIBS += $(PYTHON_EMBED_LIBADD)
673 LANG_BINDINGS += $(obj-perf)python/perf.so 678 LANG_BINDINGS += $(obj-perf)python/perf.so
679 CFLAGS += -DHAVE_LIBPYTHON_SUPPORT
674 $(call detected,CONFIG_LIBPYTHON) 680 $(call detected,CONFIG_LIBPYTHON)
675 endif 681 endif
676 endif 682 endif
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index f7517e1b73f8..83e453de36f8 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -364,7 +364,8 @@ LIBS = -Wl,--whole-archive $(PERFLIBS) $(EXTRA_PERFLIBS) -Wl,--no-whole-archive
364 364
365ifeq ($(USE_CLANG), 1) 365ifeq ($(USE_CLANG), 1)
366 CLANGLIBS_LIST = AST Basic CodeGen Driver Frontend Lex Tooling Edit Sema Analysis Parse Serialization 366 CLANGLIBS_LIST = AST Basic CodeGen Driver Frontend Lex Tooling Edit Sema Analysis Parse Serialization
367 LIBCLANG = $(foreach l,$(CLANGLIBS_LIST),$(wildcard $(shell $(LLVM_CONFIG) --libdir)/libclang$(l).a)) 367 CLANGLIBS_NOEXT_LIST = $(foreach l,$(CLANGLIBS_LIST),$(shell $(LLVM_CONFIG) --libdir)/libclang$(l))
368 LIBCLANG = $(foreach l,$(CLANGLIBS_NOEXT_LIST),$(wildcard $(l).a $(l).so))
368 LIBS += -Wl,--start-group $(LIBCLANG) -Wl,--end-group 369 LIBS += -Wl,--start-group $(LIBCLANG) -Wl,--end-group
369endif 370endif
370 371
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 87b95c9410b4..3ad17ee89403 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -112,6 +112,7 @@ struct trace {
112 bool multiple_threads; 112 bool multiple_threads;
113 bool summary; 113 bool summary;
114 bool summary_only; 114 bool summary_only;
115 bool failure_only;
115 bool show_comm; 116 bool show_comm;
116 bool print_sample; 117 bool print_sample;
117 bool show_tool_stats; 118 bool show_tool_stats;
@@ -1565,7 +1566,7 @@ static int trace__printf_interrupted_entry(struct trace *trace)
1565 struct thread_trace *ttrace; 1566 struct thread_trace *ttrace;
1566 size_t printed; 1567 size_t printed;
1567 1568
1568 if (trace->current == NULL) 1569 if (trace->failure_only || trace->current == NULL)
1569 return 0; 1570 return 0;
1570 1571
1571 ttrace = thread__priv(trace->current); 1572 ttrace = thread__priv(trace->current);
@@ -1638,7 +1639,7 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
1638 args, trace, thread); 1639 args, trace, thread);
1639 1640
1640 if (sc->is_exit) { 1641 if (sc->is_exit) {
1641 if (!(trace->duration_filter || trace->summary_only || trace->min_stack)) { 1642 if (!(trace->duration_filter || trace->summary_only || trace->failure_only || trace->min_stack)) {
1642 trace__fprintf_entry_head(trace, thread, 0, false, ttrace->entry_time, trace->output); 1643 trace__fprintf_entry_head(trace, thread, 0, false, ttrace->entry_time, trace->output);
1643 fprintf(trace->output, "%-70s)\n", ttrace->entry_str); 1644 fprintf(trace->output, "%-70s)\n", ttrace->entry_str);
1644 } 1645 }
@@ -1742,7 +1743,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
1742 } 1743 }
1743 } 1744 }
1744 1745
1745 if (trace->summary_only) 1746 if (trace->summary_only || (ret >= 0 && trace->failure_only))
1746 goto out; 1747 goto out;
1747 1748
1748 trace__fprintf_entry_head(trace, thread, duration, duration_calculated, ttrace->entry_time, trace->output); 1749 trace__fprintf_entry_head(trace, thread, duration, duration_calculated, ttrace->entry_time, trace->output);
@@ -1961,7 +1962,7 @@ static int trace__event_handler(struct trace *trace, struct perf_evsel *evsel,
1961 trace->output); 1962 trace->output);
1962 } 1963 }
1963 1964
1964 fprintf(trace->output, ")\n"); 1965 fprintf(trace->output, "\n");
1965 1966
1966 if (callchain_ret > 0) 1967 if (callchain_ret > 0)
1967 trace__fprintf_callchain(trace, sample); 1968 trace__fprintf_callchain(trace, sample);
@@ -3087,6 +3088,8 @@ int cmd_trace(int argc, const char **argv)
3087 OPT_INCR('v', "verbose", &verbose, "be more verbose"), 3088 OPT_INCR('v', "verbose", &verbose, "be more verbose"),
3088 OPT_BOOLEAN('T', "time", &trace.full_time, 3089 OPT_BOOLEAN('T', "time", &trace.full_time,
3089 "Show full timestamp, not time relative to first start"), 3090 "Show full timestamp, not time relative to first start"),
3091 OPT_BOOLEAN(0, "failure", &trace.failure_only,
3092 "Show only syscalls that failed"),
3090 OPT_BOOLEAN('s', "summary", &trace.summary_only, 3093 OPT_BOOLEAN('s', "summary", &trace.summary_only,
3091 "Show only syscall summary with statistics"), 3094 "Show only syscall summary with statistics"),
3092 OPT_BOOLEAN('S', "with-summary", &trace.summary, 3095 OPT_BOOLEAN('S', "with-summary", &trace.summary,
diff --git a/tools/perf/builtin-version.c b/tools/perf/builtin-version.c
index 37019c5d675f..2abe3910d6b6 100644
--- a/tools/perf/builtin-version.c
+++ b/tools/perf/builtin-version.c
@@ -1,11 +1,91 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "builtin.h" 2#include "builtin.h"
3#include "perf.h" 3#include "perf.h"
4#include "color.h"
4#include <linux/compiler.h> 5#include <linux/compiler.h>
6#include <tools/config.h>
5#include <stdio.h> 7#include <stdio.h>
8#include <string.h>
9#include <subcmd/parse-options.h>
6 10
7int cmd_version(int argc __maybe_unused, const char **argv __maybe_unused) 11int version_verbose;
12
13struct version {
14 bool build_options;
15};
16
17static struct version version;
18
19static struct option version_options[] = {
20 OPT_BOOLEAN(0, "build-options", &version.build_options,
21 "display the build options"),
22};
23
24static const char * const version_usage[] = {
25 "perf version [<options>]",
26 NULL
27};
28
29static void on_off_print(const char *status)
30{
31 printf("[ ");
32
33 if (!strcmp(status, "OFF"))
34 color_fprintf(stdout, PERF_COLOR_RED, "%-3s", status);
35 else
36 color_fprintf(stdout, PERF_COLOR_GREEN, "%-3s", status);
37
38 printf(" ]");
39}
40
41static void status_print(const char *name, const char *macro,
42 const char *status)
8{ 43{
44 printf("%22s: ", name);
45 on_off_print(status);
46 printf(" # %s\n", macro);
47}
48
49#define STATUS(__d, __m) \
50do { \
51 if (IS_BUILTIN(__d)) \
52 status_print(#__m, #__d, "on"); \
53 else \
54 status_print(#__m, #__d, "OFF"); \
55} while (0)
56
57static void library_status(void)
58{
59 STATUS(HAVE_DWARF_SUPPORT, dwarf);
60 STATUS(HAVE_DWARF_GETLOCATIONS_SUPPORT, dwarf_getlocations);
61 STATUS(HAVE_GLIBC_SUPPORT, glibc);
62 STATUS(HAVE_GTK2_SUPPORT, gtk2);
63 STATUS(HAVE_LIBAUDIT_SUPPORT, libaudit);
64 STATUS(HAVE_LIBBFD_SUPPORT, libbfd);
65 STATUS(HAVE_LIBELF_SUPPORT, libelf);
66 STATUS(HAVE_LIBNUMA_SUPPORT, libnuma);
67 STATUS(HAVE_LIBNUMA_SUPPORT, numa_num_possible_cpus);
68 STATUS(HAVE_LIBPERL_SUPPORT, libperl);
69 STATUS(HAVE_LIBPYTHON_SUPPORT, libpython);
70 STATUS(HAVE_SLANG_SUPPORT, libslang);
71 STATUS(HAVE_LIBCRYPTO_SUPPORT, libcrypto);
72 STATUS(HAVE_LIBUNWIND_SUPPORT, libunwind);
73 STATUS(HAVE_DWARF_SUPPORT, libdw-dwarf-unwind);
74 STATUS(HAVE_ZLIB_SUPPORT, zlib);
75 STATUS(HAVE_LZMA_SUPPORT, lzma);
76 STATUS(HAVE_AUXTRACE_SUPPORT, get_cpuid);
77 STATUS(HAVE_LIBBPF_SUPPORT, bpf);
78}
79
80int cmd_version(int argc, const char **argv)
81{
82 argc = parse_options(argc, argv, version_options, version_usage,
83 PARSE_OPT_STOP_AT_NON_OPTION);
84
9 printf("perf version %s\n", perf_version_string); 85 printf("perf version %s\n", perf_version_string);
86
87 if (version.build_options || version_verbose == 1)
88 library_status();
89
10 return 0; 90 return 0;
11} 91}
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 1b3fc8ec0fa2..1659029d03fc 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -190,6 +190,12 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
190 break; 190 break;
191 } 191 }
192 192
193 if (!strcmp(cmd, "-vv")) {
194 (*argv)[0] = "version";
195 version_verbose = 1;
196 break;
197 }
198
193 /* 199 /*
194 * Check remaining flags. 200 * Check remaining flags.
195 */ 201 */
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index 8fec1abd0f1f..a1a97956136f 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -84,6 +84,7 @@ struct record_opts {
84struct option; 84struct option;
85extern const char * const *record_usage; 85extern const char * const *record_usage;
86extern struct option *record_options; 86extern struct option *record_options;
87extern int version_verbose;
87 88
88int record__parse_freq(const struct option *opt, const char *str, int unset); 89int record__parse_freq(const struct option *opt, const char *str, int unset);
89#endif 90#endif
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
index 9f6ce29b83b4..4f75561424ed 100644
--- a/tools/perf/ui/browser.c
+++ b/tools/perf/ui/browser.c
@@ -45,11 +45,16 @@ void ui_browser__set_percent_color(struct ui_browser *browser,
45 ui_browser__set_color(browser, color); 45 ui_browser__set_color(browser, color);
46} 46}
47 47
48void ui_browser__gotorc(struct ui_browser *browser, int y, int x) 48void ui_browser__gotorc_title(struct ui_browser *browser, int y, int x)
49{ 49{
50 SLsmg_gotorc(browser->y + y, browser->x + x); 50 SLsmg_gotorc(browser->y + y, browser->x + x);
51} 51}
52 52
53void ui_browser__gotorc(struct ui_browser *browser, int y, int x)
54{
55 SLsmg_gotorc(browser->y + y + browser->extra_title_lines, browser->x + x);
56}
57
53void ui_browser__write_nstring(struct ui_browser *browser __maybe_unused, const char *msg, 58void ui_browser__write_nstring(struct ui_browser *browser __maybe_unused, const char *msg,
54 unsigned int width) 59 unsigned int width)
55{ 60{
@@ -191,6 +196,7 @@ void ui_browser__refresh_dimensions(struct ui_browser *browser)
191{ 196{
192 browser->width = SLtt_Screen_Cols - 1; 197 browser->width = SLtt_Screen_Cols - 1;
193 browser->height = browser->rows = SLtt_Screen_Rows - 2; 198 browser->height = browser->rows = SLtt_Screen_Rows - 2;
199 browser->rows -= browser->extra_title_lines;
194 browser->y = 1; 200 browser->y = 1;
195 browser->x = 0; 201 browser->x = 0;
196} 202}
@@ -337,8 +343,8 @@ static int __ui_browser__refresh(struct ui_browser *browser)
337 else 343 else
338 width += 1; 344 width += 1;
339 345
340 SLsmg_fill_region(browser->y + row, browser->x, 346 SLsmg_fill_region(browser->y + row + browser->extra_title_lines, browser->x,
341 browser->height - row, width, ' '); 347 browser->rows - row, width, ' ');
342 348
343 return 0; 349 return 0;
344} 350}
diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h
index 70057178ee34..aa5932e1d62e 100644
--- a/tools/perf/ui/browser.h
+++ b/tools/perf/ui/browser.h
@@ -17,6 +17,7 @@ struct ui_browser {
17 u64 index, top_idx; 17 u64 index, top_idx;
18 void *top, *entries; 18 void *top, *entries;
19 u16 y, x, width, height, rows, columns, horiz_scroll; 19 u16 y, x, width, height, rows, columns, horiz_scroll;
20 u8 extra_title_lines;
20 int current_color; 21 int current_color;
21 void *priv; 22 void *priv;
22 const char *title; 23 const char *title;
@@ -38,6 +39,7 @@ bool ui_browser__is_current_entry(struct ui_browser *browser, unsigned row);
38void ui_browser__refresh_dimensions(struct ui_browser *browser); 39void ui_browser__refresh_dimensions(struct ui_browser *browser);
39void ui_browser__reset_index(struct ui_browser *browser); 40void ui_browser__reset_index(struct ui_browser *browser);
40 41
42void ui_browser__gotorc_title(struct ui_browser *browser, int y, int x);
41void ui_browser__gotorc(struct ui_browser *browser, int y, int x); 43void ui_browser__gotorc(struct ui_browser *browser, int y, int x);
42void ui_browser__write_nstring(struct ui_browser *browser, const char *msg, 44void ui_browser__write_nstring(struct ui_browser *browser, const char *msg,
43 unsigned int width); 45 unsigned int width);
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index c02fb437ac8e..12c099a87f8b 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -218,7 +218,7 @@ static unsigned int annotate_browser__refresh(struct ui_browser *browser)
218 annotate_browser__draw_current_jump(browser); 218 annotate_browser__draw_current_jump(browser);
219 219
220 ui_browser__set_color(browser, HE_COLORSET_NORMAL); 220 ui_browser__set_color(browser, HE_COLORSET_NORMAL);
221 __ui_browser__vline(browser, pcnt_width, 0, browser->height - 1); 221 __ui_browser__vline(browser, pcnt_width, 0, browser->rows - 1);
222 return ret; 222 return ret;
223} 223}
224 224
@@ -592,21 +592,40 @@ bool annotate_browser__continue_search_reverse(struct annotate_browser *browser,
592 return __annotate_browser__search_reverse(browser); 592 return __annotate_browser__search_reverse(browser);
593} 593}
594 594
595static int annotate_browser__show(struct ui_browser *browser, char *title, const char *help)
596{
597 struct map_symbol *ms = browser->priv;
598 struct symbol *sym = ms->sym;
599 char symbol_dso[SYM_TITLE_MAX_SIZE];
600
601 if (ui_browser__show(browser, title, help) < 0)
602 return -1;
603
604 sym_title(sym, ms->map, symbol_dso, sizeof(symbol_dso));
605
606 ui_browser__gotorc_title(browser, 0, 0);
607 ui_browser__set_color(browser, HE_COLORSET_ROOT);
608 ui_browser__write_nstring(browser, symbol_dso, browser->width + 1);
609 return 0;
610}
611
595static int annotate_browser__run(struct annotate_browser *browser, 612static int annotate_browser__run(struct annotate_browser *browser,
596 struct perf_evsel *evsel, 613 struct perf_evsel *evsel,
597 struct hist_browser_timer *hbt) 614 struct hist_browser_timer *hbt)
598{ 615{
599 struct rb_node *nd = NULL; 616 struct rb_node *nd = NULL;
617 struct hists *hists = evsel__hists(evsel);
600 struct map_symbol *ms = browser->b.priv; 618 struct map_symbol *ms = browser->b.priv;
601 struct symbol *sym = ms->sym; 619 struct symbol *sym = ms->sym;
602 struct annotation *notes = symbol__annotation(ms->sym); 620 struct annotation *notes = symbol__annotation(ms->sym);
603 const char *help = "Press 'h' for help on key bindings"; 621 const char *help = "Press 'h' for help on key bindings";
604 int delay_secs = hbt ? hbt->refresh : 0; 622 int delay_secs = hbt ? hbt->refresh : 0;
623 char title[256];
605 int key; 624 int key;
606 char title[SYM_TITLE_MAX_SIZE];
607 625
608 sym_title(sym, ms->map, title, sizeof(title)); 626 annotation__scnprintf_samples_period(notes, title, sizeof(title), evsel);
609 if (ui_browser__show(&browser->b, title, help) < 0) 627
628 if (annotate_browser__show(&browser->b, title, help) < 0)
610 return -1; 629 return -1;
611 630
612 annotate_browser__calc_percent(browser, evsel); 631 annotate_browser__calc_percent(browser, evsel);
@@ -637,8 +656,11 @@ static int annotate_browser__run(struct annotate_browser *browser,
637 if (hbt) 656 if (hbt)
638 hbt->timer(hbt->arg); 657 hbt->timer(hbt->arg);
639 658
640 if (delay_secs != 0) 659 if (delay_secs != 0) {
641 symbol__annotate_decay_histogram(sym, evsel->idx); 660 symbol__annotate_decay_histogram(sym, evsel->idx);
661 hists__scnprintf_title(hists, title, sizeof(title));
662 annotate_browser__show(&browser->b, title, help);
663 }
642 continue; 664 continue;
643 case K_TAB: 665 case K_TAB:
644 if (nd != NULL) { 666 if (nd != NULL) {
@@ -812,6 +834,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,
812 .seek = ui_browser__list_head_seek, 834 .seek = ui_browser__list_head_seek,
813 .write = annotate_browser__write, 835 .write = annotate_browser__write,
814 .filter = disasm_line__filter, 836 .filter = disasm_line__filter,
837 .extra_title_lines = 1, /* for hists__scnprintf_title() */
815 .priv = &ms, 838 .priv = &ms,
816 .use_navkeypressed = true, 839 .use_navkeypressed = true,
817 }, 840 },
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 8b4e82548f8e..0eec06c105c6 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -32,8 +32,7 @@
32 32
33extern void hist_browser__init_hpp(void); 33extern void hist_browser__init_hpp(void);
34 34
35static int perf_evsel_browser_title(struct hist_browser *browser, 35static int hists_browser__scnprintf_title(struct hist_browser *browser, char *bf, size_t size);
36 char *bf, size_t size);
37static void hist_browser__update_nr_entries(struct hist_browser *hb); 36static void hist_browser__update_nr_entries(struct hist_browser *hb);
38 37
39static struct rb_node *hists__filter_entries(struct rb_node *nd, 38static struct rb_node *hists__filter_entries(struct rb_node *nd,
@@ -62,6 +61,15 @@ static int hist_browser__get_folding(struct hist_browser *browser)
62 return unfolded_rows; 61 return unfolded_rows;
63} 62}
64 63
64static void hist_browser__set_title_space(struct hist_browser *hb)
65{
66 struct ui_browser *browser = &hb->b;
67 struct hists *hists = hb->hists;
68 struct perf_hpp_list *hpp_list = hists->hpp_list;
69
70 browser->extra_title_lines = hb->show_headers ? hpp_list->nr_header_lines : 0;
71}
72
65static u32 hist_browser__nr_entries(struct hist_browser *hb) 73static u32 hist_browser__nr_entries(struct hist_browser *hb)
66{ 74{
67 u32 nr_entries; 75 u32 nr_entries;
@@ -82,10 +90,16 @@ static void hist_browser__update_rows(struct hist_browser *hb)
82 struct ui_browser *browser = &hb->b; 90 struct ui_browser *browser = &hb->b;
83 struct hists *hists = hb->hists; 91 struct hists *hists = hb->hists;
84 struct perf_hpp_list *hpp_list = hists->hpp_list; 92 struct perf_hpp_list *hpp_list = hists->hpp_list;
85 u16 header_offset, index_row; 93 u16 index_row;
86 94
87 header_offset = hb->show_headers ? hpp_list->nr_header_lines : 0; 95 if (!hb->show_headers) {
88 browser->rows = browser->height - header_offset; 96 browser->rows += browser->extra_title_lines;
97 browser->extra_title_lines = 0;
98 return;
99 }
100
101 browser->extra_title_lines = hpp_list->nr_header_lines;
102 browser->rows -= browser->extra_title_lines;
89 /* 103 /*
90 * Verify if we were at the last line and that line isn't 104 * Verify if we were at the last line and that line isn't
91 * visibe because we now show the header line(s). 105 * visibe because we now show the header line(s).
@@ -108,17 +122,6 @@ static void hist_browser__refresh_dimensions(struct ui_browser *browser)
108 * changeset. 122 * changeset.
109 */ 123 */
110 ui_browser__refresh_dimensions(browser); 124 ui_browser__refresh_dimensions(browser);
111 hist_browser__update_rows(hb);
112}
113
114static void hist_browser__gotorc(struct hist_browser *browser, int row, int column)
115{
116 struct hists *hists = browser->hists;
117 struct perf_hpp_list *hpp_list = hists->hpp_list;
118 u16 header_offset;
119
120 header_offset = browser->show_headers ? hpp_list->nr_header_lines : 0;
121 ui_browser__gotorc(&browser->b, row + header_offset, column);
122} 125}
123 126
124static void hist_browser__reset(struct hist_browser *browser) 127static void hist_browser__reset(struct hist_browser *browser)
@@ -656,9 +659,10 @@ int hist_browser__run(struct hist_browser *browser, const char *help,
656 struct hist_entry *h = rb_entry(browser->b.top, 659 struct hist_entry *h = rb_entry(browser->b.top,
657 struct hist_entry, rb_node); 660 struct hist_entry, rb_node);
658 ui_helpline__pop(); 661 ui_helpline__pop();
659 ui_helpline__fpush("%d: nr_ent=(%d,%d), rows=%d, idx=%d, fve: idx=%d, row_off=%d, nrows=%d", 662 ui_helpline__fpush("%d: nr_ent=(%d,%d), etl: %d, rows=%d, idx=%d, fve: idx=%d, row_off=%d, nrows=%d",
660 seq++, browser->b.nr_entries, 663 seq++, browser->b.nr_entries,
661 browser->hists->nr_entries, 664 browser->hists->nr_entries,
665 browser->b.extra_title_lines,
662 browser->b.rows, 666 browser->b.rows,
663 browser->b.index, 667 browser->b.index,
664 browser->b.top_idx, 668 browser->b.top_idx,
@@ -733,7 +737,7 @@ static void hist_browser__show_callchain_entry(struct hist_browser *browser,
733 } 737 }
734 738
735 ui_browser__set_color(&browser->b, color); 739 ui_browser__set_color(&browser->b, color);
736 hist_browser__gotorc(browser, row, 0); 740 ui_browser__gotorc(&browser->b, row, 0);
737 ui_browser__write_nstring(&browser->b, " ", offset); 741 ui_browser__write_nstring(&browser->b, " ", offset);
738 ui_browser__printf(&browser->b, "%c", folded_sign); 742 ui_browser__printf(&browser->b, "%c", folded_sign);
739 ui_browser__write_graph(&browser->b, show_annotated ? SLSMG_RARROW_CHAR : ' '); 743 ui_browser__write_graph(&browser->b, show_annotated ? SLSMG_RARROW_CHAR : ' ');
@@ -1249,7 +1253,7 @@ static int hist_browser__show_entry(struct hist_browser *browser,
1249 }; 1253 };
1250 int column = 0; 1254 int column = 0;
1251 1255
1252 hist_browser__gotorc(browser, row, 0); 1256 ui_browser__gotorc(&browser->b, row, 0);
1253 1257
1254 hists__for_each_format(browser->hists, fmt) { 1258 hists__for_each_format(browser->hists, fmt) {
1255 char s[2048]; 1259 char s[2048];
@@ -1358,7 +1362,7 @@ static int hist_browser__show_hierarchy_entry(struct hist_browser *browser,
1358 goto show_callchain; 1362 goto show_callchain;
1359 } 1363 }
1360 1364
1361 hist_browser__gotorc(browser, row, 0); 1365 ui_browser__gotorc(&browser->b, row, 0);
1362 1366
1363 if (current_entry && browser->b.navkeypressed) 1367 if (current_entry && browser->b.navkeypressed)
1364 ui_browser__set_color(&browser->b, HE_COLORSET_SELECTED); 1368 ui_browser__set_color(&browser->b, HE_COLORSET_SELECTED);
@@ -1507,7 +1511,7 @@ static int hist_browser__show_no_entry(struct hist_browser *browser,
1507 browser->selection = NULL; 1511 browser->selection = NULL;
1508 } 1512 }
1509 1513
1510 hist_browser__gotorc(browser, row, 0); 1514 ui_browser__gotorc(&browser->b, row, 0);
1511 1515
1512 if (current_entry && browser->b.navkeypressed) 1516 if (current_entry && browser->b.navkeypressed)
1513 ui_browser__set_color(&browser->b, HE_COLORSET_SELECTED); 1517 ui_browser__set_color(&browser->b, HE_COLORSET_SELECTED);
@@ -1713,7 +1717,7 @@ static void hists_browser__headers(struct hist_browser *browser)
1713 hists_browser__scnprintf_headers(browser, headers, 1717 hists_browser__scnprintf_headers(browser, headers,
1714 sizeof(headers), line); 1718 sizeof(headers), line);
1715 1719
1716 ui_browser__gotorc(&browser->b, line, 0); 1720 ui_browser__gotorc_title(&browser->b, line, 0);
1717 ui_browser__set_color(&browser->b, HE_COLORSET_ROOT); 1721 ui_browser__set_color(&browser->b, HE_COLORSET_ROOT);
1718 ui_browser__write_nstring(&browser->b, headers, browser->b.width + 1); 1722 ui_browser__write_nstring(&browser->b, headers, browser->b.width + 1);
1719 } 1723 }
@@ -1740,17 +1744,11 @@ static void ui_browser__hists_init_top(struct ui_browser *browser)
1740static unsigned int hist_browser__refresh(struct ui_browser *browser) 1744static unsigned int hist_browser__refresh(struct ui_browser *browser)
1741{ 1745{
1742 unsigned row = 0; 1746 unsigned row = 0;
1743 u16 header_offset = 0;
1744 struct rb_node *nd; 1747 struct rb_node *nd;
1745 struct hist_browser *hb = container_of(browser, struct hist_browser, b); 1748 struct hist_browser *hb = container_of(browser, struct hist_browser, b);
1746 struct hists *hists = hb->hists;
1747
1748 if (hb->show_headers) {
1749 struct perf_hpp_list *hpp_list = hists->hpp_list;
1750 1749
1750 if (hb->show_headers)
1751 hist_browser__show_headers(hb); 1751 hist_browser__show_headers(hb);
1752 header_offset = hpp_list->nr_header_lines;
1753 }
1754 1752
1755 ui_browser__hists_init_top(browser); 1753 ui_browser__hists_init_top(browser);
1756 hb->he_selection = NULL; 1754 hb->he_selection = NULL;
@@ -1788,7 +1786,7 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser)
1788 break; 1786 break;
1789 } 1787 }
1790 1788
1791 return row + header_offset; 1789 return row;
1792} 1790}
1793 1791
1794static struct rb_node *hists__filter_entries(struct rb_node *nd, 1792static struct rb_node *hists__filter_entries(struct rb_node *nd,
@@ -2143,6 +2141,7 @@ void hist_browser__init(struct hist_browser *browser,
2143 browser->b.seek = ui_browser__hists_seek; 2141 browser->b.seek = ui_browser__hists_seek;
2144 browser->b.use_navkeypressed = true; 2142 browser->b.use_navkeypressed = true;
2145 browser->show_headers = symbol_conf.show_hist_headers; 2143 browser->show_headers = symbol_conf.show_hist_headers;
2144 hist_browser__set_title_space(browser);
2146 2145
2147 if (symbol_conf.report_hierarchy) { 2146 if (symbol_conf.report_hierarchy) {
2148 struct perf_hpp_list_node *fmt_node; 2147 struct perf_hpp_list_node *fmt_node;
@@ -2183,7 +2182,7 @@ perf_evsel_browser__new(struct perf_evsel *evsel,
2183 if (browser) { 2182 if (browser) {
2184 browser->hbt = hbt; 2183 browser->hbt = hbt;
2185 browser->env = env; 2184 browser->env = env;
2186 browser->title = perf_evsel_browser_title; 2185 browser->title = hists_browser__scnprintf_title;
2187 } 2186 }
2188 return browser; 2187 return browser;
2189} 2188}
@@ -2209,84 +2208,11 @@ static inline bool is_report_browser(void *timer)
2209 return timer == NULL; 2208 return timer == NULL;
2210} 2209}
2211 2210
2212static int perf_evsel_browser_title(struct hist_browser *browser, 2211static int hists_browser__scnprintf_title(struct hist_browser *browser, char *bf, size_t size)
2213 char *bf, size_t size)
2214{ 2212{
2215 struct hist_browser_timer *hbt = browser->hbt; 2213 struct hist_browser_timer *hbt = browser->hbt;
2216 struct hists *hists = browser->hists; 2214 int printed = __hists__scnprintf_title(browser->hists, bf, size, !is_report_browser(hbt));
2217 char unit;
2218 int printed;
2219 const struct dso *dso = hists->dso_filter;
2220 const struct thread *thread = hists->thread_filter;
2221 int socket_id = hists->socket_filter;
2222 unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
2223 u64 nr_events = hists->stats.total_period;
2224 struct perf_evsel *evsel = hists_to_evsel(hists);
2225 const char *ev_name = perf_evsel__name(evsel);
2226 char buf[512], sample_freq_str[64] = "";
2227 size_t buflen = sizeof(buf);
2228 char ref[30] = " show reference callgraph, ";
2229 bool enable_ref = false;
2230 2215
2231 if (symbol_conf.filter_relative) {
2232 nr_samples = hists->stats.nr_non_filtered_samples;
2233 nr_events = hists->stats.total_non_filtered_period;
2234 }
2235
2236 if (perf_evsel__is_group_event(evsel)) {
2237 struct perf_evsel *pos;
2238
2239 perf_evsel__group_desc(evsel, buf, buflen);
2240 ev_name = buf;
2241
2242 for_each_group_member(pos, evsel) {
2243 struct hists *pos_hists = evsel__hists(pos);
2244
2245 if (symbol_conf.filter_relative) {
2246 nr_samples += pos_hists->stats.nr_non_filtered_samples;
2247 nr_events += pos_hists->stats.total_non_filtered_period;
2248 } else {
2249 nr_samples += pos_hists->stats.nr_events[PERF_RECORD_SAMPLE];
2250 nr_events += pos_hists->stats.total_period;
2251 }
2252 }
2253 }
2254
2255 if (symbol_conf.show_ref_callgraph &&
2256 strstr(ev_name, "call-graph=no"))
2257 enable_ref = true;
2258
2259 if (!is_report_browser(hbt))
2260 scnprintf(sample_freq_str, sizeof(sample_freq_str), " %d Hz,", evsel->attr.sample_freq);
2261
2262 nr_samples = convert_unit(nr_samples, &unit);
2263 printed = scnprintf(bf, size,
2264 "Samples: %lu%c of event%s '%s',%s%sEvent count (approx.): %" PRIu64,
2265 nr_samples, unit, evsel->nr_members > 1 ? "s" : "",
2266 ev_name, sample_freq_str, enable_ref ? ref : " ", nr_events);
2267
2268
2269 if (hists->uid_filter_str)
2270 printed += snprintf(bf + printed, size - printed,
2271 ", UID: %s", hists->uid_filter_str);
2272 if (thread) {
2273 if (hists__has(hists, thread)) {
2274 printed += scnprintf(bf + printed, size - printed,
2275 ", Thread: %s(%d)",
2276 (thread->comm_set ? thread__comm_str(thread) : ""),
2277 thread->tid);
2278 } else {
2279 printed += scnprintf(bf + printed, size - printed,
2280 ", Thread: %s",
2281 (thread->comm_set ? thread__comm_str(thread) : ""));
2282 }
2283 }
2284 if (dso)
2285 printed += scnprintf(bf + printed, size - printed,
2286 ", DSO: %s", dso->short_name);
2287 if (socket_id > -1)
2288 printed += scnprintf(bf + printed, size - printed,
2289 ", Processor Socket: %d", socket_id);
2290 if (!is_report_browser(hbt)) { 2216 if (!is_report_browser(hbt)) {
2291 struct perf_top *top = hbt->arg; 2217 struct perf_top *top = hbt->arg;
2292 2218
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 3a428d7c59b9..fbad8dfbb186 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -17,6 +17,7 @@
17#include "config.h" 17#include "config.h"
18#include "cache.h" 18#include "cache.h"
19#include "symbol.h" 19#include "symbol.h"
20#include "units.h"
20#include "debug.h" 21#include "debug.h"
21#include "annotate.h" 22#include "annotate.h"
22#include "evsel.h" 23#include "evsel.h"
@@ -2324,7 +2325,7 @@ int symbol__tty_annotate2(struct symbol *sym, struct map *map,
2324 struct dso *dso = map->dso; 2325 struct dso *dso = map->dso;
2325 struct rb_root source_line = RB_ROOT; 2326 struct rb_root source_line = RB_ROOT;
2326 struct annotation_options opts = annotation__default_options; 2327 struct annotation_options opts = annotation__default_options;
2327 const char *ev_name = perf_evsel__name(evsel); 2328 struct annotation *notes = symbol__annotation(sym);
2328 char buf[1024]; 2329 char buf[1024];
2329 2330
2330 if (symbol__annotate2(sym, map, evsel, &opts, NULL) < 0) 2331 if (symbol__annotate2(sym, map, evsel, &opts, NULL) < 0)
@@ -2336,12 +2337,8 @@ int symbol__tty_annotate2(struct symbol *sym, struct map *map,
2336 print_summary(&source_line, dso->long_name); 2337 print_summary(&source_line, dso->long_name);
2337 } 2338 }
2338 2339
2339 if (perf_evsel__is_group_event(evsel)) { 2340 annotation__scnprintf_samples_period(notes, buf, sizeof(buf), evsel);
2340 perf_evsel__group_desc(evsel, buf, sizeof(buf)); 2341 fprintf(stdout, "%s\n%s() %s\n", buf, sym->name, dso->long_name);
2341 ev_name = buf;
2342 }
2343
2344 fprintf(stdout, "%s() %s\nEvent: %s\n\n", sym->name, dso->long_name, ev_name);
2345 symbol__annotate_fprintf2(sym, stdout); 2342 symbol__annotate_fprintf2(sym, stdout);
2346 2343
2347 annotated_source__purge(symbol__annotation(sym)->src); 2344 annotated_source__purge(symbol__annotation(sym)->src);
@@ -2597,6 +2594,46 @@ out_free_offsets:
2597 return -1; 2594 return -1;
2598} 2595}
2599 2596
2597int __annotation__scnprintf_samples_period(struct annotation *notes,
2598 char *bf, size_t size,
2599 struct perf_evsel *evsel,
2600 bool show_freq)
2601{
2602 const char *ev_name = perf_evsel__name(evsel);
2603 char buf[1024], ref[30] = " show reference callgraph, ";
2604 char sample_freq_str[64] = "";
2605 unsigned long nr_samples = 0;
2606 int nr_members = 1;
2607 bool enable_ref = false;
2608 u64 nr_events = 0;
2609 char unit;
2610 int i;
2611
2612 if (perf_evsel__is_group_event(evsel)) {
2613 perf_evsel__group_desc(evsel, buf, sizeof(buf));
2614 ev_name = buf;
2615 nr_members = evsel->nr_members;
2616 }
2617
2618 for (i = 0; i < nr_members; i++) {
2619 struct sym_hist *ah = annotation__histogram(notes, evsel->idx + i);
2620
2621 nr_samples += ah->nr_samples;
2622 nr_events += ah->period;
2623 }
2624
2625 if (symbol_conf.show_ref_callgraph && strstr(ev_name, "call-graph=no"))
2626 enable_ref = true;
2627
2628 if (show_freq)
2629 scnprintf(sample_freq_str, sizeof(sample_freq_str), " %d Hz,", evsel->attr.sample_freq);
2630
2631 nr_samples = convert_unit(nr_samples, &unit);
2632 return scnprintf(bf, size, "Samples: %lu%c of event%s '%s',%s%sEvent count (approx.): %" PRIu64,
2633 nr_samples, unit, evsel->nr_members > 1 ? "s" : "",
2634 ev_name, sample_freq_str, enable_ref ? ref : " ", nr_events);
2635}
2636
2600#define ANNOTATION__CFG(n) \ 2637#define ANNOTATION__CFG(n) \
2601 { .name = #n, .value = &annotation__default_options.n, } 2638 { .name = #n, .value = &annotation__default_options.n, }
2602 2639
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index ff7e3df31efa..db8d09bea07e 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -151,6 +151,18 @@ double annotation_line__max_percent(struct annotation_line *al, struct annotatio
151void annotation_line__write(struct annotation_line *al, struct annotation *notes, 151void annotation_line__write(struct annotation_line *al, struct annotation *notes,
152 struct annotation_write_ops *ops); 152 struct annotation_write_ops *ops);
153 153
154int __annotation__scnprintf_samples_period(struct annotation *notes,
155 char *bf, size_t size,
156 struct perf_evsel *evsel,
157 bool show_freq);
158
159static inline int annotation__scnprintf_samples_period(struct annotation *notes,
160 char *bf, size_t size,
161 struct perf_evsel *evsel)
162{
163 return __annotation__scnprintf_samples_period(notes, bf, size, evsel, true);
164}
165
154int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw); 166int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw);
155size_t disasm__fprintf(struct list_head *head, FILE *fp); 167size_t disasm__fprintf(struct list_head *head, FILE *fp);
156void symbol__calc_percent(struct symbol *sym, struct perf_evsel *evsel); 168void symbol__calc_percent(struct symbol *sym, struct perf_evsel *evsel);
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index fb357a00dd86..857de69a5361 100644
--- a/tools/perf/util/auxtrace.c
+++ b/tools/perf/util/auxtrace.c
@@ -302,13 +302,27 @@ static int auxtrace_queues__split_buffer(struct auxtrace_queues *queues,
302 return 0; 302 return 0;
303} 303}
304 304
305static bool filter_cpu(struct perf_session *session, int cpu)
306{
307 unsigned long *cpu_bitmap = session->itrace_synth_opts->cpu_bitmap;
308
309 return cpu_bitmap && cpu != -1 && !test_bit(cpu, cpu_bitmap);
310}
311
305static int auxtrace_queues__add_buffer(struct auxtrace_queues *queues, 312static int auxtrace_queues__add_buffer(struct auxtrace_queues *queues,
306 struct perf_session *session, 313 struct perf_session *session,
307 unsigned int idx, 314 unsigned int idx,
308 struct auxtrace_buffer *buffer, 315 struct auxtrace_buffer *buffer,
309 struct auxtrace_buffer **buffer_ptr) 316 struct auxtrace_buffer **buffer_ptr)
310{ 317{
311 int err; 318 int err = -ENOMEM;
319
320 if (filter_cpu(session, buffer->cpu))
321 return 0;
322
323 buffer = memdup(buffer, sizeof(*buffer));
324 if (!buffer)
325 return -ENOMEM;
312 326
313 if (session->one_mmap) { 327 if (session->one_mmap) {
314 buffer->data = buffer->data_offset - session->one_mmap_offset + 328 buffer->data = buffer->data_offset - session->one_mmap_offset +
@@ -316,31 +330,28 @@ static int auxtrace_queues__add_buffer(struct auxtrace_queues *queues,
316 } else if (perf_data__is_pipe(session->data)) { 330 } else if (perf_data__is_pipe(session->data)) {
317 buffer->data = auxtrace_copy_data(buffer->size, session); 331 buffer->data = auxtrace_copy_data(buffer->size, session);
318 if (!buffer->data) 332 if (!buffer->data)
319 return -ENOMEM; 333 goto out_free;
320 buffer->data_needs_freeing = true; 334 buffer->data_needs_freeing = true;
321 } else if (BITS_PER_LONG == 32 && 335 } else if (BITS_PER_LONG == 32 &&
322 buffer->size > BUFFER_LIMIT_FOR_32_BIT) { 336 buffer->size > BUFFER_LIMIT_FOR_32_BIT) {
323 err = auxtrace_queues__split_buffer(queues, idx, buffer); 337 err = auxtrace_queues__split_buffer(queues, idx, buffer);
324 if (err) 338 if (err)
325 return err; 339 goto out_free;
326 } 340 }
327 341
328 err = auxtrace_queues__queue_buffer(queues, idx, buffer); 342 err = auxtrace_queues__queue_buffer(queues, idx, buffer);
329 if (err) 343 if (err)
330 return err; 344 goto out_free;
331 345
332 /* FIXME: Doesn't work for split buffer */ 346 /* FIXME: Doesn't work for split buffer */
333 if (buffer_ptr) 347 if (buffer_ptr)
334 *buffer_ptr = buffer; 348 *buffer_ptr = buffer;
335 349
336 return 0; 350 return 0;
337}
338 351
339static bool filter_cpu(struct perf_session *session, int cpu) 352out_free:
340{ 353 auxtrace_buffer__free(buffer);
341 unsigned long *cpu_bitmap = session->itrace_synth_opts->cpu_bitmap; 354 return err;
342
343 return cpu_bitmap && cpu != -1 && !test_bit(cpu, cpu_bitmap);
344} 355}
345 356
346int auxtrace_queues__add_event(struct auxtrace_queues *queues, 357int auxtrace_queues__add_event(struct auxtrace_queues *queues,
@@ -348,36 +359,19 @@ int auxtrace_queues__add_event(struct auxtrace_queues *queues,
348 union perf_event *event, off_t data_offset, 359 union perf_event *event, off_t data_offset,
349 struct auxtrace_buffer **buffer_ptr) 360 struct auxtrace_buffer **buffer_ptr)
350{ 361{
351 struct auxtrace_buffer *buffer; 362 struct auxtrace_buffer buffer = {
352 unsigned int idx; 363 .pid = -1,
353 int err; 364 .tid = event->auxtrace.tid,
354 365 .cpu = event->auxtrace.cpu,
355 if (filter_cpu(session, event->auxtrace.cpu)) 366 .data_offset = data_offset,
356 return 0; 367 .offset = event->auxtrace.offset,
357 368 .reference = event->auxtrace.reference,
358 buffer = zalloc(sizeof(struct auxtrace_buffer)); 369 .size = event->auxtrace.size,
359 if (!buffer) 370 };
360 return -ENOMEM; 371 unsigned int idx = event->auxtrace.idx;
361
362 buffer->pid = -1;
363 buffer->tid = event->auxtrace.tid;
364 buffer->cpu = event->auxtrace.cpu;
365 buffer->data_offset = data_offset;
366 buffer->offset = event->auxtrace.offset;
367 buffer->reference = event->auxtrace.reference;
368 buffer->size = event->auxtrace.size;
369 idx = event->auxtrace.idx;
370
371 err = auxtrace_queues__add_buffer(queues, session, idx, buffer,
372 buffer_ptr);
373 if (err)
374 goto out_err;
375
376 return 0;
377 372
378out_err: 373 return auxtrace_queues__add_buffer(queues, session, idx, &buffer,
379 auxtrace_buffer__free(buffer); 374 buffer_ptr);
380 return err;
381} 375}
382 376
383static int auxtrace_queues__add_indexed_event(struct auxtrace_queues *queues, 377static int auxtrace_queues__add_indexed_event(struct auxtrace_queues *queues,
diff --git a/tools/perf/util/c++/clang-test.cpp b/tools/perf/util/c++/clang-test.cpp
index a4014d786676..7b042a5ebc68 100644
--- a/tools/perf/util/c++/clang-test.cpp
+++ b/tools/perf/util/c++/clang-test.cpp
@@ -41,7 +41,7 @@ int test__clang_to_IR(void)
41 if (!M) 41 if (!M)
42 return -1; 42 return -1;
43 for (llvm::Function& F : *M) 43 for (llvm::Function& F : *M)
44 if (F.getName() == "bpf_func__SyS_epoll_wait") 44 if (F.getName() == "bpf_func__SyS_epoll_pwait")
45 return 0; 45 return 0;
46 return -1; 46 return -1;
47} 47}
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
index 1bfc946e37dc..bf31ceab33bd 100644
--- a/tools/perf/util/c++/clang.cpp
+++ b/tools/perf/util/c++/clang.cpp
@@ -9,6 +9,7 @@
9 * Copyright (C) 2016 Huawei Inc. 9 * Copyright (C) 2016 Huawei Inc.
10 */ 10 */
11 11
12#include "clang/Basic/Version.h"
12#include "clang/CodeGen/CodeGenAction.h" 13#include "clang/CodeGen/CodeGenAction.h"
13#include "clang/Frontend/CompilerInvocation.h" 14#include "clang/Frontend/CompilerInvocation.h"
14#include "clang/Frontend/CompilerInstance.h" 15#include "clang/Frontend/CompilerInstance.h"
@@ -58,7 +59,8 @@ createCompilerInvocation(llvm::opt::ArgStringList CFlags, StringRef& Path,
58 59
59 FrontendOptions& Opts = CI->getFrontendOpts(); 60 FrontendOptions& Opts = CI->getFrontendOpts();
60 Opts.Inputs.clear(); 61 Opts.Inputs.clear();
61 Opts.Inputs.emplace_back(Path, IK_C); 62 Opts.Inputs.emplace_back(Path,
63 FrontendOptions::getInputKindForExtension("c"));
62 return CI; 64 return CI;
63} 65}
64 66
@@ -71,10 +73,17 @@ getModuleFromSource(llvm::opt::ArgStringList CFlags,
71 73
72 Clang.setVirtualFileSystem(&*VFS); 74 Clang.setVirtualFileSystem(&*VFS);
73 75
76#if CLANG_VERSION_MAJOR < 4
74 IntrusiveRefCntPtr<CompilerInvocation> CI = 77 IntrusiveRefCntPtr<CompilerInvocation> CI =
75 createCompilerInvocation(std::move(CFlags), Path, 78 createCompilerInvocation(std::move(CFlags), Path,
76 Clang.getDiagnostics()); 79 Clang.getDiagnostics());
77 Clang.setInvocation(&*CI); 80 Clang.setInvocation(&*CI);
81#else
82 std::shared_ptr<CompilerInvocation> CI(
83 createCompilerInvocation(std::move(CFlags), Path,
84 Clang.getDiagnostics()));
85 Clang.setInvocation(CI);
86#endif
78 87
79 std::unique_ptr<CodeGenAction> Act(new EmitLLVMOnlyAction(&*LLVMCtx)); 88 std::unique_ptr<CodeGenAction> Act(new EmitLLVMOnlyAction(&*LLVMCtx));
80 if (!Clang.ExecuteAction(*Act)) 89 if (!Clang.ExecuteAction(*Act))
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c
index f5acda13dcfa..7eb7de5aee44 100644
--- a/tools/perf/util/dwarf-aux.c
+++ b/tools/perf/util/dwarf-aux.c
@@ -979,7 +979,7 @@ int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf)
979 return ret < 0 ? ret : strbuf_addf(buf, "\t%s", dwarf_diename(vr_die)); 979 return ret < 0 ? ret : strbuf_addf(buf, "\t%s", dwarf_diename(vr_die));
980} 980}
981 981
982#ifdef HAVE_DWARF_GETLOCATIONS 982#ifdef HAVE_DWARF_GETLOCATIONS_SUPPORT
983/** 983/**
984 * die_get_var_innermost_scope - Get innermost scope range of given variable DIE 984 * die_get_var_innermost_scope - Get innermost scope range of given variable DIE
985 * @sp_die: a subprogram DIE 985 * @sp_die: a subprogram DIE
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 7d968892ee39..4d602fba40b2 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -6,6 +6,7 @@
6#include "session.h" 6#include "session.h"
7#include "namespaces.h" 7#include "namespaces.h"
8#include "sort.h" 8#include "sort.h"
9#include "units.h"
9#include "evlist.h" 10#include "evlist.h"
10#include "evsel.h" 11#include "evsel.h"
11#include "annotate.h" 12#include "annotate.h"
@@ -14,6 +15,7 @@
14#include "ui/progress.h" 15#include "ui/progress.h"
15#include <errno.h> 16#include <errno.h>
16#include <math.h> 17#include <math.h>
18#include <inttypes.h>
17#include <sys/param.h> 19#include <sys/param.h>
18 20
19static bool hists__filter_entry_by_dso(struct hists *hists, 21static bool hists__filter_entry_by_dso(struct hists *hists,
@@ -2454,6 +2456,85 @@ u64 hists__total_period(struct hists *hists)
2454 hists->stats.total_period; 2456 hists->stats.total_period;
2455} 2457}
2456 2458
2459int __hists__scnprintf_title(struct hists *hists, char *bf, size_t size, bool show_freq)
2460{
2461 char unit;
2462 int printed;
2463 const struct dso *dso = hists->dso_filter;
2464 const struct thread *thread = hists->thread_filter;
2465 int socket_id = hists->socket_filter;
2466 unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
2467 u64 nr_events = hists->stats.total_period;
2468 struct perf_evsel *evsel = hists_to_evsel(hists);
2469 const char *ev_name = perf_evsel__name(evsel);
2470 char buf[512], sample_freq_str[64] = "";
2471 size_t buflen = sizeof(buf);
2472 char ref[30] = " show reference callgraph, ";
2473 bool enable_ref = false;
2474
2475 if (symbol_conf.filter_relative) {
2476 nr_samples = hists->stats.nr_non_filtered_samples;
2477 nr_events = hists->stats.total_non_filtered_period;
2478 }
2479
2480 if (perf_evsel__is_group_event(evsel)) {
2481 struct perf_evsel *pos;
2482
2483 perf_evsel__group_desc(evsel, buf, buflen);
2484 ev_name = buf;
2485
2486 for_each_group_member(pos, evsel) {
2487 struct hists *pos_hists = evsel__hists(pos);
2488
2489 if (symbol_conf.filter_relative) {
2490 nr_samples += pos_hists->stats.nr_non_filtered_samples;
2491 nr_events += pos_hists->stats.total_non_filtered_period;
2492 } else {
2493 nr_samples += pos_hists->stats.nr_events[PERF_RECORD_SAMPLE];
2494 nr_events += pos_hists->stats.total_period;
2495 }
2496 }
2497 }
2498
2499 if (symbol_conf.show_ref_callgraph &&
2500 strstr(ev_name, "call-graph=no"))
2501 enable_ref = true;
2502
2503 if (show_freq)
2504 scnprintf(sample_freq_str, sizeof(sample_freq_str), " %d Hz,", evsel->attr.sample_freq);
2505
2506 nr_samples = convert_unit(nr_samples, &unit);
2507 printed = scnprintf(bf, size,
2508 "Samples: %lu%c of event%s '%s',%s%sEvent count (approx.): %" PRIu64,
2509 nr_samples, unit, evsel->nr_members > 1 ? "s" : "",
2510 ev_name, sample_freq_str, enable_ref ? ref : " ", nr_events);
2511
2512
2513 if (hists->uid_filter_str)
2514 printed += snprintf(bf + printed, size - printed,
2515 ", UID: %s", hists->uid_filter_str);
2516 if (thread) {
2517 if (hists__has(hists, thread)) {
2518 printed += scnprintf(bf + printed, size - printed,
2519 ", Thread: %s(%d)",
2520 (thread->comm_set ? thread__comm_str(thread) : ""),
2521 thread->tid);
2522 } else {
2523 printed += scnprintf(bf + printed, size - printed,
2524 ", Thread: %s",
2525 (thread->comm_set ? thread__comm_str(thread) : ""));
2526 }
2527 }
2528 if (dso)
2529 printed += scnprintf(bf + printed, size - printed,
2530 ", DSO: %s", dso->short_name);
2531 if (socket_id > -1)
2532 printed += scnprintf(bf + printed, size - printed,
2533 ", Processor Socket: %d", socket_id);
2534
2535 return printed;
2536}
2537
2457int parse_filter_percentage(const struct option *opt __maybe_unused, 2538int parse_filter_percentage(const struct option *opt __maybe_unused,
2458 const char *arg, int unset __maybe_unused) 2539 const char *arg, int unset __maybe_unused)
2459{ 2540{
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index e869cad4d89f..fbabfd8a215d 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -61,6 +61,7 @@ enum hist_column {
61 HISTC_SRCLINE_TO, 61 HISTC_SRCLINE_TO,
62 HISTC_TRACE, 62 HISTC_TRACE,
63 HISTC_SYM_SIZE, 63 HISTC_SYM_SIZE,
64 HISTC_DSO_SIZE,
64 HISTC_NR_COLS, /* Last entry */ 65 HISTC_NR_COLS, /* Last entry */
65}; 66};
66 67
@@ -503,5 +504,11 @@ int __hpp__slsmg_color_printf(struct perf_hpp *hpp, const char *fmt, ...);
503int __hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp, 504int __hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp,
504 struct perf_hpp_list *hpp_list); 505 struct perf_hpp_list *hpp_list);
505int hists__fprintf_headers(struct hists *hists, FILE *fp); 506int hists__fprintf_headers(struct hists *hists, FILE *fp);
507int __hists__scnprintf_title(struct hists *hists, char *bf, size_t size, bool show_freq);
508
509static inline int hists__scnprintf_title(struct hists *hists, char *bf, size_t size)
510{
511 return __hists__scnprintf_title(hists, bf, size, true);
512}
506 513
507#endif /* __PERF_HIST_H */ 514#endif /* __PERF_HIST_H */
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index edeb7291c8e1..0e9bbe01b0ab 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -103,6 +103,10 @@ static inline u64 identity__map_ip(struct map *map __maybe_unused, u64 ip)
103 return ip; 103 return ip;
104} 104}
105 105
106static inline size_t map__size(const struct map *map)
107{
108 return map->end - map->start;
109}
106 110
107/* rip/ip <-> addr suitable for passing to `objdump --start-address=` */ 111/* rip/ip <-> addr suitable for passing to `objdump --start-address=` */
108u64 map__rip_2objdump(struct map *map, u64 rip); 112u64 map__rip_2objdump(struct map *map, u64 rip);
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index c71ced7db152..f4a7a437ee87 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1591,7 +1591,7 @@ static void perf_session__warn_about_errors(const struct perf_session *session)
1591 drop_rate = (double)stats->total_lost_samples / 1591 drop_rate = (double)stats->total_lost_samples /
1592 (double) (stats->nr_events[PERF_RECORD_SAMPLE] + stats->total_lost_samples); 1592 (double) (stats->nr_events[PERF_RECORD_SAMPLE] + stats->total_lost_samples);
1593 if (drop_rate > 0.05) { 1593 if (drop_rate > 0.05) {
1594 ui__warning("Processed %" PRIu64 " samples and lost %3.2f%% samples!\n\n", 1594 ui__warning("Processed %" PRIu64 " samples and lost %3.2f%%!\n\n",
1595 stats->nr_events[PERF_RECORD_SAMPLE] + stats->total_lost_samples, 1595 stats->nr_events[PERF_RECORD_SAMPLE] + stats->total_lost_samples,
1596 drop_rate * 100.0); 1596 drop_rate * 100.0);
1597 } 1597 }
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index e8514f651865..26a68dfd8a4f 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -1545,6 +1545,46 @@ struct sort_entry sort_sym_size = {
1545 .se_width_idx = HISTC_SYM_SIZE, 1545 .se_width_idx = HISTC_SYM_SIZE,
1546}; 1546};
1547 1547
1548/* --sort dso_size */
1549
1550static int64_t _sort__dso_size_cmp(struct map *map_l, struct map *map_r)
1551{
1552 int64_t size_l = map_l != NULL ? map__size(map_l) : 0;
1553 int64_t size_r = map_r != NULL ? map__size(map_r) : 0;
1554
1555 return size_l < size_r ? -1 :
1556 size_l == size_r ? 0 : 1;
1557}
1558
1559static int64_t
1560sort__dso_size_cmp(struct hist_entry *left, struct hist_entry *right)
1561{
1562 return _sort__dso_size_cmp(right->ms.map, left->ms.map);
1563}
1564
1565static int _hist_entry__dso_size_snprintf(struct map *map, char *bf,
1566 size_t bf_size, unsigned int width)
1567{
1568 if (map && map->dso)
1569 return repsep_snprintf(bf, bf_size, "%*d", width,
1570 map__size(map));
1571
1572 return repsep_snprintf(bf, bf_size, "%*s", width, "unknown");
1573}
1574
1575static int hist_entry__dso_size_snprintf(struct hist_entry *he, char *bf,
1576 size_t size, unsigned int width)
1577{
1578 return _hist_entry__dso_size_snprintf(he->ms.map, bf, size, width);
1579}
1580
1581struct sort_entry sort_dso_size = {
1582 .se_header = "DSO size",
1583 .se_cmp = sort__dso_size_cmp,
1584 .se_snprintf = hist_entry__dso_size_snprintf,
1585 .se_width_idx = HISTC_DSO_SIZE,
1586};
1587
1548 1588
1549struct sort_dimension { 1589struct sort_dimension {
1550 const char *name; 1590 const char *name;
@@ -1569,6 +1609,7 @@ static struct sort_dimension common_sort_dimensions[] = {
1569 DIM(SORT_TRANSACTION, "transaction", sort_transaction), 1609 DIM(SORT_TRANSACTION, "transaction", sort_transaction),
1570 DIM(SORT_TRACE, "trace", sort_trace), 1610 DIM(SORT_TRACE, "trace", sort_trace),
1571 DIM(SORT_SYM_SIZE, "symbol_size", sort_sym_size), 1611 DIM(SORT_SYM_SIZE, "symbol_size", sort_sym_size),
1612 DIM(SORT_DSO_SIZE, "dso_size", sort_dso_size),
1572 DIM(SORT_CGROUP_ID, "cgroup_id", sort_cgroup_id), 1613 DIM(SORT_CGROUP_ID, "cgroup_id", sort_cgroup_id),
1573}; 1614};
1574 1615
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index f5901c10a563..035b62e2c60b 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -220,6 +220,7 @@ enum sort_type {
220 SORT_TRANSACTION, 220 SORT_TRANSACTION,
221 SORT_TRACE, 221 SORT_TRACE,
222 SORT_SYM_SIZE, 222 SORT_SYM_SIZE,
223 SORT_DSO_SIZE,
223 SORT_CGROUP_ID, 224 SORT_CGROUP_ID,
224 225
225 /* branch stack specific sort keys */ 226 /* branch stack specific sort keys */
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 9496365da3d7..c9626c206208 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -11,8 +11,7 @@
11#include <stdlib.h> 11#include <stdlib.h>
12#include <stdarg.h> 12#include <stdarg.h>
13#include <linux/compiler.h> 13#include <linux/compiler.h>
14#include <linux/types.h> 14#include <sys/types.h>
15#include "namespaces.h"
16 15
17/* General helper functions */ 16/* General helper functions */
18void usage(const char *err) __noreturn; 17void usage(const char *err) __noreturn;
@@ -26,6 +25,7 @@ static inline void *zalloc(size_t size)
26#define zfree(ptr) ({ free(*ptr); *ptr = NULL; }) 25#define zfree(ptr) ({ free(*ptr); *ptr = NULL; })
27 26
28struct dirent; 27struct dirent;
28struct nsinfo;
29struct strlist; 29struct strlist;
30 30
31int mkdir_p(char *path, mode_t mode); 31int mkdir_p(char *path, mode_t mode);
diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include
index dd614463d4d6..495066bafbe3 100644
--- a/tools/scripts/Makefile.include
+++ b/tools/scripts/Makefile.include
@@ -120,3 +120,5 @@ ifneq ($(silent),1)
120 QUIET_UNINST = @printf ' UNINST %s\n' $1; 120 QUIET_UNINST = @printf ' UNINST %s\n' $1;
121 endif 121 endif
122endif 122endif
123
124pound := \#
diff --git a/tools/testing/ktest/config-bisect.pl b/tools/testing/ktest/config-bisect.pl
new file mode 100755
index 000000000000..b28feea7c363
--- /dev/null
+++ b/tools/testing/ktest/config-bisect.pl
@@ -0,0 +1,770 @@
1#!/usr/bin/perl -w
2#
3# Copyright 2015 - Steven Rostedt, Red Hat Inc.
4# Copyright 2017 - Steven Rostedt, VMware, Inc.
5#
6# Licensed under the terms of the GNU GPL License version 2
7#
8
9# usage:
10# config-bisect.pl [options] good-config bad-config [good|bad]
11#
12
13# Compares a good config to a bad config, then takes half of the diffs
14# and produces a config that is somewhere between the good config and
15# the bad config. That is, the resulting config will start with the
16# good config and will try to make half of the differences of between
17# the good and bad configs match the bad config. It tries because of
18# dependencies between the two configs it may not be able to change
19# exactly half of the configs that are different between the two config
20# files.
21
22# Here's a normal way to use it:
23#
24# $ cd /path/to/linux/kernel
25# $ config-bisect.pl /path/to/good/config /path/to/bad/config
26
27# This will now pull in good config (blowing away .config in that directory
28# so do not make that be one of the good or bad configs), and then
29# build the config with "make oldconfig" to make sure it matches the
30# current kernel. It will then store the configs in that result for
31# the good config. It does the same for the bad config as well.
32# The algorithm will run, merging half of the differences between
33# the two configs and building them with "make oldconfig" to make sure
34# the result changes (dependencies may reset changes the tool had made).
35# It then copies the result of its good config to /path/to/good/config.tmp
36# and the bad config to /path/to/bad/config.tmp (just appends ".tmp" to the
37# files passed in). And the ".config" that you should test will be in
38# directory
39
40# After the first run, determine if the result is good or bad then
41# run the same command appending the result
42
43# For good results:
44# $ config-bisect.pl /path/to/good/config /path/to/bad/config good
45
46# For bad results:
47# $ config-bisect.pl /path/to/good/config /path/to/bad/config bad
48
49# Do not change the good-config or bad-config, config-bisect.pl will
50# copy the good-config to a temp file with the same name as good-config
51# but with a ".tmp" after it. It will do the same with the bad-config.
52
53# If "good" or "bad" is not stated at the end, it will copy the good and
54# bad configs to the .tmp versions. If a .tmp version already exists, it will
55# warn before writing over them (-r will not warn, and just write over them).
56# If the last config is labeled "good", then it will copy it to the good .tmp
57# version. If the last config is labeled "bad", it will copy it to the bad
58# .tmp version. It will continue this until it can not merge the two any more
59# without the result being equal to either the good or bad .tmp configs.
60
61my $start = 0;
62my $val = "";
63
64my $pwd = `pwd`;
65chomp $pwd;
66my $tree = $pwd;
67my $build;
68
69my $output_config;
70my $reset_bisect;
71
72sub usage {
73 print << "EOF"
74
75usage: config-bisect.pl [-l linux-tree][-b build-dir] good-config bad-config [good|bad]
76 -l [optional] define location of linux-tree (default is current directory)
77 -b [optional] define location to build (O=build-dir) (default is linux-tree)
78 good-config the config that is considered good
79 bad-config the config that does not work
80 "good" add this if the last run produced a good config
81 "bad" add this if the last run produced a bad config
82 If "good" or "bad" is not specified, then it is the start of a new bisect
83
84 Note, each run will create copy of good and bad configs with ".tmp" appended.
85
86EOF
87;
88
89 exit(-1);
90}
91
92sub doprint {
93 print @_;
94}
95
96sub dodie {
97 doprint "CRITICAL FAILURE... ", @_, "\n";
98
99 die @_, "\n";
100}
101
102sub expand_path {
103 my ($file) = @_;
104
105 if ($file =~ m,^/,) {
106 return $file;
107 }
108 return "$pwd/$file";
109}
110
111sub read_prompt {
112 my ($cancel, $prompt) = @_;
113
114 my $ans;
115
116 for (;;) {
117 if ($cancel) {
118 print "$prompt [y/n/C] ";
119 } else {
120 print "$prompt [y/N] ";
121 }
122 $ans = <STDIN>;
123 chomp $ans;
124 if ($ans =~ /^\s*$/) {
125 if ($cancel) {
126 $ans = "c";
127 } else {
128 $ans = "n";
129 }
130 }
131 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
132 if ($cancel) {
133 last if ($ans =~ /^c$/i);
134 print "Please answer either 'y', 'n' or 'c'.\n";
135 } else {
136 print "Please answer either 'y' or 'n'.\n";
137 }
138 }
139 if ($ans =~ /^c/i) {
140 exit;
141 }
142 if ($ans !~ /^y$/i) {
143 return 0;
144 }
145 return 1;
146}
147
148sub read_yn {
149 my ($prompt) = @_;
150
151 return read_prompt 0, $prompt;
152}
153
154sub read_ync {
155 my ($prompt) = @_;
156
157 return read_prompt 1, $prompt;
158}
159
160sub run_command {
161 my ($command, $redirect) = @_;
162 my $start_time;
163 my $end_time;
164 my $dord = 0;
165 my $pid;
166
167 $start_time = time;
168
169 doprint("$command ... ");
170
171 $pid = open(CMD, "$command 2>&1 |") or
172 dodie "unable to exec $command";
173
174 if (defined($redirect)) {
175 open (RD, ">$redirect") or
176 dodie "failed to write to redirect $redirect";
177 $dord = 1;
178 }
179
180 while (<CMD>) {
181 print RD if ($dord);
182 }
183
184 waitpid($pid, 0);
185 my $failed = $?;
186
187 close(CMD);
188 close(RD) if ($dord);
189
190 $end_time = time;
191 my $delta = $end_time - $start_time;
192
193 if ($delta == 1) {
194 doprint "[1 second] ";
195 } else {
196 doprint "[$delta seconds] ";
197 }
198
199 if ($failed) {
200 doprint "FAILED!\n";
201 } else {
202 doprint "SUCCESS\n";
203 }
204
205 return !$failed;
206}
207
208###### CONFIG BISECT ######
209
210# config_ignore holds the configs that were set (or unset) for
211# a good config and we will ignore these configs for the rest
212# of a config bisect. These configs stay as they were.
213my %config_ignore;
214
215# config_set holds what all configs were set as.
216my %config_set;
217
218# config_off holds the set of configs that the bad config had disabled.
219# We need to record them and set them in the .config when running
220# olddefconfig, because olddefconfig keeps the defaults.
221my %config_off;
222
223# config_off_tmp holds a set of configs to turn off for now
224my @config_off_tmp;
225
226# config_list is the set of configs that are being tested
227my %config_list;
228my %null_config;
229
230my %dependency;
231
232my $make;
233
234sub make_oldconfig {
235
236 if (!run_command "$make olddefconfig") {
237 # Perhaps olddefconfig doesn't exist in this version of the kernel
238 # try oldnoconfig
239 doprint "olddefconfig failed, trying make oldnoconfig\n";
240 if (!run_command "$make oldnoconfig") {
241 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
242 # try a yes '' | oldconfig
243 run_command "yes '' | $make oldconfig" or
244 dodie "failed make config oldconfig";
245 }
246 }
247}
248
249sub assign_configs {
250 my ($hash, $config) = @_;
251
252 doprint "Reading configs from $config\n";
253
254 open (IN, $config)
255 or dodie "Failed to read $config";
256
257 while (<IN>) {
258 chomp;
259 if (/^((CONFIG\S*)=.*)/) {
260 ${$hash}{$2} = $1;
261 } elsif (/^(# (CONFIG\S*) is not set)/) {
262 ${$hash}{$2} = $1;
263 }
264 }
265
266 close(IN);
267}
268
269sub process_config_ignore {
270 my ($config) = @_;
271
272 assign_configs \%config_ignore, $config;
273}
274
275sub get_dependencies {
276 my ($config) = @_;
277
278 my $arr = $dependency{$config};
279 if (!defined($arr)) {
280 return ();
281 }
282
283 my @deps = @{$arr};
284
285 foreach my $dep (@{$arr}) {
286 print "ADD DEP $dep\n";
287 @deps = (@deps, get_dependencies $dep);
288 }
289
290 return @deps;
291}
292
293sub save_config {
294 my ($pc, $file) = @_;
295
296 my %configs = %{$pc};
297
298 doprint "Saving configs into $file\n";
299
300 open(OUT, ">$file") or dodie "Can not write to $file";
301
302 foreach my $config (keys %configs) {
303 print OUT "$configs{$config}\n";
304 }
305 close(OUT);
306}
307
308sub create_config {
309 my ($name, $pc) = @_;
310
311 doprint "Creating old config from $name configs\n";
312
313 save_config $pc, $output_config;
314
315 make_oldconfig;
316}
317
318# compare two config hashes, and return configs with different vals.
319# It returns B's config values, but you can use A to see what A was.
320sub diff_config_vals {
321 my ($pa, $pb) = @_;
322
323 # crappy Perl way to pass in hashes.
324 my %a = %{$pa};
325 my %b = %{$pb};
326
327 my %ret;
328
329 foreach my $item (keys %a) {
330 if (defined($b{$item}) && $b{$item} ne $a{$item}) {
331 $ret{$item} = $b{$item};
332 }
333 }
334
335 return %ret;
336}
337
338# compare two config hashes and return the configs in B but not A
339sub diff_configs {
340 my ($pa, $pb) = @_;
341
342 my %ret;
343
344 # crappy Perl way to pass in hashes.
345 my %a = %{$pa};
346 my %b = %{$pb};
347
348 foreach my $item (keys %b) {
349 if (!defined($a{$item})) {
350 $ret{$item} = $b{$item};
351 }
352 }
353
354 return %ret;
355}
356
357# return if two configs are equal or not
358# 0 is equal +1 b has something a does not
359# +1 if a and b have a different item.
360# -1 if a has something b does not
361sub compare_configs {
362 my ($pa, $pb) = @_;
363
364 my %ret;
365
366 # crappy Perl way to pass in hashes.
367 my %a = %{$pa};
368 my %b = %{$pb};
369
370 foreach my $item (keys %b) {
371 if (!defined($a{$item})) {
372 return 1;
373 }
374 if ($a{$item} ne $b{$item}) {
375 return 1;
376 }
377 }
378
379 foreach my $item (keys %a) {
380 if (!defined($b{$item})) {
381 return -1;
382 }
383 }
384
385 return 0;
386}
387
388sub process_failed {
389 my ($config) = @_;
390
391 doprint "\n\n***************************************\n";
392 doprint "Found bad config: $config\n";
393 doprint "***************************************\n\n";
394}
395
396sub process_new_config {
397 my ($tc, $nc, $gc, $bc) = @_;
398
399 my %tmp_config = %{$tc};
400 my %good_configs = %{$gc};
401 my %bad_configs = %{$bc};
402
403 my %new_configs;
404
405 my $runtest = 1;
406 my $ret;
407
408 create_config "tmp_configs", \%tmp_config;
409 assign_configs \%new_configs, $output_config;
410
411 $ret = compare_configs \%new_configs, \%bad_configs;
412 if (!$ret) {
413 doprint "New config equals bad config, try next test\n";
414 $runtest = 0;
415 }
416
417 if ($runtest) {
418 $ret = compare_configs \%new_configs, \%good_configs;
419 if (!$ret) {
420 doprint "New config equals good config, try next test\n";
421 $runtest = 0;
422 }
423 }
424
425 %{$nc} = %new_configs;
426
427 return $runtest;
428}
429
430sub convert_config {
431 my ($config) = @_;
432
433 if ($config =~ /^# (.*) is not set/) {
434 $config = "$1=n";
435 }
436
437 $config =~ s/^CONFIG_//;
438 return $config;
439}
440
441sub print_config {
442 my ($sym, $config) = @_;
443
444 $config = convert_config $config;
445 doprint "$sym$config\n";
446}
447
448sub print_config_compare {
449 my ($good_config, $bad_config) = @_;
450
451 $good_config = convert_config $good_config;
452 $bad_config = convert_config $bad_config;
453
454 my $good_value = $good_config;
455 my $bad_value = $bad_config;
456 $good_value =~ s/(.*)=//;
457 my $config = $1;
458
459 $bad_value =~ s/.*=//;
460
461 doprint " $config $good_value -> $bad_value\n";
462}
463
464# Pass in:
465# $phalf: half of the configs names you want to add
466# $oconfigs: The orginial configs to start with
467# $sconfigs: The source to update $oconfigs with (from $phalf)
468# $which: The name of which half that is updating (top / bottom)
469# $type: The name of the source type (good / bad)
470sub make_half {
471 my ($phalf, $oconfigs, $sconfigs, $which, $type) = @_;
472
473 my @half = @{$phalf};
474 my %orig_configs = %{$oconfigs};
475 my %source_configs = %{$sconfigs};
476
477 my %tmp_config = %orig_configs;
478
479 doprint "Settings bisect with $which half of $type configs:\n";
480 foreach my $item (@half) {
481 doprint "Updating $item to $source_configs{$item}\n";
482 $tmp_config{$item} = $source_configs{$item};
483 }
484
485 return %tmp_config;
486}
487
488sub run_config_bisect {
489 my ($pgood, $pbad) = @_;
490
491 my %good_configs = %{$pgood};
492 my %bad_configs = %{$pbad};
493
494 my %diff_configs = diff_config_vals \%good_configs, \%bad_configs;
495 my %b_configs = diff_configs \%good_configs, \%bad_configs;
496 my %g_configs = diff_configs \%bad_configs, \%good_configs;
497
498 # diff_arr is what is in both good and bad but are different (y->n)
499 my @diff_arr = keys %diff_configs;
500 my $len_diff = $#diff_arr + 1;
501
502 # b_arr is what is in bad but not in good (has depends)
503 my @b_arr = keys %b_configs;
504 my $len_b = $#b_arr + 1;
505
506 # g_arr is what is in good but not in bad
507 my @g_arr = keys %g_configs;
508 my $len_g = $#g_arr + 1;
509
510 my $runtest = 0;
511 my %new_configs;
512 my $ret;
513
514 # Look at the configs that are different between good and bad.
515 # This does not include those that depend on other configs
516 # (configs depending on other configs that are not set would
517 # not show up even as a "# CONFIG_FOO is not set"
518
519
520 doprint "# of configs to check: $len_diff\n";
521 doprint "# of configs showing only in good: $len_g\n";
522 doprint "# of configs showing only in bad: $len_b\n";
523
524 if ($len_diff > 0) {
525 # Now test for different values
526
527 doprint "Configs left to check:\n";
528 doprint " Good Config\t\t\tBad Config\n";
529 doprint " -----------\t\t\t----------\n";
530 foreach my $item (@diff_arr) {
531 doprint " $good_configs{$item}\t$bad_configs{$item}\n";
532 }
533
534 my $half = int($#diff_arr / 2);
535 my @tophalf = @diff_arr[0 .. $half];
536
537 doprint "Set tmp config to be good config with some bad config values\n";
538
539 my %tmp_config = make_half \@tophalf, \%good_configs,
540 \%bad_configs, "top", "bad";
541
542 $runtest = process_new_config \%tmp_config, \%new_configs,
543 \%good_configs, \%bad_configs;
544
545 if (!$runtest) {
546 doprint "Set tmp config to be bad config with some good config values\n";
547
548 my %tmp_config = make_half \@tophalf, \%bad_configs,
549 \%good_configs, "top", "good";
550
551 $runtest = process_new_config \%tmp_config, \%new_configs,
552 \%good_configs, \%bad_configs;
553 }
554 }
555
556 if (!$runtest && $len_diff > 0) {
557 # do the same thing, but this time with bottom half
558
559 my $half = int($#diff_arr / 2);
560 my @bottomhalf = @diff_arr[$half+1 .. $#diff_arr];
561
562 doprint "Set tmp config to be good config with some bad config values\n";
563
564 my %tmp_config = make_half \@bottomhalf, \%good_configs,
565 \%bad_configs, "bottom", "bad";
566
567 $runtest = process_new_config \%tmp_config, \%new_configs,
568 \%good_configs, \%bad_configs;
569
570 if (!$runtest) {
571 doprint "Set tmp config to be bad config with some good config values\n";
572
573 my %tmp_config = make_half \@bottomhalf, \%bad_configs,
574 \%good_configs, "bottom", "good";
575
576 $runtest = process_new_config \%tmp_config, \%new_configs,
577 \%good_configs, \%bad_configs;
578 }
579 }
580
581 if ($runtest) {
582 make_oldconfig;
583 doprint "READY TO TEST .config IN $build\n";
584 return 0;
585 }
586
587 doprint "\n%%%%%%%% FAILED TO FIND SINGLE BAD CONFIG %%%%%%%%\n";
588 doprint "Hmm, can't make any more changes without making good == bad?\n";
589 doprint "Difference between good (+) and bad (-)\n";
590
591 foreach my $item (keys %bad_configs) {
592 if (!defined($good_configs{$item})) {
593 print_config "-", $bad_configs{$item};
594 }
595 }
596
597 foreach my $item (keys %good_configs) {
598 next if (!defined($bad_configs{$item}));
599 if ($good_configs{$item} ne $bad_configs{$item}) {
600 print_config_compare $good_configs{$item}, $bad_configs{$item};
601 }
602 }
603
604 foreach my $item (keys %good_configs) {
605 if (!defined($bad_configs{$item})) {
606 print_config "+", $good_configs{$item};
607 }
608 }
609 return -1;
610}
611
612sub config_bisect {
613 my ($good_config, $bad_config) = @_;
614 my $ret;
615
616 my %good_configs;
617 my %bad_configs;
618 my %tmp_configs;
619
620 doprint "Run good configs through make oldconfig\n";
621 assign_configs \%tmp_configs, $good_config;
622 create_config "$good_config", \%tmp_configs;
623 assign_configs \%good_configs, $output_config;
624
625 doprint "Run bad configs through make oldconfig\n";
626 assign_configs \%tmp_configs, $bad_config;
627 create_config "$bad_config", \%tmp_configs;
628 assign_configs \%bad_configs, $output_config;
629
630 save_config \%good_configs, $good_config;
631 save_config \%bad_configs, $bad_config;
632
633 return run_config_bisect \%good_configs, \%bad_configs;
634}
635
636while ($#ARGV >= 0) {
637 if ($ARGV[0] !~ m/^-/) {
638 last;
639 }
640 my $opt = shift @ARGV;
641
642 if ($opt eq "-b") {
643 $val = shift @ARGV;
644 if (!defined($val)) {
645 die "-b requires value\n";
646 }
647 $build = $val;
648 }
649
650 elsif ($opt eq "-l") {
651 $val = shift @ARGV;
652 if (!defined($val)) {
653 die "-l requires value\n";
654 }
655 $tree = $val;
656 }
657
658 elsif ($opt eq "-r") {
659 $reset_bisect = 1;
660 }
661
662 elsif ($opt eq "-h") {
663 usage;
664 }
665
666 else {
667 die "Unknow option $opt\n";
668 }
669}
670
671$build = $tree if (!defined($build));
672
673$tree = expand_path $tree;
674$build = expand_path $build;
675
676if ( ! -d $tree ) {
677 die "$tree not a directory\n";
678}
679
680if ( ! -d $build ) {
681 die "$build not a directory\n";
682}
683
684usage if $#ARGV < 1;
685
686if ($#ARGV == 1) {
687 $start = 1;
688} elsif ($#ARGV == 2) {
689 $val = $ARGV[2];
690 if ($val ne "good" && $val ne "bad") {
691 die "Unknown command '$val', bust be either \"good\" or \"bad\"\n";
692 }
693} else {
694 usage;
695}
696
697my $good_start = expand_path $ARGV[0];
698my $bad_start = expand_path $ARGV[1];
699
700my $good = "$good_start.tmp";
701my $bad = "$bad_start.tmp";
702
703$make = "make";
704
705if ($build ne $tree) {
706 $make = "make O=$build"
707}
708
709$output_config = "$build/.config";
710
711if ($start) {
712 if ( ! -f $good_start ) {
713 die "$good_start not found\n";
714 }
715 if ( ! -f $bad_start ) {
716 die "$bad_start not found\n";
717 }
718 if ( -f $good || -f $bad ) {
719 my $p = "";
720
721 if ( -f $good ) {
722 $p = "$good exists\n";
723 }
724
725 if ( -f $bad ) {
726 $p = "$p$bad exists\n";
727 }
728
729 if (!defined($reset_bisect)) {
730 if (!read_yn "${p}Overwrite and start new bisect anyway?") {
731 exit (-1);
732 }
733 }
734 }
735 run_command "cp $good_start $good" or die "failed to copy to $good\n";
736 run_command "cp $bad_start $bad" or die "faield to copy to $bad\n";
737} else {
738 if ( ! -f $good ) {
739 die "Can not find file $good\n";
740 }
741 if ( ! -f $bad ) {
742 die "Can not find file $bad\n";
743 }
744 if ($val eq "good") {
745 run_command "cp $output_config $good" or die "failed to copy $config to $good\n";
746 } elsif ($val eq "bad") {
747 run_command "cp $output_config $bad" or die "failed to copy $config to $bad\n";
748 }
749}
750
751chdir $tree || die "can't change directory to $tree";
752
753my $ret = config_bisect $good, $bad;
754
755if (!$ret) {
756 exit(0);
757}
758
759if ($ret > 0) {
760 doprint "Cleaning temp files\n";
761 run_command "rm $good";
762 run_command "rm $bad";
763 exit(1);
764} else {
765 doprint "See good and bad configs for details:\n";
766 doprint "good: $good\n";
767 doprint "bad: $bad\n";
768 doprint "%%%%%%%% FAILED TO FIND SINGLE BAD CONFIG %%%%%%%%\n";
769}
770exit(2);
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
index 8809f244bb7c..87af8a68ab25 100755
--- a/tools/testing/ktest/ktest.pl
+++ b/tools/testing/ktest/ktest.pl
@@ -10,6 +10,7 @@ use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
10use File::Path qw(mkpath); 10use File::Path qw(mkpath);
11use File::Copy qw(cp); 11use File::Copy qw(cp);
12use FileHandle; 12use FileHandle;
13use FindBin;
13 14
14my $VERSION = "0.2"; 15my $VERSION = "0.2";
15 16
@@ -22,6 +23,11 @@ my %evals;
22 23
23#default opts 24#default opts
24my %default = ( 25my %default = (
26 "MAILER" => "sendmail", # default mailer
27 "EMAIL_ON_ERROR" => 1,
28 "EMAIL_WHEN_FINISHED" => 1,
29 "EMAIL_WHEN_CANCELED" => 0,
30 "EMAIL_WHEN_STARTED" => 0,
25 "NUM_TESTS" => 1, 31 "NUM_TESTS" => 1,
26 "TEST_TYPE" => "build", 32 "TEST_TYPE" => "build",
27 "BUILD_TYPE" => "randconfig", 33 "BUILD_TYPE" => "randconfig",
@@ -59,6 +65,7 @@ my %default = (
59 "GRUB_REBOOT" => "grub2-reboot", 65 "GRUB_REBOOT" => "grub2-reboot",
60 "SYSLINUX" => "extlinux", 66 "SYSLINUX" => "extlinux",
61 "SYSLINUX_PATH" => "/boot/extlinux", 67 "SYSLINUX_PATH" => "/boot/extlinux",
68 "CONNECT_TIMEOUT" => 25,
62 69
63# required, and we will ask users if they don't have them but we keep the default 70# required, and we will ask users if they don't have them but we keep the default
64# value something that is common. 71# value something that is common.
@@ -163,6 +170,8 @@ my $store_failures;
163my $store_successes; 170my $store_successes;
164my $test_name; 171my $test_name;
165my $timeout; 172my $timeout;
173my $connect_timeout;
174my $config_bisect_exec;
166my $booted_timeout; 175my $booted_timeout;
167my $detect_triplefault; 176my $detect_triplefault;
168my $console; 177my $console;
@@ -204,6 +213,20 @@ my $install_time;
204my $reboot_time; 213my $reboot_time;
205my $test_time; 214my $test_time;
206 215
216my $pwd;
217my $dirname = $FindBin::Bin;
218
219my $mailto;
220my $mailer;
221my $mail_path;
222my $mail_command;
223my $email_on_error;
224my $email_when_finished;
225my $email_when_started;
226my $email_when_canceled;
227
228my $script_start_time = localtime();
229
207# set when a test is something other that just building or install 230# set when a test is something other that just building or install
208# which would require more options. 231# which would require more options.
209my $buildonly = 1; 232my $buildonly = 1;
@@ -229,6 +252,14 @@ my $no_reboot = 1;
229my $reboot_success = 0; 252my $reboot_success = 0;
230 253
231my %option_map = ( 254my %option_map = (
255 "MAILTO" => \$mailto,
256 "MAILER" => \$mailer,
257 "MAIL_PATH" => \$mail_path,
258 "MAIL_COMMAND" => \$mail_command,
259 "EMAIL_ON_ERROR" => \$email_on_error,
260 "EMAIL_WHEN_FINISHED" => \$email_when_finished,
261 "EMAIL_WHEN_STARTED" => \$email_when_started,
262 "EMAIL_WHEN_CANCELED" => \$email_when_canceled,
232 "MACHINE" => \$machine, 263 "MACHINE" => \$machine,
233 "SSH_USER" => \$ssh_user, 264 "SSH_USER" => \$ssh_user,
234 "TMP_DIR" => \$tmpdir, 265 "TMP_DIR" => \$tmpdir,
@@ -296,6 +327,8 @@ my %option_map = (
296 "STORE_SUCCESSES" => \$store_successes, 327 "STORE_SUCCESSES" => \$store_successes,
297 "TEST_NAME" => \$test_name, 328 "TEST_NAME" => \$test_name,
298 "TIMEOUT" => \$timeout, 329 "TIMEOUT" => \$timeout,
330 "CONNECT_TIMEOUT" => \$connect_timeout,
331 "CONFIG_BISECT_EXEC" => \$config_bisect_exec,
299 "BOOTED_TIMEOUT" => \$booted_timeout, 332 "BOOTED_TIMEOUT" => \$booted_timeout,
300 "CONSOLE" => \$console, 333 "CONSOLE" => \$console,
301 "CLOSE_CONSOLE_SIGNAL" => \$close_console_signal, 334 "CLOSE_CONSOLE_SIGNAL" => \$close_console_signal,
@@ -337,6 +370,7 @@ my %used_options;
337 370
338# default variables that can be used 371# default variables that can be used
339chomp ($variable{"PWD"} = `pwd`); 372chomp ($variable{"PWD"} = `pwd`);
373$pwd = $variable{"PWD"};
340 374
341$config_help{"MACHINE"} = << "EOF" 375$config_help{"MACHINE"} = << "EOF"
342 The machine hostname that you will test. 376 The machine hostname that you will test.
@@ -718,22 +752,14 @@ sub set_value {
718 752
719 my $prvalue = process_variables($rvalue); 753 my $prvalue = process_variables($rvalue);
720 754
721 if ($buildonly && $lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $prvalue ne "build") { 755 if ($lvalue =~ /^(TEST|BISECT|CONFIG_BISECT)_TYPE(\[.*\])?$/ &&
756 $prvalue !~ /^(config_|)bisect$/ &&
757 $prvalue !~ /^build$/ &&
758 $buildonly) {
759
722 # Note if a test is something other than build, then we 760 # Note if a test is something other than build, then we
723 # will need other mandatory options. 761 # will need other mandatory options.
724 if ($prvalue ne "install") { 762 if ($prvalue ne "install") {
725 # for bisect, we need to check BISECT_TYPE
726 if ($prvalue ne "bisect") {
727 $buildonly = 0;
728 }
729 } else {
730 # install still limits some mandatory options.
731 $buildonly = 2;
732 }
733 }
734
735 if ($buildonly && $lvalue =~ /^BISECT_TYPE(\[.*\])?$/ && $prvalue ne "build") {
736 if ($prvalue ne "install") {
737 $buildonly = 0; 763 $buildonly = 0;
738 } else { 764 } else {
739 # install still limits some mandatory options. 765 # install still limits some mandatory options.
@@ -1140,7 +1166,8 @@ sub __read_config {
1140sub get_test_case { 1166sub get_test_case {
1141 print "What test case would you like to run?\n"; 1167 print "What test case would you like to run?\n";
1142 print " (build, install or boot)\n"; 1168 print " (build, install or boot)\n";
1143 print " Other tests are available but require editing the config file\n"; 1169 print " Other tests are available but require editing ktest.conf\n";
1170 print " (see tools/testing/ktest/sample.conf)\n";
1144 my $ans = <STDIN>; 1171 my $ans = <STDIN>;
1145 chomp $ans; 1172 chomp $ans;
1146 $default{"TEST_TYPE"} = $ans; 1173 $default{"TEST_TYPE"} = $ans;
@@ -1328,8 +1355,8 @@ sub reboot {
1328 my ($time) = @_; 1355 my ($time) = @_;
1329 my $powercycle = 0; 1356 my $powercycle = 0;
1330 1357
1331 # test if the machine can be connected to within 5 seconds 1358 # test if the machine can be connected to within a few seconds
1332 my $stat = run_ssh("echo check machine status", 5); 1359 my $stat = run_ssh("echo check machine status", $connect_timeout);
1333 if (!$stat) { 1360 if (!$stat) {
1334 doprint("power cycle\n"); 1361 doprint("power cycle\n");
1335 $powercycle = 1; 1362 $powercycle = 1;
@@ -1404,10 +1431,18 @@ sub do_not_reboot {
1404 1431
1405 return $test_type eq "build" || $no_reboot || 1432 return $test_type eq "build" || $no_reboot ||
1406 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") || 1433 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
1407 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build"); 1434 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build") ||
1435 ($test_type eq "config_bisect" && $opt{"CONFIG_BISECT_TYPE[$i]"} eq "build");
1408} 1436}
1409 1437
1438my $in_die = 0;
1439
1410sub dodie { 1440sub dodie {
1441
1442 # avoid recusion
1443 return if ($in_die);
1444 $in_die = 1;
1445
1411 doprint "CRITICAL FAILURE... ", @_, "\n"; 1446 doprint "CRITICAL FAILURE... ", @_, "\n";
1412 1447
1413 my $i = $iteration; 1448 my $i = $iteration;
@@ -1426,6 +1461,11 @@ sub dodie {
1426 print " See $opt{LOG_FILE} for more info.\n"; 1461 print " See $opt{LOG_FILE} for more info.\n";
1427 } 1462 }
1428 1463
1464 if ($email_on_error) {
1465 send_email("KTEST: critical failure for your [$test_type] test",
1466 "Your test started at $script_start_time has failed with:\n@_\n");
1467 }
1468
1429 if ($monitor_cnt) { 1469 if ($monitor_cnt) {
1430 # restore terminal settings 1470 # restore terminal settings
1431 system("stty $stty_orig"); 1471 system("stty $stty_orig");
@@ -1477,7 +1517,7 @@ sub exec_console {
1477 close($pts); 1517 close($pts);
1478 1518
1479 exec $console or 1519 exec $console or
1480 die "Can't open console $console"; 1520 dodie "Can't open console $console";
1481} 1521}
1482 1522
1483sub open_console { 1523sub open_console {
@@ -1515,6 +1555,9 @@ sub close_console {
1515 doprint "kill child process $pid\n"; 1555 doprint "kill child process $pid\n";
1516 kill $close_console_signal, $pid; 1556 kill $close_console_signal, $pid;
1517 1557
1558 doprint "wait for child process $pid to exit\n";
1559 waitpid($pid, 0);
1560
1518 print "closing!\n"; 1561 print "closing!\n";
1519 close($fp); 1562 close($fp);
1520 1563
@@ -1625,7 +1668,7 @@ sub save_logs {
1625 1668
1626 if (!-d $dir) { 1669 if (!-d $dir) {
1627 mkpath($dir) or 1670 mkpath($dir) or
1628 die "can't create $dir"; 1671 dodie "can't create $dir";
1629 } 1672 }
1630 1673
1631 my %files = ( 1674 my %files = (
@@ -1638,7 +1681,7 @@ sub save_logs {
1638 while (my ($name, $source) = each(%files)) { 1681 while (my ($name, $source) = each(%files)) {
1639 if (-f "$source") { 1682 if (-f "$source") {
1640 cp "$source", "$dir/$name" or 1683 cp "$source", "$dir/$name" or
1641 die "failed to copy $source"; 1684 dodie "failed to copy $source";
1642 } 1685 }
1643 } 1686 }
1644 1687
@@ -1692,6 +1735,7 @@ sub run_command {
1692 my $end_time; 1735 my $end_time;
1693 my $dolog = 0; 1736 my $dolog = 0;
1694 my $dord = 0; 1737 my $dord = 0;
1738 my $dostdout = 0;
1695 my $pid; 1739 my $pid;
1696 1740
1697 $command =~ s/\$SSH_USER/$ssh_user/g; 1741 $command =~ s/\$SSH_USER/$ssh_user/g;
@@ -1710,9 +1754,15 @@ sub run_command {
1710 } 1754 }
1711 1755
1712 if (defined($redirect)) { 1756 if (defined($redirect)) {
1713 open (RD, ">$redirect") or 1757 if ($redirect eq 1) {
1714 dodie "failed to write to redirect $redirect"; 1758 $dostdout = 1;
1715 $dord = 1; 1759 # Have the output of the command on its own line
1760 doprint "\n";
1761 } else {
1762 open (RD, ">$redirect") or
1763 dodie "failed to write to redirect $redirect";
1764 $dord = 1;
1765 }
1716 } 1766 }
1717 1767
1718 my $hit_timeout = 0; 1768 my $hit_timeout = 0;
@@ -1734,6 +1784,7 @@ sub run_command {
1734 } 1784 }
1735 print LOG $line if ($dolog); 1785 print LOG $line if ($dolog);
1736 print RD $line if ($dord); 1786 print RD $line if ($dord);
1787 print $line if ($dostdout);
1737 } 1788 }
1738 1789
1739 waitpid($pid, 0); 1790 waitpid($pid, 0);
@@ -1812,7 +1863,7 @@ sub get_grub2_index {
1812 $ssh_grub =~ s,\$SSH_COMMAND,cat $grub_file,g; 1863 $ssh_grub =~ s,\$SSH_COMMAND,cat $grub_file,g;
1813 1864
1814 open(IN, "$ssh_grub |") 1865 open(IN, "$ssh_grub |")
1815 or die "unable to get $grub_file"; 1866 or dodie "unable to get $grub_file";
1816 1867
1817 my $found = 0; 1868 my $found = 0;
1818 1869
@@ -1821,13 +1872,13 @@ sub get_grub2_index {
1821 $grub_number++; 1872 $grub_number++;
1822 $found = 1; 1873 $found = 1;
1823 last; 1874 last;
1824 } elsif (/^menuentry\s/) { 1875 } elsif (/^menuentry\s|^submenu\s/) {
1825 $grub_number++; 1876 $grub_number++;
1826 } 1877 }
1827 } 1878 }
1828 close(IN); 1879 close(IN);
1829 1880
1830 die "Could not find '$grub_menu' in $grub_file on $machine" 1881 dodie "Could not find '$grub_menu' in $grub_file on $machine"
1831 if (!$found); 1882 if (!$found);
1832 doprint "$grub_number\n"; 1883 doprint "$grub_number\n";
1833 $last_grub_menu = $grub_menu; 1884 $last_grub_menu = $grub_menu;
@@ -1855,7 +1906,7 @@ sub get_grub_index {
1855 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g; 1906 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1856 1907
1857 open(IN, "$ssh_grub |") 1908 open(IN, "$ssh_grub |")
1858 or die "unable to get menu.lst"; 1909 or dodie "unable to get menu.lst";
1859 1910
1860 my $found = 0; 1911 my $found = 0;
1861 1912
@@ -1870,7 +1921,7 @@ sub get_grub_index {
1870 } 1921 }
1871 close(IN); 1922 close(IN);
1872 1923
1873 die "Could not find '$grub_menu' in /boot/grub/menu on $machine" 1924 dodie "Could not find '$grub_menu' in /boot/grub/menu on $machine"
1874 if (!$found); 1925 if (!$found);
1875 doprint "$grub_number\n"; 1926 doprint "$grub_number\n";
1876 $last_grub_menu = $grub_menu; 1927 $last_grub_menu = $grub_menu;
@@ -1983,7 +2034,7 @@ sub monitor {
1983 my $full_line = ""; 2034 my $full_line = "";
1984 2035
1985 open(DMESG, "> $dmesg") or 2036 open(DMESG, "> $dmesg") or
1986 die "unable to write to $dmesg"; 2037 dodie "unable to write to $dmesg";
1987 2038
1988 reboot_to; 2039 reboot_to;
1989 2040
@@ -2862,7 +2913,7 @@ sub run_bisect {
2862sub update_bisect_replay { 2913sub update_bisect_replay {
2863 my $tmp_log = "$tmpdir/ktest_bisect_log"; 2914 my $tmp_log = "$tmpdir/ktest_bisect_log";
2864 run_command "git bisect log > $tmp_log" or 2915 run_command "git bisect log > $tmp_log" or
2865 die "can't create bisect log"; 2916 dodie "can't create bisect log";
2866 return $tmp_log; 2917 return $tmp_log;
2867} 2918}
2868 2919
@@ -2871,9 +2922,9 @@ sub bisect {
2871 2922
2872 my $result; 2923 my $result;
2873 2924
2874 die "BISECT_GOOD[$i] not defined\n" if (!defined($bisect_good)); 2925 dodie "BISECT_GOOD[$i] not defined\n" if (!defined($bisect_good));
2875 die "BISECT_BAD[$i] not defined\n" if (!defined($bisect_bad)); 2926 dodie "BISECT_BAD[$i] not defined\n" if (!defined($bisect_bad));
2876 die "BISECT_TYPE[$i] not defined\n" if (!defined($bisect_type)); 2927 dodie "BISECT_TYPE[$i] not defined\n" if (!defined($bisect_type));
2877 2928
2878 my $good = $bisect_good; 2929 my $good = $bisect_good;
2879 my $bad = $bisect_bad; 2930 my $bad = $bisect_bad;
@@ -2936,7 +2987,7 @@ sub bisect {
2936 if ($check ne "good") { 2987 if ($check ne "good") {
2937 doprint "TESTING BISECT BAD [$bad]\n"; 2988 doprint "TESTING BISECT BAD [$bad]\n";
2938 run_command "git checkout $bad" or 2989 run_command "git checkout $bad" or
2939 die "Failed to checkout $bad"; 2990 dodie "Failed to checkout $bad";
2940 2991
2941 $result = run_bisect $type; 2992 $result = run_bisect $type;
2942 2993
@@ -2948,7 +2999,7 @@ sub bisect {
2948 if ($check ne "bad") { 2999 if ($check ne "bad") {
2949 doprint "TESTING BISECT GOOD [$good]\n"; 3000 doprint "TESTING BISECT GOOD [$good]\n";
2950 run_command "git checkout $good" or 3001 run_command "git checkout $good" or
2951 die "Failed to checkout $good"; 3002 dodie "Failed to checkout $good";
2952 3003
2953 $result = run_bisect $type; 3004 $result = run_bisect $type;
2954 3005
@@ -2959,7 +3010,7 @@ sub bisect {
2959 3010
2960 # checkout where we started 3011 # checkout where we started
2961 run_command "git checkout $head" or 3012 run_command "git checkout $head" or
2962 die "Failed to checkout $head"; 3013 dodie "Failed to checkout $head";
2963 } 3014 }
2964 3015
2965 run_command "git bisect start$start_files" or 3016 run_command "git bisect start$start_files" or
@@ -3092,76 +3143,6 @@ sub create_config {
3092 make_oldconfig; 3143 make_oldconfig;
3093} 3144}
3094 3145
3095# compare two config hashes, and return configs with different vals.
3096# It returns B's config values, but you can use A to see what A was.
3097sub diff_config_vals {
3098 my ($pa, $pb) = @_;
3099
3100 # crappy Perl way to pass in hashes.
3101 my %a = %{$pa};
3102 my %b = %{$pb};
3103
3104 my %ret;
3105
3106 foreach my $item (keys %a) {
3107 if (defined($b{$item}) && $b{$item} ne $a{$item}) {
3108 $ret{$item} = $b{$item};
3109 }
3110 }
3111
3112 return %ret;
3113}
3114
3115# compare two config hashes and return the configs in B but not A
3116sub diff_configs {
3117 my ($pa, $pb) = @_;
3118
3119 my %ret;
3120
3121 # crappy Perl way to pass in hashes.
3122 my %a = %{$pa};
3123 my %b = %{$pb};
3124
3125 foreach my $item (keys %b) {
3126 if (!defined($a{$item})) {
3127 $ret{$item} = $b{$item};
3128 }
3129 }
3130
3131 return %ret;
3132}
3133
3134# return if two configs are equal or not
3135# 0 is equal +1 b has something a does not
3136# +1 if a and b have a different item.
3137# -1 if a has something b does not
3138sub compare_configs {
3139 my ($pa, $pb) = @_;
3140
3141 my %ret;
3142
3143 # crappy Perl way to pass in hashes.
3144 my %a = %{$pa};
3145 my %b = %{$pb};
3146
3147 foreach my $item (keys %b) {
3148 if (!defined($a{$item})) {
3149 return 1;
3150 }
3151 if ($a{$item} ne $b{$item}) {
3152 return 1;
3153 }
3154 }
3155
3156 foreach my $item (keys %a) {
3157 if (!defined($b{$item})) {
3158 return -1;
3159 }
3160 }
3161
3162 return 0;
3163}
3164
3165sub run_config_bisect_test { 3146sub run_config_bisect_test {
3166 my ($type) = @_; 3147 my ($type) = @_;
3167 3148
@@ -3174,166 +3155,57 @@ sub run_config_bisect_test {
3174 return $ret; 3155 return $ret;
3175} 3156}
3176 3157
3177sub process_failed { 3158sub config_bisect_end {
3178 my ($config) = @_; 3159 my ($good, $bad) = @_;
3160 my $diffexec = "diff -u";
3179 3161
3162 if (-f "$builddir/scripts/diffconfig") {
3163 $diffexec = "$builddir/scripts/diffconfig";
3164 }
3180 doprint "\n\n***************************************\n"; 3165 doprint "\n\n***************************************\n";
3181 doprint "Found bad config: $config\n"; 3166 doprint "No more config bisecting possible.\n";
3167 run_command "$diffexec $good $bad", 1;
3182 doprint "***************************************\n\n"; 3168 doprint "***************************************\n\n";
3183} 3169}
3184 3170
3185# used for config bisecting
3186my $good_config;
3187my $bad_config;
3188
3189sub process_new_config {
3190 my ($tc, $nc, $gc, $bc) = @_;
3191
3192 my %tmp_config = %{$tc};
3193 my %good_configs = %{$gc};
3194 my %bad_configs = %{$bc};
3195
3196 my %new_configs;
3197
3198 my $runtest = 1;
3199 my $ret;
3200
3201 create_config "tmp_configs", \%tmp_config;
3202 assign_configs \%new_configs, $output_config;
3203
3204 $ret = compare_configs \%new_configs, \%bad_configs;
3205 if (!$ret) {
3206 doprint "New config equals bad config, try next test\n";
3207 $runtest = 0;
3208 }
3209
3210 if ($runtest) {
3211 $ret = compare_configs \%new_configs, \%good_configs;
3212 if (!$ret) {
3213 doprint "New config equals good config, try next test\n";
3214 $runtest = 0;
3215 }
3216 }
3217
3218 %{$nc} = %new_configs;
3219
3220 return $runtest;
3221}
3222
3223sub run_config_bisect { 3171sub run_config_bisect {
3224 my ($pgood, $pbad) = @_; 3172 my ($good, $bad, $last_result) = @_;
3225 3173 my $reset = "";
3226 my $type = $config_bisect_type; 3174 my $cmd;
3227
3228 my %good_configs = %{$pgood};
3229 my %bad_configs = %{$pbad};
3230
3231 my %diff_configs = diff_config_vals \%good_configs, \%bad_configs;
3232 my %b_configs = diff_configs \%good_configs, \%bad_configs;
3233 my %g_configs = diff_configs \%bad_configs, \%good_configs;
3234
3235 my @diff_arr = keys %diff_configs;
3236 my $len_diff = $#diff_arr + 1;
3237
3238 my @b_arr = keys %b_configs;
3239 my $len_b = $#b_arr + 1;
3240
3241 my @g_arr = keys %g_configs;
3242 my $len_g = $#g_arr + 1;
3243
3244 my $runtest = 1;
3245 my %new_configs;
3246 my $ret; 3175 my $ret;
3247 3176
3248 # First, lets get it down to a single subset. 3177 if (!length($last_result)) {
3249 # Is the problem with a difference in values? 3178 $reset = "-r";
3250 # Is the problem with a missing config?
3251 # Is the problem with a config that breaks things?
3252
3253 # Enable all of one set and see if we get a new bad
3254 # or good config.
3255
3256 # first set the good config to the bad values.
3257
3258 doprint "d=$len_diff g=$len_g b=$len_b\n";
3259
3260 # first lets enable things in bad config that are enabled in good config
3261
3262 if ($len_diff > 0) {
3263 if ($len_b > 0 || $len_g > 0) {
3264 my %tmp_config = %bad_configs;
3265
3266 doprint "Set tmp config to be bad config with good config values\n";
3267 foreach my $item (@diff_arr) {
3268 $tmp_config{$item} = $good_configs{$item};
3269 }
3270
3271 $runtest = process_new_config \%tmp_config, \%new_configs,
3272 \%good_configs, \%bad_configs;
3273 }
3274 } 3179 }
3180 run_command "$config_bisect_exec $reset -b $outputdir $good $bad $last_result", 1;
3275 3181
3276 if (!$runtest && $len_diff > 0) { 3182 # config-bisect returns:
3277 3183 # 0 if there is more to bisect
3278 if ($len_diff == 1) { 3184 # 1 for finding a good config
3279 process_failed $diff_arr[0]; 3185 # 2 if it can not find any more configs
3280 return 1; 3186 # -1 (255) on error
3281 } 3187 if ($run_command_status) {
3282 my %tmp_config = %bad_configs; 3188 return $run_command_status;
3283
3284 my $half = int($#diff_arr / 2);
3285 my @tophalf = @diff_arr[0 .. $half];
3286
3287 doprint "Settings bisect with top half:\n";
3288 doprint "Set tmp config to be bad config with some good config values\n";
3289 foreach my $item (@tophalf) {
3290 $tmp_config{$item} = $good_configs{$item};
3291 }
3292
3293 $runtest = process_new_config \%tmp_config, \%new_configs,
3294 \%good_configs, \%bad_configs;
3295
3296 if (!$runtest) {
3297 my %tmp_config = %bad_configs;
3298
3299 doprint "Try bottom half\n";
3300
3301 my @bottomhalf = @diff_arr[$half+1 .. $#diff_arr];
3302
3303 foreach my $item (@bottomhalf) {
3304 $tmp_config{$item} = $good_configs{$item};
3305 }
3306
3307 $runtest = process_new_config \%tmp_config, \%new_configs,
3308 \%good_configs, \%bad_configs;
3309 }
3310 } 3189 }
3311 3190
3312 if ($runtest) { 3191 $ret = run_config_bisect_test $config_bisect_type;
3313 $ret = run_config_bisect_test $type; 3192 if ($ret) {
3314 if ($ret) { 3193 doprint "NEW GOOD CONFIG\n";
3315 doprint "NEW GOOD CONFIG\n"; 3194 # Return 3 for good config
3316 %good_configs = %new_configs; 3195 return 3;
3317 run_command "mv $good_config ${good_config}.last"; 3196 } else {
3318 save_config \%good_configs, $good_config; 3197 doprint "NEW BAD CONFIG\n";
3319 %{$pgood} = %good_configs; 3198 # Return 4 for bad config
3320 } else { 3199 return 4;
3321 doprint "NEW BAD CONFIG\n";
3322 %bad_configs = %new_configs;
3323 run_command "mv $bad_config ${bad_config}.last";
3324 save_config \%bad_configs, $bad_config;
3325 %{$pbad} = %bad_configs;
3326 }
3327 return 0;
3328 } 3200 }
3329
3330 fail "Hmm, need to do a mix match?\n";
3331 return -1;
3332} 3201}
3333 3202
3334sub config_bisect { 3203sub config_bisect {
3335 my ($i) = @_; 3204 my ($i) = @_;
3336 3205
3206 my $good_config;
3207 my $bad_config;
3208
3337 my $type = $config_bisect_type; 3209 my $type = $config_bisect_type;
3338 my $ret; 3210 my $ret;
3339 3211
@@ -3353,6 +3225,24 @@ sub config_bisect {
3353 $good_config = $output_config; 3225 $good_config = $output_config;
3354 } 3226 }
3355 3227
3228 if (!defined($config_bisect_exec)) {
3229 # First check the location that ktest.pl ran
3230 my @locations = ( "$pwd/config-bisect.pl",
3231 "$dirname/config-bisect.pl",
3232 "$builddir/tools/testing/ktest/config-bisect.pl",
3233 undef );
3234 foreach my $loc (@locations) {
3235 doprint "loc = $loc\n";
3236 $config_bisect_exec = $loc;
3237 last if (defined($config_bisect_exec && -x $config_bisect_exec));
3238 }
3239 if (!defined($config_bisect_exec)) {
3240 fail "Could not find an executable config-bisect.pl\n",
3241 " Set CONFIG_BISECT_EXEC to point to config-bisect.pl";
3242 return 1;
3243 }
3244 }
3245
3356 # we don't want min configs to cause issues here. 3246 # we don't want min configs to cause issues here.
3357 doprint "Disabling 'MIN_CONFIG' for this test\n"; 3247 doprint "Disabling 'MIN_CONFIG' for this test\n";
3358 undef $minconfig; 3248 undef $minconfig;
@@ -3361,21 +3251,31 @@ sub config_bisect {
3361 my %bad_configs; 3251 my %bad_configs;
3362 my %tmp_configs; 3252 my %tmp_configs;
3363 3253
3254 if (-f "$tmpdir/good_config.tmp" || -f "$tmpdir/bad_config.tmp") {
3255 if (read_yn "Interrupted config-bisect. Continue (n - will start new)?") {
3256 if (-f "$tmpdir/good_config.tmp") {
3257 $good_config = "$tmpdir/good_config.tmp";
3258 } else {
3259 $good_config = "$tmpdir/good_config";
3260 }
3261 if (-f "$tmpdir/bad_config.tmp") {
3262 $bad_config = "$tmpdir/bad_config.tmp";
3263 } else {
3264 $bad_config = "$tmpdir/bad_config";
3265 }
3266 }
3267 }
3364 doprint "Run good configs through make oldconfig\n"; 3268 doprint "Run good configs through make oldconfig\n";
3365 assign_configs \%tmp_configs, $good_config; 3269 assign_configs \%tmp_configs, $good_config;
3366 create_config "$good_config", \%tmp_configs; 3270 create_config "$good_config", \%tmp_configs;
3367 assign_configs \%good_configs, $output_config; 3271 $good_config = "$tmpdir/good_config";
3272 system("cp $output_config $good_config") == 0 or dodie "cp good config";
3368 3273
3369 doprint "Run bad configs through make oldconfig\n"; 3274 doprint "Run bad configs through make oldconfig\n";
3370 assign_configs \%tmp_configs, $bad_config; 3275 assign_configs \%tmp_configs, $bad_config;
3371 create_config "$bad_config", \%tmp_configs; 3276 create_config "$bad_config", \%tmp_configs;
3372 assign_configs \%bad_configs, $output_config;
3373
3374 $good_config = "$tmpdir/good_config";
3375 $bad_config = "$tmpdir/bad_config"; 3277 $bad_config = "$tmpdir/bad_config";
3376 3278 system("cp $output_config $bad_config") == 0 or dodie "cp bad config";
3377 save_config \%good_configs, $good_config;
3378 save_config \%bad_configs, $bad_config;
3379 3279
3380 if (defined($config_bisect_check) && $config_bisect_check ne "0") { 3280 if (defined($config_bisect_check) && $config_bisect_check ne "0") {
3381 if ($config_bisect_check ne "good") { 3281 if ($config_bisect_check ne "good") {
@@ -3398,10 +3298,21 @@ sub config_bisect {
3398 } 3298 }
3399 } 3299 }
3400 3300
3301 my $last_run = "";
3302
3401 do { 3303 do {
3402 $ret = run_config_bisect \%good_configs, \%bad_configs; 3304 $ret = run_config_bisect $good_config, $bad_config, $last_run;
3305 if ($ret == 3) {
3306 $last_run = "good";
3307 } elsif ($ret == 4) {
3308 $last_run = "bad";
3309 }
3403 print_times; 3310 print_times;
3404 } while (!$ret); 3311 } while ($ret == 3 || $ret == 4);
3312
3313 if ($ret == 2) {
3314 config_bisect_end "$good_config.tmp", "$bad_config.tmp";
3315 }
3405 3316
3406 return $ret if ($ret < 0); 3317 return $ret if ($ret < 0);
3407 3318
@@ -3416,9 +3327,9 @@ sub patchcheck_reboot {
3416sub patchcheck { 3327sub patchcheck {
3417 my ($i) = @_; 3328 my ($i) = @_;
3418 3329
3419 die "PATCHCHECK_START[$i] not defined\n" 3330 dodie "PATCHCHECK_START[$i] not defined\n"
3420 if (!defined($patchcheck_start)); 3331 if (!defined($patchcheck_start));
3421 die "PATCHCHECK_TYPE[$i] not defined\n" 3332 dodie "PATCHCHECK_TYPE[$i] not defined\n"
3422 if (!defined($patchcheck_type)); 3333 if (!defined($patchcheck_type));
3423 3334
3424 my $start = $patchcheck_start; 3335 my $start = $patchcheck_start;
@@ -3432,7 +3343,7 @@ sub patchcheck {
3432 if (defined($patchcheck_end)) { 3343 if (defined($patchcheck_end)) {
3433 $end = $patchcheck_end; 3344 $end = $patchcheck_end;
3434 } elsif ($cherry) { 3345 } elsif ($cherry) {
3435 die "PATCHCHECK_END must be defined with PATCHCHECK_CHERRY\n"; 3346 dodie "PATCHCHECK_END must be defined with PATCHCHECK_CHERRY\n";
3436 } 3347 }
3437 3348
3438 # Get the true sha1's since we can use things like HEAD~3 3349 # Get the true sha1's since we can use things like HEAD~3
@@ -3496,7 +3407,7 @@ sub patchcheck {
3496 doprint "\nProcessing commit \"$item\"\n\n"; 3407 doprint "\nProcessing commit \"$item\"\n\n";
3497 3408
3498 run_command "git checkout $sha1" or 3409 run_command "git checkout $sha1" or
3499 die "Failed to checkout $sha1"; 3410 dodie "Failed to checkout $sha1";
3500 3411
3501 # only clean on the first and last patch 3412 # only clean on the first and last patch
3502 if ($item eq $list[0] || 3413 if ($item eq $list[0] ||
@@ -3587,7 +3498,7 @@ sub read_kconfig {
3587 } 3498 }
3588 3499
3589 open(KIN, "$kconfig") 3500 open(KIN, "$kconfig")
3590 or die "Can't open $kconfig"; 3501 or dodie "Can't open $kconfig";
3591 while (<KIN>) { 3502 while (<KIN>) {
3592 chomp; 3503 chomp;
3593 3504
@@ -3746,7 +3657,7 @@ sub get_depends {
3746 3657
3747 $dep =~ s/^[^$valid]*[$valid]+//; 3658 $dep =~ s/^[^$valid]*[$valid]+//;
3748 } else { 3659 } else {
3749 die "this should never happen"; 3660 dodie "this should never happen";
3750 } 3661 }
3751 } 3662 }
3752 3663
@@ -4007,7 +3918,7 @@ sub make_min_config {
4007 # update new ignore configs 3918 # update new ignore configs
4008 if (defined($ignore_config)) { 3919 if (defined($ignore_config)) {
4009 open (OUT, ">$temp_config") 3920 open (OUT, ">$temp_config")
4010 or die "Can't write to $temp_config"; 3921 or dodie "Can't write to $temp_config";
4011 foreach my $config (keys %save_configs) { 3922 foreach my $config (keys %save_configs) {
4012 print OUT "$save_configs{$config}\n"; 3923 print OUT "$save_configs{$config}\n";
4013 } 3924 }
@@ -4035,7 +3946,7 @@ sub make_min_config {
4035 3946
4036 # Save off all the current mandatory configs 3947 # Save off all the current mandatory configs
4037 open (OUT, ">$temp_config") 3948 open (OUT, ">$temp_config")
4038 or die "Can't write to $temp_config"; 3949 or dodie "Can't write to $temp_config";
4039 foreach my $config (keys %keep_configs) { 3950 foreach my $config (keys %keep_configs) {
4040 print OUT "$keep_configs{$config}\n"; 3951 print OUT "$keep_configs{$config}\n";
4041 } 3952 }
@@ -4222,6 +4133,74 @@ sub set_test_option {
4222 return eval_option($name, $option, $i); 4133 return eval_option($name, $option, $i);
4223} 4134}
4224 4135
4136sub find_mailer {
4137 my ($mailer) = @_;
4138
4139 my @paths = split /:/, $ENV{PATH};
4140
4141 # sendmail is usually in /usr/sbin
4142 $paths[$#paths + 1] = "/usr/sbin";
4143
4144 foreach my $path (@paths) {
4145 if (-x "$path/$mailer") {
4146 return $path;
4147 }
4148 }
4149
4150 return undef;
4151}
4152
4153sub do_send_mail {
4154 my ($subject, $message) = @_;
4155
4156 if (!defined($mail_path)) {
4157 # find the mailer
4158 $mail_path = find_mailer $mailer;
4159 if (!defined($mail_path)) {
4160 die "\nCan not find $mailer in PATH\n";
4161 }
4162 }
4163
4164 if (!defined($mail_command)) {
4165 if ($mailer eq "mail" || $mailer eq "mailx") {
4166 $mail_command = "\$MAIL_PATH/\$MAILER -s \'\$SUBJECT\' \$MAILTO <<< \'\$MESSAGE\'";
4167 } elsif ($mailer eq "sendmail" ) {
4168 $mail_command = "echo \'Subject: \$SUBJECT\n\n\$MESSAGE\' | \$MAIL_PATH/\$MAILER -t \$MAILTO";
4169 } else {
4170 die "\nYour mailer: $mailer is not supported.\n";
4171 }
4172 }
4173
4174 $mail_command =~ s/\$MAILER/$mailer/g;
4175 $mail_command =~ s/\$MAIL_PATH/$mail_path/g;
4176 $mail_command =~ s/\$MAILTO/$mailto/g;
4177 $mail_command =~ s/\$SUBJECT/$subject/g;
4178 $mail_command =~ s/\$MESSAGE/$message/g;
4179
4180 run_command $mail_command;
4181}
4182
4183sub send_email {
4184
4185 if (defined($mailto)) {
4186 if (!defined($mailer)) {
4187 doprint "No email sent: email or mailer not specified in config.\n";
4188 return;
4189 }
4190 do_send_mail @_;
4191 }
4192}
4193
4194sub cancel_test {
4195 if ($email_when_canceled) {
4196 send_email("KTEST: Your [$test_type] test was cancelled",
4197 "Your test started at $script_start_time was cancelled: sig int");
4198 }
4199 die "\nCaught Sig Int, test interrupted: $!\n"
4200}
4201
4202$SIG{INT} = qw(cancel_test);
4203
4225# First we need to do is the builds 4204# First we need to do is the builds
4226for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { 4205for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
4227 4206
@@ -4245,11 +4224,11 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
4245 $outputdir = set_test_option("OUTPUT_DIR", $i); 4224 $outputdir = set_test_option("OUTPUT_DIR", $i);
4246 $builddir = set_test_option("BUILD_DIR", $i); 4225 $builddir = set_test_option("BUILD_DIR", $i);
4247 4226
4248 chdir $builddir || die "can't change directory to $builddir"; 4227 chdir $builddir || dodie "can't change directory to $builddir";
4249 4228
4250 if (!-d $outputdir) { 4229 if (!-d $outputdir) {
4251 mkpath($outputdir) or 4230 mkpath($outputdir) or
4252 die "can't create $outputdir"; 4231 dodie "can't create $outputdir";
4253 } 4232 }
4254 4233
4255 $make = "$makecmd O=$outputdir"; 4234 $make = "$makecmd O=$outputdir";
@@ -4262,9 +4241,15 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
4262 $start_minconfig_defined = 1; 4241 $start_minconfig_defined = 1;
4263 4242
4264 # The first test may override the PRE_KTEST option 4243 # The first test may override the PRE_KTEST option
4265 if (defined($pre_ktest) && $i == 1) { 4244 if ($i == 1) {
4266 doprint "\n"; 4245 if (defined($pre_ktest)) {
4267 run_command $pre_ktest; 4246 doprint "\n";
4247 run_command $pre_ktest;
4248 }
4249 if ($email_when_started) {
4250 send_email("KTEST: Your [$test_type] test was started",
4251 "Your test was started on $script_start_time");
4252 }
4268 } 4253 }
4269 4254
4270 # Any test can override the POST_KTEST option 4255 # Any test can override the POST_KTEST option
@@ -4280,7 +4265,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
4280 4265
4281 if (!-d $tmpdir) { 4266 if (!-d $tmpdir) {
4282 mkpath($tmpdir) or 4267 mkpath($tmpdir) or
4283 die "can't create $tmpdir"; 4268 dodie "can't create $tmpdir";
4284 } 4269 }
4285 4270
4286 $ENV{"SSH_USER"} = $ssh_user; 4271 $ENV{"SSH_USER"} = $ssh_user;
@@ -4353,7 +4338,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
4353 4338
4354 if (defined($checkout)) { 4339 if (defined($checkout)) {
4355 run_command "git checkout $checkout" or 4340 run_command "git checkout $checkout" or
4356 die "failed to checkout $checkout"; 4341 dodie "failed to checkout $checkout";
4357 } 4342 }
4358 4343
4359 $no_reboot = 0; 4344 $no_reboot = 0;
@@ -4428,4 +4413,8 @@ if ($opt{"POWEROFF_ON_SUCCESS"}) {
4428 4413
4429doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n"; 4414doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
4430 4415
4416if ($email_when_finished) {
4417 send_email("KTEST: Your [$test_type] test has finished!",
4418 "$successes of $opt{NUM_TESTS} tests started at $script_start_time were successful!");
4419}
4431exit 0; 4420exit 0;
diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf
index 6c58cd8bbbae..6ca6ca0ce695 100644
--- a/tools/testing/ktest/sample.conf
+++ b/tools/testing/ktest/sample.conf
@@ -1,6 +1,11 @@
1# 1#
2# Config file for ktest.pl 2# Config file for ktest.pl
3# 3#
4# Place your customized version of this, in the working directory that
5# ktest.pl is run from. By default, ktest.pl will look for a file
6# called "ktest.conf", but you can name it anything you like and specify
7# the name of your config file as the first argument of ktest.pl.
8#
4# Note, all paths must be absolute 9# Note, all paths must be absolute
5# 10#
6 11
@@ -396,6 +401,44 @@
396 401
397#### Optional Config Options (all have defaults) #### 402#### Optional Config Options (all have defaults) ####
398 403
404# Email options for receiving notifications. Users must setup
405# the specified mailer prior to using this feature.
406#
407# (default undefined)
408#MAILTO =
409#
410# Supported mailers: sendmail, mail, mailx
411# (default sendmail)
412#MAILER = sendmail
413#
414# The executable to run
415# (default: for sendmail "/usr/sbin/sendmail", otherwise equals ${MAILER})
416#MAIL_EXEC = /usr/sbin/sendmail
417#
418# The command used to send mail, which uses the above options
419# can be modified. By default if the mailer is "sendmail" then
420# MAIL_COMMAND = echo \'Subject: $SUBJECT\n\n$MESSAGE\' | $MAIL_PATH/$MAILER -t $MAILTO
421# For mail or mailx:
422# MAIL_COMMAND = "$MAIL_PATH/$MAILER -s \'$SUBJECT\' $MAILTO <<< \'$MESSAGE\'
423# ktest.pl will do the substitution for MAIL_PATH, MAILER, MAILTO at the time
424# it sends the mail if "$FOO" format is used. If "${FOO}" format is used,
425# then the substitutions will occur at the time the config file is read.
426# But note, MAIL_PATH and MAILER require being set by the config file if
427# ${MAIL_PATH} or ${MAILER} are used, but not if $MAIL_PATH or $MAILER are.
428#MAIL_COMMAND = echo \'Subject: $SUBJECT\n\n$MESSAGE\' | $MAIL_PATH/$MAILER -t $MAILTO
429#
430# Errors are defined as those would terminate the script
431# (default 1)
432#EMAIL_ON_ERROR = 1
433# (default 1)
434#EMAIL_WHEN_FINISHED = 1
435# (default 0)
436#EMAIL_WHEN_STARTED = 1
437#
438# Users can cancel the test by Ctrl^C
439# (default 0)
440#EMAIL_WHEN_CANCELED = 1
441
399# Start a test setup. If you leave this off, all options 442# Start a test setup. If you leave this off, all options
400# will be default and the test will run once. 443# will be default and the test will run once.
401# This is a label and not really an option (it takes no value). 444# This is a label and not really an option (it takes no value).
@@ -725,6 +768,13 @@
725# (default 120) 768# (default 120)
726#TIMEOUT = 120 769#TIMEOUT = 120
727 770
771# The timeout in seconds when to test if the box can be rebooted
772# or not. Before issuing the reboot command, a ssh connection
773# is attempted to see if the target machine is still active.
774# If the target does not connect within this timeout, a power cycle
775# is issued instead of a reboot.
776# CONNECT_TIMEOUT = 25
777
728# In between tests, a reboot of the box may occur, and this 778# In between tests, a reboot of the box may occur, and this
729# is the time to wait for the console after it stops producing 779# is the time to wait for the console after it stops producing
730# output. Some machines may not produce a large lag on reboot 780# output. Some machines may not produce a large lag on reboot
@@ -1167,6 +1217,16 @@
1167# Set it to "good" to test only the good config and set it 1217# Set it to "good" to test only the good config and set it
1168# to "bad" to only test the bad config. 1218# to "bad" to only test the bad config.
1169# 1219#
1220# CONFIG_BISECT_EXEC (optional)
1221# The config bisect is a separate program that comes with ktest.pl.
1222# By befault, it will look for:
1223# `pwd`/config-bisect.pl # the location ktest.pl was executed from.
1224# If it does not find it there, it will look for:
1225# `dirname <ktest.pl>`/config-bisect.pl # The directory that holds ktest.pl
1226# If it does not find it there, it will look for:
1227# ${BUILD_DIR}/tools/testing/ktest/config-bisect.pl
1228# Setting CONFIG_BISECT_EXEC will override where it looks.
1229#
1170# Example: 1230# Example:
1171# TEST_START 1231# TEST_START
1172# TEST_TYPE = config_bisect 1232# TEST_TYPE = config_bisect
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index 620fa78b3b1b..cb166be4918d 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -104,7 +104,8 @@ enum {
104 NUM_HINTS = 8, 104 NUM_HINTS = 8,
105 NUM_BDW = NUM_DCR, 105 NUM_BDW = NUM_DCR,
106 NUM_SPA = NUM_PM + NUM_DCR + NUM_BDW, 106 NUM_SPA = NUM_PM + NUM_DCR + NUM_BDW,
107 NUM_MEM = NUM_DCR + NUM_BDW + 2 /* spa0 iset */ + 4 /* spa1 iset */, 107 NUM_MEM = NUM_DCR + NUM_BDW + 2 /* spa0 iset */
108 + 4 /* spa1 iset */ + 1 /* spa11 iset */,
108 DIMM_SIZE = SZ_32M, 109 DIMM_SIZE = SZ_32M,
109 LABEL_SIZE = SZ_128K, 110 LABEL_SIZE = SZ_128K,
110 SPA_VCD_SIZE = SZ_4M, 111 SPA_VCD_SIZE = SZ_4M,
@@ -153,6 +154,7 @@ struct nfit_test {
153 void *nfit_buf; 154 void *nfit_buf;
154 dma_addr_t nfit_dma; 155 dma_addr_t nfit_dma;
155 size_t nfit_size; 156 size_t nfit_size;
157 size_t nfit_filled;
156 int dcr_idx; 158 int dcr_idx;
157 int num_dcr; 159 int num_dcr;
158 int num_pm; 160 int num_pm;
@@ -709,7 +711,9 @@ static void smart_notify(struct device *bus_dev,
709 >= thresh->media_temperature) 711 >= thresh->media_temperature)
710 || ((thresh->alarm_control & ND_INTEL_SMART_CTEMP_TRIP) 712 || ((thresh->alarm_control & ND_INTEL_SMART_CTEMP_TRIP)
711 && smart->ctrl_temperature 713 && smart->ctrl_temperature
712 >= thresh->ctrl_temperature)) { 714 >= thresh->ctrl_temperature)
715 || (smart->health != ND_INTEL_SMART_NON_CRITICAL_HEALTH)
716 || (smart->shutdown_state != 0)) {
713 device_lock(bus_dev); 717 device_lock(bus_dev);
714 __acpi_nvdimm_notify(dimm_dev, 0x81); 718 __acpi_nvdimm_notify(dimm_dev, 0x81);
715 device_unlock(bus_dev); 719 device_unlock(bus_dev);
@@ -735,6 +739,32 @@ static int nfit_test_cmd_smart_set_threshold(
735 return 0; 739 return 0;
736} 740}
737 741
742static int nfit_test_cmd_smart_inject(
743 struct nd_intel_smart_inject *inj,
744 unsigned int buf_len,
745 struct nd_intel_smart_threshold *thresh,
746 struct nd_intel_smart *smart,
747 struct device *bus_dev, struct device *dimm_dev)
748{
749 if (buf_len != sizeof(*inj))
750 return -EINVAL;
751
752 if (inj->mtemp_enable)
753 smart->media_temperature = inj->media_temperature;
754 if (inj->spare_enable)
755 smart->spares = inj->spares;
756 if (inj->fatal_enable)
757 smart->health = ND_INTEL_SMART_FATAL_HEALTH;
758 if (inj->unsafe_shutdown_enable) {
759 smart->shutdown_state = 1;
760 smart->shutdown_count++;
761 }
762 inj->status = 0;
763 smart_notify(bus_dev, dimm_dev, smart, thresh);
764
765 return 0;
766}
767
738static void uc_error_notify(struct work_struct *work) 768static void uc_error_notify(struct work_struct *work)
739{ 769{
740 struct nfit_test *t = container_of(work, typeof(*t), work); 770 struct nfit_test *t = container_of(work, typeof(*t), work);
@@ -935,6 +965,13 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
935 t->dcr_idx], 965 t->dcr_idx],
936 &t->smart[i - t->dcr_idx], 966 &t->smart[i - t->dcr_idx],
937 &t->pdev.dev, t->dimm_dev[i]); 967 &t->pdev.dev, t->dimm_dev[i]);
968 case ND_INTEL_SMART_INJECT:
969 return nfit_test_cmd_smart_inject(buf,
970 buf_len,
971 &t->smart_threshold[i -
972 t->dcr_idx],
973 &t->smart[i - t->dcr_idx],
974 &t->pdev.dev, t->dimm_dev[i]);
938 default: 975 default:
939 return -ENOTTY; 976 return -ENOTTY;
940 } 977 }
@@ -1222,7 +1259,7 @@ static void smart_init(struct nfit_test *t)
1222 | ND_INTEL_SMART_MTEMP_VALID, 1259 | ND_INTEL_SMART_MTEMP_VALID,
1223 .health = ND_INTEL_SMART_NON_CRITICAL_HEALTH, 1260 .health = ND_INTEL_SMART_NON_CRITICAL_HEALTH,
1224 .media_temperature = 23 * 16, 1261 .media_temperature = 23 * 16,
1225 .ctrl_temperature = 30 * 16, 1262 .ctrl_temperature = 25 * 16,
1226 .pmic_temperature = 40 * 16, 1263 .pmic_temperature = 40 * 16,
1227 .spares = 75, 1264 .spares = 75,
1228 .alarm_flags = ND_INTEL_SMART_SPARE_TRIP 1265 .alarm_flags = ND_INTEL_SMART_SPARE_TRIP
@@ -1366,7 +1403,7 @@ static void nfit_test0_setup(struct nfit_test *t)
1366 struct acpi_nfit_data_region *bdw; 1403 struct acpi_nfit_data_region *bdw;
1367 struct acpi_nfit_flush_address *flush; 1404 struct acpi_nfit_flush_address *flush;
1368 struct acpi_nfit_capabilities *pcap; 1405 struct acpi_nfit_capabilities *pcap;
1369 unsigned int offset, i; 1406 unsigned int offset = 0, i;
1370 1407
1371 /* 1408 /*
1372 * spa0 (interleave first half of dimm0 and dimm1, note storage 1409 * spa0 (interleave first half of dimm0 and dimm1, note storage
@@ -1380,93 +1417,102 @@ static void nfit_test0_setup(struct nfit_test *t)
1380 spa->range_index = 0+1; 1417 spa->range_index = 0+1;
1381 spa->address = t->spa_set_dma[0]; 1418 spa->address = t->spa_set_dma[0];
1382 spa->length = SPA0_SIZE; 1419 spa->length = SPA0_SIZE;
1420 offset += spa->header.length;
1383 1421
1384 /* 1422 /*
1385 * spa1 (interleave last half of the 4 DIMMS, note storage 1423 * spa1 (interleave last half of the 4 DIMMS, note storage
1386 * does not actually alias the related block-data-window 1424 * does not actually alias the related block-data-window
1387 * regions) 1425 * regions)
1388 */ 1426 */
1389 spa = nfit_buf + sizeof(*spa); 1427 spa = nfit_buf + offset;
1390 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS; 1428 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
1391 spa->header.length = sizeof(*spa); 1429 spa->header.length = sizeof(*spa);
1392 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_PM), 16); 1430 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_PM), 16);
1393 spa->range_index = 1+1; 1431 spa->range_index = 1+1;
1394 spa->address = t->spa_set_dma[1]; 1432 spa->address = t->spa_set_dma[1];
1395 spa->length = SPA1_SIZE; 1433 spa->length = SPA1_SIZE;
1434 offset += spa->header.length;
1396 1435
1397 /* spa2 (dcr0) dimm0 */ 1436 /* spa2 (dcr0) dimm0 */
1398 spa = nfit_buf + sizeof(*spa) * 2; 1437 spa = nfit_buf + offset;
1399 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS; 1438 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
1400 spa->header.length = sizeof(*spa); 1439 spa->header.length = sizeof(*spa);
1401 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16); 1440 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16);
1402 spa->range_index = 2+1; 1441 spa->range_index = 2+1;
1403 spa->address = t->dcr_dma[0]; 1442 spa->address = t->dcr_dma[0];
1404 spa->length = DCR_SIZE; 1443 spa->length = DCR_SIZE;
1444 offset += spa->header.length;
1405 1445
1406 /* spa3 (dcr1) dimm1 */ 1446 /* spa3 (dcr1) dimm1 */
1407 spa = nfit_buf + sizeof(*spa) * 3; 1447 spa = nfit_buf + offset;
1408 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS; 1448 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
1409 spa->header.length = sizeof(*spa); 1449 spa->header.length = sizeof(*spa);
1410 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16); 1450 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16);
1411 spa->range_index = 3+1; 1451 spa->range_index = 3+1;
1412 spa->address = t->dcr_dma[1]; 1452 spa->address = t->dcr_dma[1];
1413 spa->length = DCR_SIZE; 1453 spa->length = DCR_SIZE;
1454 offset += spa->header.length;
1414 1455
1415 /* spa4 (dcr2) dimm2 */ 1456 /* spa4 (dcr2) dimm2 */
1416 spa = nfit_buf + sizeof(*spa) * 4; 1457 spa = nfit_buf + offset;
1417 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS; 1458 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
1418 spa->header.length = sizeof(*spa); 1459 spa->header.length = sizeof(*spa);
1419 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16); 1460 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16);
1420 spa->range_index = 4+1; 1461 spa->range_index = 4+1;
1421 spa->address = t->dcr_dma[2]; 1462 spa->address = t->dcr_dma[2];
1422 spa->length = DCR_SIZE; 1463 spa->length = DCR_SIZE;
1464 offset += spa->header.length;
1423 1465
1424 /* spa5 (dcr3) dimm3 */ 1466 /* spa5 (dcr3) dimm3 */
1425 spa = nfit_buf + sizeof(*spa) * 5; 1467 spa = nfit_buf + offset;
1426 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS; 1468 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
1427 spa->header.length = sizeof(*spa); 1469 spa->header.length = sizeof(*spa);
1428 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16); 1470 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16);
1429 spa->range_index = 5+1; 1471 spa->range_index = 5+1;
1430 spa->address = t->dcr_dma[3]; 1472 spa->address = t->dcr_dma[3];
1431 spa->length = DCR_SIZE; 1473 spa->length = DCR_SIZE;
1474 offset += spa->header.length;
1432 1475
1433 /* spa6 (bdw for dcr0) dimm0 */ 1476 /* spa6 (bdw for dcr0) dimm0 */
1434 spa = nfit_buf + sizeof(*spa) * 6; 1477 spa = nfit_buf + offset;
1435 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS; 1478 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
1436 spa->header.length = sizeof(*spa); 1479 spa->header.length = sizeof(*spa);
1437 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16); 1480 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
1438 spa->range_index = 6+1; 1481 spa->range_index = 6+1;
1439 spa->address = t->dimm_dma[0]; 1482 spa->address = t->dimm_dma[0];
1440 spa->length = DIMM_SIZE; 1483 spa->length = DIMM_SIZE;
1484 offset += spa->header.length;
1441 1485
1442 /* spa7 (bdw for dcr1) dimm1 */ 1486 /* spa7 (bdw for dcr1) dimm1 */
1443 spa = nfit_buf + sizeof(*spa) * 7; 1487 spa = nfit_buf + offset;
1444 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS; 1488 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
1445 spa->header.length = sizeof(*spa); 1489 spa->header.length = sizeof(*spa);
1446 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16); 1490 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
1447 spa->range_index = 7+1; 1491 spa->range_index = 7+1;
1448 spa->address = t->dimm_dma[1]; 1492 spa->address = t->dimm_dma[1];
1449 spa->length = DIMM_SIZE; 1493 spa->length = DIMM_SIZE;
1494 offset += spa->header.length;
1450 1495
1451 /* spa8 (bdw for dcr2) dimm2 */ 1496 /* spa8 (bdw for dcr2) dimm2 */
1452 spa = nfit_buf + sizeof(*spa) * 8; 1497 spa = nfit_buf + offset;
1453 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS; 1498 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
1454 spa->header.length = sizeof(*spa); 1499 spa->header.length = sizeof(*spa);
1455 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16); 1500 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
1456 spa->range_index = 8+1; 1501 spa->range_index = 8+1;
1457 spa->address = t->dimm_dma[2]; 1502 spa->address = t->dimm_dma[2];
1458 spa->length = DIMM_SIZE; 1503 spa->length = DIMM_SIZE;
1504 offset += spa->header.length;
1459 1505
1460 /* spa9 (bdw for dcr3) dimm3 */ 1506 /* spa9 (bdw for dcr3) dimm3 */
1461 spa = nfit_buf + sizeof(*spa) * 9; 1507 spa = nfit_buf + offset;
1462 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS; 1508 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
1463 spa->header.length = sizeof(*spa); 1509 spa->header.length = sizeof(*spa);
1464 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16); 1510 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
1465 spa->range_index = 9+1; 1511 spa->range_index = 9+1;
1466 spa->address = t->dimm_dma[3]; 1512 spa->address = t->dimm_dma[3];
1467 spa->length = DIMM_SIZE; 1513 spa->length = DIMM_SIZE;
1514 offset += spa->header.length;
1468 1515
1469 offset = sizeof(*spa) * 10;
1470 /* mem-region0 (spa0, dimm0) */ 1516 /* mem-region0 (spa0, dimm0) */
1471 memdev = nfit_buf + offset; 1517 memdev = nfit_buf + offset;
1472 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; 1518 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
@@ -1481,9 +1527,10 @@ static void nfit_test0_setup(struct nfit_test *t)
1481 memdev->address = 0; 1527 memdev->address = 0;
1482 memdev->interleave_index = 0; 1528 memdev->interleave_index = 0;
1483 memdev->interleave_ways = 2; 1529 memdev->interleave_ways = 2;
1530 offset += memdev->header.length;
1484 1531
1485 /* mem-region1 (spa0, dimm1) */ 1532 /* mem-region1 (spa0, dimm1) */
1486 memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map); 1533 memdev = nfit_buf + offset;
1487 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; 1534 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1488 memdev->header.length = sizeof(*memdev); 1535 memdev->header.length = sizeof(*memdev);
1489 memdev->device_handle = handle[1]; 1536 memdev->device_handle = handle[1];
@@ -1497,9 +1544,10 @@ static void nfit_test0_setup(struct nfit_test *t)
1497 memdev->interleave_index = 0; 1544 memdev->interleave_index = 0;
1498 memdev->interleave_ways = 2; 1545 memdev->interleave_ways = 2;
1499 memdev->flags = ACPI_NFIT_MEM_HEALTH_ENABLED; 1546 memdev->flags = ACPI_NFIT_MEM_HEALTH_ENABLED;
1547 offset += memdev->header.length;
1500 1548
1501 /* mem-region2 (spa1, dimm0) */ 1549 /* mem-region2 (spa1, dimm0) */
1502 memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 2; 1550 memdev = nfit_buf + offset;
1503 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; 1551 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1504 memdev->header.length = sizeof(*memdev); 1552 memdev->header.length = sizeof(*memdev);
1505 memdev->device_handle = handle[0]; 1553 memdev->device_handle = handle[0];
@@ -1513,9 +1561,10 @@ static void nfit_test0_setup(struct nfit_test *t)
1513 memdev->interleave_index = 0; 1561 memdev->interleave_index = 0;
1514 memdev->interleave_ways = 4; 1562 memdev->interleave_ways = 4;
1515 memdev->flags = ACPI_NFIT_MEM_HEALTH_ENABLED; 1563 memdev->flags = ACPI_NFIT_MEM_HEALTH_ENABLED;
1564 offset += memdev->header.length;
1516 1565
1517 /* mem-region3 (spa1, dimm1) */ 1566 /* mem-region3 (spa1, dimm1) */
1518 memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 3; 1567 memdev = nfit_buf + offset;
1519 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; 1568 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1520 memdev->header.length = sizeof(*memdev); 1569 memdev->header.length = sizeof(*memdev);
1521 memdev->device_handle = handle[1]; 1570 memdev->device_handle = handle[1];
@@ -1528,9 +1577,10 @@ static void nfit_test0_setup(struct nfit_test *t)
1528 memdev->address = SPA0_SIZE/2; 1577 memdev->address = SPA0_SIZE/2;
1529 memdev->interleave_index = 0; 1578 memdev->interleave_index = 0;
1530 memdev->interleave_ways = 4; 1579 memdev->interleave_ways = 4;
1580 offset += memdev->header.length;
1531 1581
1532 /* mem-region4 (spa1, dimm2) */ 1582 /* mem-region4 (spa1, dimm2) */
1533 memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 4; 1583 memdev = nfit_buf + offset;
1534 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; 1584 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1535 memdev->header.length = sizeof(*memdev); 1585 memdev->header.length = sizeof(*memdev);
1536 memdev->device_handle = handle[2]; 1586 memdev->device_handle = handle[2];
@@ -1544,9 +1594,10 @@ static void nfit_test0_setup(struct nfit_test *t)
1544 memdev->interleave_index = 0; 1594 memdev->interleave_index = 0;
1545 memdev->interleave_ways = 4; 1595 memdev->interleave_ways = 4;
1546 memdev->flags = ACPI_NFIT_MEM_HEALTH_ENABLED; 1596 memdev->flags = ACPI_NFIT_MEM_HEALTH_ENABLED;
1597 offset += memdev->header.length;
1547 1598
1548 /* mem-region5 (spa1, dimm3) */ 1599 /* mem-region5 (spa1, dimm3) */
1549 memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 5; 1600 memdev = nfit_buf + offset;
1550 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; 1601 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1551 memdev->header.length = sizeof(*memdev); 1602 memdev->header.length = sizeof(*memdev);
1552 memdev->device_handle = handle[3]; 1603 memdev->device_handle = handle[3];
@@ -1559,9 +1610,10 @@ static void nfit_test0_setup(struct nfit_test *t)
1559 memdev->address = SPA0_SIZE/2; 1610 memdev->address = SPA0_SIZE/2;
1560 memdev->interleave_index = 0; 1611 memdev->interleave_index = 0;
1561 memdev->interleave_ways = 4; 1612 memdev->interleave_ways = 4;
1613 offset += memdev->header.length;
1562 1614
1563 /* mem-region6 (spa/dcr0, dimm0) */ 1615 /* mem-region6 (spa/dcr0, dimm0) */
1564 memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 6; 1616 memdev = nfit_buf + offset;
1565 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; 1617 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1566 memdev->header.length = sizeof(*memdev); 1618 memdev->header.length = sizeof(*memdev);
1567 memdev->device_handle = handle[0]; 1619 memdev->device_handle = handle[0];
@@ -1574,9 +1626,10 @@ static void nfit_test0_setup(struct nfit_test *t)
1574 memdev->address = 0; 1626 memdev->address = 0;
1575 memdev->interleave_index = 0; 1627 memdev->interleave_index = 0;
1576 memdev->interleave_ways = 1; 1628 memdev->interleave_ways = 1;
1629 offset += memdev->header.length;
1577 1630
1578 /* mem-region7 (spa/dcr1, dimm1) */ 1631 /* mem-region7 (spa/dcr1, dimm1) */
1579 memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 7; 1632 memdev = nfit_buf + offset;
1580 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; 1633 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1581 memdev->header.length = sizeof(*memdev); 1634 memdev->header.length = sizeof(*memdev);
1582 memdev->device_handle = handle[1]; 1635 memdev->device_handle = handle[1];
@@ -1589,9 +1642,10 @@ static void nfit_test0_setup(struct nfit_test *t)
1589 memdev->address = 0; 1642 memdev->address = 0;
1590 memdev->interleave_index = 0; 1643 memdev->interleave_index = 0;
1591 memdev->interleave_ways = 1; 1644 memdev->interleave_ways = 1;
1645 offset += memdev->header.length;
1592 1646
1593 /* mem-region8 (spa/dcr2, dimm2) */ 1647 /* mem-region8 (spa/dcr2, dimm2) */
1594 memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 8; 1648 memdev = nfit_buf + offset;
1595 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; 1649 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1596 memdev->header.length = sizeof(*memdev); 1650 memdev->header.length = sizeof(*memdev);
1597 memdev->device_handle = handle[2]; 1651 memdev->device_handle = handle[2];
@@ -1604,9 +1658,10 @@ static void nfit_test0_setup(struct nfit_test *t)
1604 memdev->address = 0; 1658 memdev->address = 0;
1605 memdev->interleave_index = 0; 1659 memdev->interleave_index = 0;
1606 memdev->interleave_ways = 1; 1660 memdev->interleave_ways = 1;
1661 offset += memdev->header.length;
1607 1662
1608 /* mem-region9 (spa/dcr3, dimm3) */ 1663 /* mem-region9 (spa/dcr3, dimm3) */
1609 memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 9; 1664 memdev = nfit_buf + offset;
1610 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; 1665 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1611 memdev->header.length = sizeof(*memdev); 1666 memdev->header.length = sizeof(*memdev);
1612 memdev->device_handle = handle[3]; 1667 memdev->device_handle = handle[3];
@@ -1619,9 +1674,10 @@ static void nfit_test0_setup(struct nfit_test *t)
1619 memdev->address = 0; 1674 memdev->address = 0;
1620 memdev->interleave_index = 0; 1675 memdev->interleave_index = 0;
1621 memdev->interleave_ways = 1; 1676 memdev->interleave_ways = 1;
1677 offset += memdev->header.length;
1622 1678
1623 /* mem-region10 (spa/bdw0, dimm0) */ 1679 /* mem-region10 (spa/bdw0, dimm0) */
1624 memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 10; 1680 memdev = nfit_buf + offset;
1625 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; 1681 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1626 memdev->header.length = sizeof(*memdev); 1682 memdev->header.length = sizeof(*memdev);
1627 memdev->device_handle = handle[0]; 1683 memdev->device_handle = handle[0];
@@ -1634,9 +1690,10 @@ static void nfit_test0_setup(struct nfit_test *t)
1634 memdev->address = 0; 1690 memdev->address = 0;
1635 memdev->interleave_index = 0; 1691 memdev->interleave_index = 0;
1636 memdev->interleave_ways = 1; 1692 memdev->interleave_ways = 1;
1693 offset += memdev->header.length;
1637 1694
1638 /* mem-region11 (spa/bdw1, dimm1) */ 1695 /* mem-region11 (spa/bdw1, dimm1) */
1639 memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 11; 1696 memdev = nfit_buf + offset;
1640 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; 1697 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1641 memdev->header.length = sizeof(*memdev); 1698 memdev->header.length = sizeof(*memdev);
1642 memdev->device_handle = handle[1]; 1699 memdev->device_handle = handle[1];
@@ -1649,9 +1706,10 @@ static void nfit_test0_setup(struct nfit_test *t)
1649 memdev->address = 0; 1706 memdev->address = 0;
1650 memdev->interleave_index = 0; 1707 memdev->interleave_index = 0;
1651 memdev->interleave_ways = 1; 1708 memdev->interleave_ways = 1;
1709 offset += memdev->header.length;
1652 1710
1653 /* mem-region12 (spa/bdw2, dimm2) */ 1711 /* mem-region12 (spa/bdw2, dimm2) */
1654 memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 12; 1712 memdev = nfit_buf + offset;
1655 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; 1713 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1656 memdev->header.length = sizeof(*memdev); 1714 memdev->header.length = sizeof(*memdev);
1657 memdev->device_handle = handle[2]; 1715 memdev->device_handle = handle[2];
@@ -1664,9 +1722,10 @@ static void nfit_test0_setup(struct nfit_test *t)
1664 memdev->address = 0; 1722 memdev->address = 0;
1665 memdev->interleave_index = 0; 1723 memdev->interleave_index = 0;
1666 memdev->interleave_ways = 1; 1724 memdev->interleave_ways = 1;
1725 offset += memdev->header.length;
1667 1726
1668 /* mem-region13 (spa/dcr3, dimm3) */ 1727 /* mem-region13 (spa/dcr3, dimm3) */
1669 memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 13; 1728 memdev = nfit_buf + offset;
1670 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; 1729 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1671 memdev->header.length = sizeof(*memdev); 1730 memdev->header.length = sizeof(*memdev);
1672 memdev->device_handle = handle[3]; 1731 memdev->device_handle = handle[3];
@@ -1680,12 +1739,12 @@ static void nfit_test0_setup(struct nfit_test *t)
1680 memdev->interleave_index = 0; 1739 memdev->interleave_index = 0;
1681 memdev->interleave_ways = 1; 1740 memdev->interleave_ways = 1;
1682 memdev->flags = ACPI_NFIT_MEM_HEALTH_ENABLED; 1741 memdev->flags = ACPI_NFIT_MEM_HEALTH_ENABLED;
1742 offset += memdev->header.length;
1683 1743
1684 offset = offset + sizeof(struct acpi_nfit_memory_map) * 14;
1685 /* dcr-descriptor0: blk */ 1744 /* dcr-descriptor0: blk */
1686 dcr = nfit_buf + offset; 1745 dcr = nfit_buf + offset;
1687 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; 1746 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1688 dcr->header.length = sizeof(struct acpi_nfit_control_region); 1747 dcr->header.length = sizeof(*dcr);
1689 dcr->region_index = 0+1; 1748 dcr->region_index = 0+1;
1690 dcr_common_init(dcr); 1749 dcr_common_init(dcr);
1691 dcr->serial_number = ~handle[0]; 1750 dcr->serial_number = ~handle[0];
@@ -1696,11 +1755,12 @@ static void nfit_test0_setup(struct nfit_test *t)
1696 dcr->command_size = 8; 1755 dcr->command_size = 8;
1697 dcr->status_offset = 8; 1756 dcr->status_offset = 8;
1698 dcr->status_size = 4; 1757 dcr->status_size = 4;
1758 offset += dcr->header.length;
1699 1759
1700 /* dcr-descriptor1: blk */ 1760 /* dcr-descriptor1: blk */
1701 dcr = nfit_buf + offset + sizeof(struct acpi_nfit_control_region); 1761 dcr = nfit_buf + offset;
1702 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; 1762 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1703 dcr->header.length = sizeof(struct acpi_nfit_control_region); 1763 dcr->header.length = sizeof(*dcr);
1704 dcr->region_index = 1+1; 1764 dcr->region_index = 1+1;
1705 dcr_common_init(dcr); 1765 dcr_common_init(dcr);
1706 dcr->serial_number = ~handle[1]; 1766 dcr->serial_number = ~handle[1];
@@ -1711,11 +1771,12 @@ static void nfit_test0_setup(struct nfit_test *t)
1711 dcr->command_size = 8; 1771 dcr->command_size = 8;
1712 dcr->status_offset = 8; 1772 dcr->status_offset = 8;
1713 dcr->status_size = 4; 1773 dcr->status_size = 4;
1774 offset += dcr->header.length;
1714 1775
1715 /* dcr-descriptor2: blk */ 1776 /* dcr-descriptor2: blk */
1716 dcr = nfit_buf + offset + sizeof(struct acpi_nfit_control_region) * 2; 1777 dcr = nfit_buf + offset;
1717 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; 1778 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1718 dcr->header.length = sizeof(struct acpi_nfit_control_region); 1779 dcr->header.length = sizeof(*dcr);
1719 dcr->region_index = 2+1; 1780 dcr->region_index = 2+1;
1720 dcr_common_init(dcr); 1781 dcr_common_init(dcr);
1721 dcr->serial_number = ~handle[2]; 1782 dcr->serial_number = ~handle[2];
@@ -1726,11 +1787,12 @@ static void nfit_test0_setup(struct nfit_test *t)
1726 dcr->command_size = 8; 1787 dcr->command_size = 8;
1727 dcr->status_offset = 8; 1788 dcr->status_offset = 8;
1728 dcr->status_size = 4; 1789 dcr->status_size = 4;
1790 offset += dcr->header.length;
1729 1791
1730 /* dcr-descriptor3: blk */ 1792 /* dcr-descriptor3: blk */
1731 dcr = nfit_buf + offset + sizeof(struct acpi_nfit_control_region) * 3; 1793 dcr = nfit_buf + offset;
1732 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; 1794 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1733 dcr->header.length = sizeof(struct acpi_nfit_control_region); 1795 dcr->header.length = sizeof(*dcr);
1734 dcr->region_index = 3+1; 1796 dcr->region_index = 3+1;
1735 dcr_common_init(dcr); 1797 dcr_common_init(dcr);
1736 dcr->serial_number = ~handle[3]; 1798 dcr->serial_number = ~handle[3];
@@ -1741,8 +1803,8 @@ static void nfit_test0_setup(struct nfit_test *t)
1741 dcr->command_size = 8; 1803 dcr->command_size = 8;
1742 dcr->status_offset = 8; 1804 dcr->status_offset = 8;
1743 dcr->status_size = 4; 1805 dcr->status_size = 4;
1806 offset += dcr->header.length;
1744 1807
1745 offset = offset + sizeof(struct acpi_nfit_control_region) * 4;
1746 /* dcr-descriptor0: pmem */ 1808 /* dcr-descriptor0: pmem */
1747 dcr = nfit_buf + offset; 1809 dcr = nfit_buf + offset;
1748 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; 1810 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
@@ -1753,10 +1815,10 @@ static void nfit_test0_setup(struct nfit_test *t)
1753 dcr->serial_number = ~handle[0]; 1815 dcr->serial_number = ~handle[0];
1754 dcr->code = NFIT_FIC_BYTEN; 1816 dcr->code = NFIT_FIC_BYTEN;
1755 dcr->windows = 0; 1817 dcr->windows = 0;
1818 offset += dcr->header.length;
1756 1819
1757 /* dcr-descriptor1: pmem */ 1820 /* dcr-descriptor1: pmem */
1758 dcr = nfit_buf + offset + offsetof(struct acpi_nfit_control_region, 1821 dcr = nfit_buf + offset;
1759 window_size);
1760 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; 1822 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1761 dcr->header.length = offsetof(struct acpi_nfit_control_region, 1823 dcr->header.length = offsetof(struct acpi_nfit_control_region,
1762 window_size); 1824 window_size);
@@ -1765,10 +1827,10 @@ static void nfit_test0_setup(struct nfit_test *t)
1765 dcr->serial_number = ~handle[1]; 1827 dcr->serial_number = ~handle[1];
1766 dcr->code = NFIT_FIC_BYTEN; 1828 dcr->code = NFIT_FIC_BYTEN;
1767 dcr->windows = 0; 1829 dcr->windows = 0;
1830 offset += dcr->header.length;
1768 1831
1769 /* dcr-descriptor2: pmem */ 1832 /* dcr-descriptor2: pmem */
1770 dcr = nfit_buf + offset + offsetof(struct acpi_nfit_control_region, 1833 dcr = nfit_buf + offset;
1771 window_size) * 2;
1772 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; 1834 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1773 dcr->header.length = offsetof(struct acpi_nfit_control_region, 1835 dcr->header.length = offsetof(struct acpi_nfit_control_region,
1774 window_size); 1836 window_size);
@@ -1777,10 +1839,10 @@ static void nfit_test0_setup(struct nfit_test *t)
1777 dcr->serial_number = ~handle[2]; 1839 dcr->serial_number = ~handle[2];
1778 dcr->code = NFIT_FIC_BYTEN; 1840 dcr->code = NFIT_FIC_BYTEN;
1779 dcr->windows = 0; 1841 dcr->windows = 0;
1842 offset += dcr->header.length;
1780 1843
1781 /* dcr-descriptor3: pmem */ 1844 /* dcr-descriptor3: pmem */
1782 dcr = nfit_buf + offset + offsetof(struct acpi_nfit_control_region, 1845 dcr = nfit_buf + offset;
1783 window_size) * 3;
1784 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; 1846 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1785 dcr->header.length = offsetof(struct acpi_nfit_control_region, 1847 dcr->header.length = offsetof(struct acpi_nfit_control_region,
1786 window_size); 1848 window_size);
@@ -1789,54 +1851,56 @@ static void nfit_test0_setup(struct nfit_test *t)
1789 dcr->serial_number = ~handle[3]; 1851 dcr->serial_number = ~handle[3];
1790 dcr->code = NFIT_FIC_BYTEN; 1852 dcr->code = NFIT_FIC_BYTEN;
1791 dcr->windows = 0; 1853 dcr->windows = 0;
1854 offset += dcr->header.length;
1792 1855
1793 offset = offset + offsetof(struct acpi_nfit_control_region,
1794 window_size) * 4;
1795 /* bdw0 (spa/dcr0, dimm0) */ 1856 /* bdw0 (spa/dcr0, dimm0) */
1796 bdw = nfit_buf + offset; 1857 bdw = nfit_buf + offset;
1797 bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION; 1858 bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION;
1798 bdw->header.length = sizeof(struct acpi_nfit_data_region); 1859 bdw->header.length = sizeof(*bdw);
1799 bdw->region_index = 0+1; 1860 bdw->region_index = 0+1;
1800 bdw->windows = 1; 1861 bdw->windows = 1;
1801 bdw->offset = 0; 1862 bdw->offset = 0;
1802 bdw->size = BDW_SIZE; 1863 bdw->size = BDW_SIZE;
1803 bdw->capacity = DIMM_SIZE; 1864 bdw->capacity = DIMM_SIZE;
1804 bdw->start_address = 0; 1865 bdw->start_address = 0;
1866 offset += bdw->header.length;
1805 1867
1806 /* bdw1 (spa/dcr1, dimm1) */ 1868 /* bdw1 (spa/dcr1, dimm1) */
1807 bdw = nfit_buf + offset + sizeof(struct acpi_nfit_data_region); 1869 bdw = nfit_buf + offset;
1808 bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION; 1870 bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION;
1809 bdw->header.length = sizeof(struct acpi_nfit_data_region); 1871 bdw->header.length = sizeof(*bdw);
1810 bdw->region_index = 1+1; 1872 bdw->region_index = 1+1;
1811 bdw->windows = 1; 1873 bdw->windows = 1;
1812 bdw->offset = 0; 1874 bdw->offset = 0;
1813 bdw->size = BDW_SIZE; 1875 bdw->size = BDW_SIZE;
1814 bdw->capacity = DIMM_SIZE; 1876 bdw->capacity = DIMM_SIZE;
1815 bdw->start_address = 0; 1877 bdw->start_address = 0;
1878 offset += bdw->header.length;
1816 1879
1817 /* bdw2 (spa/dcr2, dimm2) */ 1880 /* bdw2 (spa/dcr2, dimm2) */
1818 bdw = nfit_buf + offset + sizeof(struct acpi_nfit_data_region) * 2; 1881 bdw = nfit_buf + offset;
1819 bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION; 1882 bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION;
1820 bdw->header.length = sizeof(struct acpi_nfit_data_region); 1883 bdw->header.length = sizeof(*bdw);
1821 bdw->region_index = 2+1; 1884 bdw->region_index = 2+1;
1822 bdw->windows = 1; 1885 bdw->windows = 1;
1823 bdw->offset = 0; 1886 bdw->offset = 0;
1824 bdw->size = BDW_SIZE; 1887 bdw->size = BDW_SIZE;
1825 bdw->capacity = DIMM_SIZE; 1888 bdw->capacity = DIMM_SIZE;
1826 bdw->start_address = 0; 1889 bdw->start_address = 0;
1890 offset += bdw->header.length;
1827 1891
1828 /* bdw3 (spa/dcr3, dimm3) */ 1892 /* bdw3 (spa/dcr3, dimm3) */
1829 bdw = nfit_buf + offset + sizeof(struct acpi_nfit_data_region) * 3; 1893 bdw = nfit_buf + offset;
1830 bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION; 1894 bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION;
1831 bdw->header.length = sizeof(struct acpi_nfit_data_region); 1895 bdw->header.length = sizeof(*bdw);
1832 bdw->region_index = 3+1; 1896 bdw->region_index = 3+1;
1833 bdw->windows = 1; 1897 bdw->windows = 1;
1834 bdw->offset = 0; 1898 bdw->offset = 0;
1835 bdw->size = BDW_SIZE; 1899 bdw->size = BDW_SIZE;
1836 bdw->capacity = DIMM_SIZE; 1900 bdw->capacity = DIMM_SIZE;
1837 bdw->start_address = 0; 1901 bdw->start_address = 0;
1902 offset += bdw->header.length;
1838 1903
1839 offset = offset + sizeof(struct acpi_nfit_data_region) * 4;
1840 /* flush0 (dimm0) */ 1904 /* flush0 (dimm0) */
1841 flush = nfit_buf + offset; 1905 flush = nfit_buf + offset;
1842 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS; 1906 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
@@ -1845,48 +1909,52 @@ static void nfit_test0_setup(struct nfit_test *t)
1845 flush->hint_count = NUM_HINTS; 1909 flush->hint_count = NUM_HINTS;
1846 for (i = 0; i < NUM_HINTS; i++) 1910 for (i = 0; i < NUM_HINTS; i++)
1847 flush->hint_address[i] = t->flush_dma[0] + i * sizeof(u64); 1911 flush->hint_address[i] = t->flush_dma[0] + i * sizeof(u64);
1912 offset += flush->header.length;
1848 1913
1849 /* flush1 (dimm1) */ 1914 /* flush1 (dimm1) */
1850 flush = nfit_buf + offset + flush_hint_size * 1; 1915 flush = nfit_buf + offset;
1851 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS; 1916 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1852 flush->header.length = flush_hint_size; 1917 flush->header.length = flush_hint_size;
1853 flush->device_handle = handle[1]; 1918 flush->device_handle = handle[1];
1854 flush->hint_count = NUM_HINTS; 1919 flush->hint_count = NUM_HINTS;
1855 for (i = 0; i < NUM_HINTS; i++) 1920 for (i = 0; i < NUM_HINTS; i++)
1856 flush->hint_address[i] = t->flush_dma[1] + i * sizeof(u64); 1921 flush->hint_address[i] = t->flush_dma[1] + i * sizeof(u64);
1922 offset += flush->header.length;
1857 1923
1858 /* flush2 (dimm2) */ 1924 /* flush2 (dimm2) */
1859 flush = nfit_buf + offset + flush_hint_size * 2; 1925 flush = nfit_buf + offset;
1860 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS; 1926 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1861 flush->header.length = flush_hint_size; 1927 flush->header.length = flush_hint_size;
1862 flush->device_handle = handle[2]; 1928 flush->device_handle = handle[2];
1863 flush->hint_count = NUM_HINTS; 1929 flush->hint_count = NUM_HINTS;
1864 for (i = 0; i < NUM_HINTS; i++) 1930 for (i = 0; i < NUM_HINTS; i++)
1865 flush->hint_address[i] = t->flush_dma[2] + i * sizeof(u64); 1931 flush->hint_address[i] = t->flush_dma[2] + i * sizeof(u64);
1932 offset += flush->header.length;
1866 1933
1867 /* flush3 (dimm3) */ 1934 /* flush3 (dimm3) */
1868 flush = nfit_buf + offset + flush_hint_size * 3; 1935 flush = nfit_buf + offset;
1869 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS; 1936 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1870 flush->header.length = flush_hint_size; 1937 flush->header.length = flush_hint_size;
1871 flush->device_handle = handle[3]; 1938 flush->device_handle = handle[3];
1872 flush->hint_count = NUM_HINTS; 1939 flush->hint_count = NUM_HINTS;
1873 for (i = 0; i < NUM_HINTS; i++) 1940 for (i = 0; i < NUM_HINTS; i++)
1874 flush->hint_address[i] = t->flush_dma[3] + i * sizeof(u64); 1941 flush->hint_address[i] = t->flush_dma[3] + i * sizeof(u64);
1942 offset += flush->header.length;
1875 1943
1876 /* platform capabilities */ 1944 /* platform capabilities */
1877 pcap = nfit_buf + offset + flush_hint_size * 4; 1945 pcap = nfit_buf + offset;
1878 pcap->header.type = ACPI_NFIT_TYPE_CAPABILITIES; 1946 pcap->header.type = ACPI_NFIT_TYPE_CAPABILITIES;
1879 pcap->header.length = sizeof(*pcap); 1947 pcap->header.length = sizeof(*pcap);
1880 pcap->highest_capability = 1; 1948 pcap->highest_capability = 1;
1881 pcap->capabilities = ACPI_NFIT_CAPABILITY_CACHE_FLUSH | 1949 pcap->capabilities = ACPI_NFIT_CAPABILITY_CACHE_FLUSH |
1882 ACPI_NFIT_CAPABILITY_MEM_FLUSH; 1950 ACPI_NFIT_CAPABILITY_MEM_FLUSH;
1951 offset += pcap->header.length;
1883 1952
1884 if (t->setup_hotplug) { 1953 if (t->setup_hotplug) {
1885 offset = offset + flush_hint_size * 4 + sizeof(*pcap);
1886 /* dcr-descriptor4: blk */ 1954 /* dcr-descriptor4: blk */
1887 dcr = nfit_buf + offset; 1955 dcr = nfit_buf + offset;
1888 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; 1956 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1889 dcr->header.length = sizeof(struct acpi_nfit_control_region); 1957 dcr->header.length = sizeof(*dcr);
1890 dcr->region_index = 8+1; 1958 dcr->region_index = 8+1;
1891 dcr_common_init(dcr); 1959 dcr_common_init(dcr);
1892 dcr->serial_number = ~handle[4]; 1960 dcr->serial_number = ~handle[4];
@@ -1897,8 +1965,8 @@ static void nfit_test0_setup(struct nfit_test *t)
1897 dcr->command_size = 8; 1965 dcr->command_size = 8;
1898 dcr->status_offset = 8; 1966 dcr->status_offset = 8;
1899 dcr->status_size = 4; 1967 dcr->status_size = 4;
1968 offset += dcr->header.length;
1900 1969
1901 offset = offset + sizeof(struct acpi_nfit_control_region);
1902 /* dcr-descriptor4: pmem */ 1970 /* dcr-descriptor4: pmem */
1903 dcr = nfit_buf + offset; 1971 dcr = nfit_buf + offset;
1904 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; 1972 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
@@ -1909,21 +1977,20 @@ static void nfit_test0_setup(struct nfit_test *t)
1909 dcr->serial_number = ~handle[4]; 1977 dcr->serial_number = ~handle[4];
1910 dcr->code = NFIT_FIC_BYTEN; 1978 dcr->code = NFIT_FIC_BYTEN;
1911 dcr->windows = 0; 1979 dcr->windows = 0;
1980 offset += dcr->header.length;
1912 1981
1913 offset = offset + offsetof(struct acpi_nfit_control_region,
1914 window_size);
1915 /* bdw4 (spa/dcr4, dimm4) */ 1982 /* bdw4 (spa/dcr4, dimm4) */
1916 bdw = nfit_buf + offset; 1983 bdw = nfit_buf + offset;
1917 bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION; 1984 bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION;
1918 bdw->header.length = sizeof(struct acpi_nfit_data_region); 1985 bdw->header.length = sizeof(*bdw);
1919 bdw->region_index = 8+1; 1986 bdw->region_index = 8+1;
1920 bdw->windows = 1; 1987 bdw->windows = 1;
1921 bdw->offset = 0; 1988 bdw->offset = 0;
1922 bdw->size = BDW_SIZE; 1989 bdw->size = BDW_SIZE;
1923 bdw->capacity = DIMM_SIZE; 1990 bdw->capacity = DIMM_SIZE;
1924 bdw->start_address = 0; 1991 bdw->start_address = 0;
1992 offset += bdw->header.length;
1925 1993
1926 offset = offset + sizeof(struct acpi_nfit_data_region);
1927 /* spa10 (dcr4) dimm4 */ 1994 /* spa10 (dcr4) dimm4 */
1928 spa = nfit_buf + offset; 1995 spa = nfit_buf + offset;
1929 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS; 1996 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
@@ -1932,30 +1999,32 @@ static void nfit_test0_setup(struct nfit_test *t)
1932 spa->range_index = 10+1; 1999 spa->range_index = 10+1;
1933 spa->address = t->dcr_dma[4]; 2000 spa->address = t->dcr_dma[4];
1934 spa->length = DCR_SIZE; 2001 spa->length = DCR_SIZE;
2002 offset += spa->header.length;
1935 2003
1936 /* 2004 /*
1937 * spa11 (single-dimm interleave for hotplug, note storage 2005 * spa11 (single-dimm interleave for hotplug, note storage
1938 * does not actually alias the related block-data-window 2006 * does not actually alias the related block-data-window
1939 * regions) 2007 * regions)
1940 */ 2008 */
1941 spa = nfit_buf + offset + sizeof(*spa); 2009 spa = nfit_buf + offset;
1942 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS; 2010 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
1943 spa->header.length = sizeof(*spa); 2011 spa->header.length = sizeof(*spa);
1944 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_PM), 16); 2012 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_PM), 16);
1945 spa->range_index = 11+1; 2013 spa->range_index = 11+1;
1946 spa->address = t->spa_set_dma[2]; 2014 spa->address = t->spa_set_dma[2];
1947 spa->length = SPA0_SIZE; 2015 spa->length = SPA0_SIZE;
2016 offset += spa->header.length;
1948 2017
1949 /* spa12 (bdw for dcr4) dimm4 */ 2018 /* spa12 (bdw for dcr4) dimm4 */
1950 spa = nfit_buf + offset + sizeof(*spa) * 2; 2019 spa = nfit_buf + offset;
1951 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS; 2020 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
1952 spa->header.length = sizeof(*spa); 2021 spa->header.length = sizeof(*spa);
1953 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16); 2022 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
1954 spa->range_index = 12+1; 2023 spa->range_index = 12+1;
1955 spa->address = t->dimm_dma[4]; 2024 spa->address = t->dimm_dma[4];
1956 spa->length = DIMM_SIZE; 2025 spa->length = DIMM_SIZE;
2026 offset += spa->header.length;
1957 2027
1958 offset = offset + sizeof(*spa) * 3;
1959 /* mem-region14 (spa/dcr4, dimm4) */ 2028 /* mem-region14 (spa/dcr4, dimm4) */
1960 memdev = nfit_buf + offset; 2029 memdev = nfit_buf + offset;
1961 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; 2030 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
@@ -1970,10 +2039,10 @@ static void nfit_test0_setup(struct nfit_test *t)
1970 memdev->address = 0; 2039 memdev->address = 0;
1971 memdev->interleave_index = 0; 2040 memdev->interleave_index = 0;
1972 memdev->interleave_ways = 1; 2041 memdev->interleave_ways = 1;
2042 offset += memdev->header.length;
1973 2043
1974 /* mem-region15 (spa0, dimm4) */ 2044 /* mem-region15 (spa11, dimm4) */
1975 memdev = nfit_buf + offset + 2045 memdev = nfit_buf + offset;
1976 sizeof(struct acpi_nfit_memory_map);
1977 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; 2046 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1978 memdev->header.length = sizeof(*memdev); 2047 memdev->header.length = sizeof(*memdev);
1979 memdev->device_handle = handle[4]; 2048 memdev->device_handle = handle[4];
@@ -1987,10 +2056,10 @@ static void nfit_test0_setup(struct nfit_test *t)
1987 memdev->interleave_index = 0; 2056 memdev->interleave_index = 0;
1988 memdev->interleave_ways = 1; 2057 memdev->interleave_ways = 1;
1989 memdev->flags = ACPI_NFIT_MEM_HEALTH_ENABLED; 2058 memdev->flags = ACPI_NFIT_MEM_HEALTH_ENABLED;
2059 offset += memdev->header.length;
1990 2060
1991 /* mem-region16 (spa/bdw4, dimm4) */ 2061 /* mem-region16 (spa/bdw4, dimm4) */
1992 memdev = nfit_buf + offset + 2062 memdev = nfit_buf + offset;
1993 sizeof(struct acpi_nfit_memory_map) * 2;
1994 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; 2063 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1995 memdev->header.length = sizeof(*memdev); 2064 memdev->header.length = sizeof(*memdev);
1996 memdev->device_handle = handle[4]; 2065 memdev->device_handle = handle[4];
@@ -2003,8 +2072,8 @@ static void nfit_test0_setup(struct nfit_test *t)
2003 memdev->address = 0; 2072 memdev->address = 0;
2004 memdev->interleave_index = 0; 2073 memdev->interleave_index = 0;
2005 memdev->interleave_ways = 1; 2074 memdev->interleave_ways = 1;
2075 offset += memdev->header.length;
2006 2076
2007 offset = offset + sizeof(struct acpi_nfit_memory_map) * 3;
2008 /* flush3 (dimm4) */ 2077 /* flush3 (dimm4) */
2009 flush = nfit_buf + offset; 2078 flush = nfit_buf + offset;
2010 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS; 2079 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
@@ -2014,8 +2083,14 @@ static void nfit_test0_setup(struct nfit_test *t)
2014 for (i = 0; i < NUM_HINTS; i++) 2083 for (i = 0; i < NUM_HINTS; i++)
2015 flush->hint_address[i] = t->flush_dma[4] 2084 flush->hint_address[i] = t->flush_dma[4]
2016 + i * sizeof(u64); 2085 + i * sizeof(u64);
2086 offset += flush->header.length;
2087
2088 /* sanity check to make sure we've filled the buffer */
2089 WARN_ON(offset != t->nfit_size);
2017 } 2090 }
2018 2091
2092 t->nfit_filled = offset;
2093
2019 post_ars_status(&t->ars_state, &t->badrange, t->spa_set_dma[0], 2094 post_ars_status(&t->ars_state, &t->badrange, t->spa_set_dma[0],
2020 SPA0_SIZE); 2095 SPA0_SIZE);
2021 2096
@@ -2026,6 +2101,7 @@ static void nfit_test0_setup(struct nfit_test *t)
2026 set_bit(ND_INTEL_SMART, &acpi_desc->dimm_cmd_force_en); 2101 set_bit(ND_INTEL_SMART, &acpi_desc->dimm_cmd_force_en);
2027 set_bit(ND_INTEL_SMART_THRESHOLD, &acpi_desc->dimm_cmd_force_en); 2102 set_bit(ND_INTEL_SMART_THRESHOLD, &acpi_desc->dimm_cmd_force_en);
2028 set_bit(ND_INTEL_SMART_SET_THRESHOLD, &acpi_desc->dimm_cmd_force_en); 2103 set_bit(ND_INTEL_SMART_SET_THRESHOLD, &acpi_desc->dimm_cmd_force_en);
2104 set_bit(ND_INTEL_SMART_INJECT, &acpi_desc->dimm_cmd_force_en);
2029 set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_cmd_force_en); 2105 set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_cmd_force_en);
2030 set_bit(ND_CMD_ARS_START, &acpi_desc->bus_cmd_force_en); 2106 set_bit(ND_CMD_ARS_START, &acpi_desc->bus_cmd_force_en);
2031 set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_cmd_force_en); 2107 set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_cmd_force_en);
@@ -2061,17 +2137,18 @@ static void nfit_test1_setup(struct nfit_test *t)
2061 spa->range_index = 0+1; 2137 spa->range_index = 0+1;
2062 spa->address = t->spa_set_dma[0]; 2138 spa->address = t->spa_set_dma[0];
2063 spa->length = SPA2_SIZE; 2139 spa->length = SPA2_SIZE;
2140 offset += spa->header.length;
2064 2141
2065 /* virtual cd region */ 2142 /* virtual cd region */
2066 spa = nfit_buf + sizeof(*spa); 2143 spa = nfit_buf + offset;
2067 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS; 2144 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
2068 spa->header.length = sizeof(*spa); 2145 spa->header.length = sizeof(*spa);
2069 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_VCD), 16); 2146 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_VCD), 16);
2070 spa->range_index = 0; 2147 spa->range_index = 0;
2071 spa->address = t->spa_set_dma[1]; 2148 spa->address = t->spa_set_dma[1];
2072 spa->length = SPA_VCD_SIZE; 2149 spa->length = SPA_VCD_SIZE;
2150 offset += spa->header.length;
2073 2151
2074 offset += sizeof(*spa) * 2;
2075 /* mem-region0 (spa0, dimm0) */ 2152 /* mem-region0 (spa0, dimm0) */
2076 memdev = nfit_buf + offset; 2153 memdev = nfit_buf + offset;
2077 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; 2154 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
@@ -2089,8 +2166,8 @@ static void nfit_test1_setup(struct nfit_test *t)
2089 memdev->flags = ACPI_NFIT_MEM_SAVE_FAILED | ACPI_NFIT_MEM_RESTORE_FAILED 2166 memdev->flags = ACPI_NFIT_MEM_SAVE_FAILED | ACPI_NFIT_MEM_RESTORE_FAILED
2090 | ACPI_NFIT_MEM_FLUSH_FAILED | ACPI_NFIT_MEM_HEALTH_OBSERVED 2167 | ACPI_NFIT_MEM_FLUSH_FAILED | ACPI_NFIT_MEM_HEALTH_OBSERVED
2091 | ACPI_NFIT_MEM_NOT_ARMED; 2168 | ACPI_NFIT_MEM_NOT_ARMED;
2169 offset += memdev->header.length;
2092 2170
2093 offset += sizeof(*memdev);
2094 /* dcr-descriptor0 */ 2171 /* dcr-descriptor0 */
2095 dcr = nfit_buf + offset; 2172 dcr = nfit_buf + offset;
2096 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; 2173 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
@@ -2101,8 +2178,8 @@ static void nfit_test1_setup(struct nfit_test *t)
2101 dcr->serial_number = ~handle[5]; 2178 dcr->serial_number = ~handle[5];
2102 dcr->code = NFIT_FIC_BYTE; 2179 dcr->code = NFIT_FIC_BYTE;
2103 dcr->windows = 0; 2180 dcr->windows = 0;
2104
2105 offset += dcr->header.length; 2181 offset += dcr->header.length;
2182
2106 memdev = nfit_buf + offset; 2183 memdev = nfit_buf + offset;
2107 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; 2184 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
2108 memdev->header.length = sizeof(*memdev); 2185 memdev->header.length = sizeof(*memdev);
@@ -2117,9 +2194,9 @@ static void nfit_test1_setup(struct nfit_test *t)
2117 memdev->interleave_index = 0; 2194 memdev->interleave_index = 0;
2118 memdev->interleave_ways = 1; 2195 memdev->interleave_ways = 1;
2119 memdev->flags = ACPI_NFIT_MEM_MAP_FAILED; 2196 memdev->flags = ACPI_NFIT_MEM_MAP_FAILED;
2197 offset += memdev->header.length;
2120 2198
2121 /* dcr-descriptor1 */ 2199 /* dcr-descriptor1 */
2122 offset += sizeof(*memdev);
2123 dcr = nfit_buf + offset; 2200 dcr = nfit_buf + offset;
2124 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; 2201 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
2125 dcr->header.length = offsetof(struct acpi_nfit_control_region, 2202 dcr->header.length = offsetof(struct acpi_nfit_control_region,
@@ -2129,6 +2206,12 @@ static void nfit_test1_setup(struct nfit_test *t)
2129 dcr->serial_number = ~handle[6]; 2206 dcr->serial_number = ~handle[6];
2130 dcr->code = NFIT_FIC_BYTE; 2207 dcr->code = NFIT_FIC_BYTE;
2131 dcr->windows = 0; 2208 dcr->windows = 0;
2209 offset += dcr->header.length;
2210
2211 /* sanity check to make sure we've filled the buffer */
2212 WARN_ON(offset != t->nfit_size);
2213
2214 t->nfit_filled = offset;
2132 2215
2133 post_ars_status(&t->ars_state, &t->badrange, t->spa_set_dma[0], 2216 post_ars_status(&t->ars_state, &t->badrange, t->spa_set_dma[0],
2134 SPA2_SIZE); 2217 SPA2_SIZE);
@@ -2487,7 +2570,7 @@ static int nfit_test_probe(struct platform_device *pdev)
2487 nd_desc->ndctl = nfit_test_ctl; 2570 nd_desc->ndctl = nfit_test_ctl;
2488 2571
2489 rc = acpi_nfit_init(acpi_desc, nfit_test->nfit_buf, 2572 rc = acpi_nfit_init(acpi_desc, nfit_test->nfit_buf,
2490 nfit_test->nfit_size); 2573 nfit_test->nfit_filled);
2491 if (rc) 2574 if (rc)
2492 return rc; 2575 return rc;
2493 2576
diff --git a/tools/testing/nvdimm/test/nfit_test.h b/tools/testing/nvdimm/test/nfit_test.h
index 428344519cdf..33752e06ff8d 100644
--- a/tools/testing/nvdimm/test/nfit_test.h
+++ b/tools/testing/nvdimm/test/nfit_test.h
@@ -93,6 +93,7 @@ struct nd_cmd_ars_err_inj_stat {
93#define ND_INTEL_FW_FINISH_UPDATE 15 93#define ND_INTEL_FW_FINISH_UPDATE 15
94#define ND_INTEL_FW_FINISH_QUERY 16 94#define ND_INTEL_FW_FINISH_QUERY 16
95#define ND_INTEL_SMART_SET_THRESHOLD 17 95#define ND_INTEL_SMART_SET_THRESHOLD 17
96#define ND_INTEL_SMART_INJECT 18
96 97
97#define ND_INTEL_SMART_HEALTH_VALID (1 << 0) 98#define ND_INTEL_SMART_HEALTH_VALID (1 << 0)
98#define ND_INTEL_SMART_SPARES_VALID (1 << 1) 99#define ND_INTEL_SMART_SPARES_VALID (1 << 1)
@@ -111,6 +112,10 @@ struct nd_cmd_ars_err_inj_stat {
111#define ND_INTEL_SMART_NON_CRITICAL_HEALTH (1 << 0) 112#define ND_INTEL_SMART_NON_CRITICAL_HEALTH (1 << 0)
112#define ND_INTEL_SMART_CRITICAL_HEALTH (1 << 1) 113#define ND_INTEL_SMART_CRITICAL_HEALTH (1 << 1)
113#define ND_INTEL_SMART_FATAL_HEALTH (1 << 2) 114#define ND_INTEL_SMART_FATAL_HEALTH (1 << 2)
115#define ND_INTEL_SMART_INJECT_MTEMP (1 << 0)
116#define ND_INTEL_SMART_INJECT_SPARE (1 << 1)
117#define ND_INTEL_SMART_INJECT_FATAL (1 << 2)
118#define ND_INTEL_SMART_INJECT_SHUTDOWN (1 << 3)
114 119
115struct nd_intel_smart { 120struct nd_intel_smart {
116 __u32 status; 121 __u32 status;
@@ -158,6 +163,17 @@ struct nd_intel_smart_set_threshold {
158 __u32 status; 163 __u32 status;
159} __packed; 164} __packed;
160 165
166struct nd_intel_smart_inject {
167 __u64 flags;
168 __u8 mtemp_enable;
169 __u16 media_temperature;
170 __u8 spare_enable;
171 __u8 spares;
172 __u8 fatal_enable;
173 __u8 unsafe_shutdown_enable;
174 __u32 status;
175} __packed;
176
161#define INTEL_FW_STORAGE_SIZE 0x100000 177#define INTEL_FW_STORAGE_SIZE 0x100000
162#define INTEL_FW_MAX_SEND_LEN 0xFFEC 178#define INTEL_FW_MAX_SEND_LEN 0xFFEC
163#define INTEL_FW_QUERY_INTERVAL 250000 179#define INTEL_FW_QUERY_INTERVAL 250000
diff --git a/tools/testing/radix-tree/linux/gfp.h b/tools/testing/radix-tree/linux/gfp.h
index e3201ccf54c3..32159c08a52e 100644
--- a/tools/testing/radix-tree/linux/gfp.h
+++ b/tools/testing/radix-tree/linux/gfp.h
@@ -19,6 +19,7 @@
19 19
20#define __GFP_RECLAIM (__GFP_DIRECT_RECLAIM|__GFP_KSWAPD_RECLAIM) 20#define __GFP_RECLAIM (__GFP_DIRECT_RECLAIM|__GFP_KSWAPD_RECLAIM)
21 21
22#define GFP_ZONEMASK 0x0fu
22#define GFP_ATOMIC (__GFP_HIGH|__GFP_ATOMIC|__GFP_KSWAPD_RECLAIM) 23#define GFP_ATOMIC (__GFP_HIGH|__GFP_ATOMIC|__GFP_KSWAPD_RECLAIM)
23#define GFP_KERNEL (__GFP_RECLAIM | __GFP_IO | __GFP_FS) 24#define GFP_KERNEL (__GFP_RECLAIM | __GFP_IO | __GFP_FS)
24#define GFP_NOWAIT (__GFP_KSWAPD_RECLAIM) 25#define GFP_NOWAIT (__GFP_KSWAPD_RECLAIM)
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index dbda89c9d9b9..32aafa92074c 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -15,6 +15,7 @@ TARGETS += gpio
15TARGETS += intel_pstate 15TARGETS += intel_pstate
16TARGETS += ipc 16TARGETS += ipc
17TARGETS += kcmp 17TARGETS += kcmp
18TARGETS += kvm
18TARGETS += lib 19TARGETS += lib
19TARGETS += membarrier 20TARGETS += membarrier
20TARGETS += memfd 21TARGETS += memfd
@@ -24,6 +25,7 @@ TARGETS += mqueue
24TARGETS += net 25TARGETS += net
25TARGETS += nsfs 26TARGETS += nsfs
26TARGETS += powerpc 27TARGETS += powerpc
28TARGETS += proc
27TARGETS += pstore 29TARGETS += pstore
28TARGETS += ptrace 30TARGETS += ptrace
29TARGETS += seccomp 31TARGETS += seccomp
@@ -67,6 +69,12 @@ ifndef BUILD
67 BUILD := $(shell pwd) 69 BUILD := $(shell pwd)
68endif 70endif
69 71
72# KSFT_TAP_LEVEL is used from KSFT framework to prevent nested TAP header
73# printing from tests. Applicable to run_tests case where run_tests adds
74# TAP header prior running tests and when a test program invokes another
75# with system() call. Export it here to cover override RUN_TESTS defines.
76export KSFT_TAP_LEVEL=`echo 1`
77
70export BUILD 78export BUILD
71all: 79all:
72 @for TARGET in $(TARGETS); do \ 80 @for TARGET in $(TARGETS); do \
@@ -126,11 +134,14 @@ ifdef INSTALL_PATH
126 echo "else" >> $(ALL_SCRIPT) 134 echo "else" >> $(ALL_SCRIPT)
127 echo " OUTPUT=/dev/stdout" >> $(ALL_SCRIPT) 135 echo " OUTPUT=/dev/stdout" >> $(ALL_SCRIPT)
128 echo "fi" >> $(ALL_SCRIPT) 136 echo "fi" >> $(ALL_SCRIPT)
137 echo "export KSFT_TAP_LEVEL=`echo 1`" >> $(ALL_SCRIPT)
129 138
130 for TARGET in $(TARGETS); do \ 139 for TARGET in $(TARGETS); do \
131 BUILD_TARGET=$$BUILD/$$TARGET; \ 140 BUILD_TARGET=$$BUILD/$$TARGET; \
132 echo "echo ; echo Running tests in $$TARGET" >> $(ALL_SCRIPT); \ 141 echo "echo ; echo TAP version 13" >> $(ALL_SCRIPT); \
142 echo "echo Running tests in $$TARGET" >> $(ALL_SCRIPT); \
133 echo "echo ========================================" >> $(ALL_SCRIPT); \ 143 echo "echo ========================================" >> $(ALL_SCRIPT); \
144 echo "[ -w /dev/kmsg ] && echo \"kselftest: Running tests in $$TARGET\" >> /dev/kmsg" >> $(ALL_SCRIPT); \
134 echo "cd $$TARGET" >> $(ALL_SCRIPT); \ 145 echo "cd $$TARGET" >> $(ALL_SCRIPT); \
135 make -s --no-print-directory OUTPUT=$$BUILD_TARGET -C $$TARGET emit_tests >> $(ALL_SCRIPT); \ 146 make -s --no-print-directory OUTPUT=$$BUILD_TARGET -C $$TARGET emit_tests >> $(ALL_SCRIPT); \
136 echo "cd \$$ROOT" >> $(ALL_SCRIPT); \ 147 echo "cd \$$ROOT" >> $(ALL_SCRIPT); \
diff --git a/tools/testing/selftests/android/ion/.gitignore b/tools/testing/selftests/android/ion/.gitignore
index 67e6f391b2a9..95e8f4561474 100644
--- a/tools/testing/selftests/android/ion/.gitignore
+++ b/tools/testing/selftests/android/ion/.gitignore
@@ -1,2 +1,3 @@
1ionapp_export 1ionapp_export
2ionapp_import 2ionapp_import
3ionmap_test
diff --git a/tools/testing/selftests/android/ion/Makefile b/tools/testing/selftests/android/ion/Makefile
index 96e0c448b39d..e03695287f76 100644
--- a/tools/testing/selftests/android/ion/Makefile
+++ b/tools/testing/selftests/android/ion/Makefile
@@ -1,8 +1,8 @@
1 1
2INCLUDEDIR := -I. -I../../../../../drivers/staging/android/uapi/ 2INCLUDEDIR := -I. -I../../../../../drivers/staging/android/uapi/ -I../../../../../usr/include/
3CFLAGS := $(CFLAGS) $(INCLUDEDIR) -Wall -O2 -g 3CFLAGS := $(CFLAGS) $(INCLUDEDIR) -Wall -O2 -g
4 4
5TEST_GEN_FILES := ionapp_export ionapp_import 5TEST_GEN_FILES := ionapp_export ionapp_import ionmap_test
6 6
7all: $(TEST_GEN_FILES) 7all: $(TEST_GEN_FILES)
8 8
@@ -14,3 +14,4 @@ include ../../lib.mk
14 14
15$(OUTPUT)/ionapp_export: ionapp_export.c ipcsocket.c ionutils.c 15$(OUTPUT)/ionapp_export: ionapp_export.c ipcsocket.c ionutils.c
16$(OUTPUT)/ionapp_import: ionapp_import.c ipcsocket.c ionutils.c 16$(OUTPUT)/ionapp_import: ionapp_import.c ipcsocket.c ionutils.c
17$(OUTPUT)/ionmap_test: ionmap_test.c ionutils.c
diff --git a/tools/testing/selftests/android/ion/config b/tools/testing/selftests/android/ion/config
index 19db6ca9aa2b..b4ad748a9dd9 100644
--- a/tools/testing/selftests/android/ion/config
+++ b/tools/testing/selftests/android/ion/config
@@ -2,3 +2,4 @@ CONFIG_ANDROID=y
2CONFIG_STAGING=y 2CONFIG_STAGING=y
3CONFIG_ION=y 3CONFIG_ION=y
4CONFIG_ION_SYSTEM_HEAP=y 4CONFIG_ION_SYSTEM_HEAP=y
5CONFIG_DRM_VGEM=y
diff --git a/tools/testing/selftests/android/ion/ionmap_test.c b/tools/testing/selftests/android/ion/ionmap_test.c
new file mode 100644
index 000000000000..dab36b06b37d
--- /dev/null
+++ b/tools/testing/selftests/android/ion/ionmap_test.c
@@ -0,0 +1,136 @@
1#include <errno.h>
2#include <fcntl.h>
3#include <stdio.h>
4#include <stdint.h>
5#include <string.h>
6#include <unistd.h>
7
8#include <sys/ioctl.h>
9#include <sys/types.h>
10#include <sys/stat.h>
11
12#include <linux/dma-buf.h>
13
14#include <drm/drm.h>
15
16#include "ion.h"
17#include "ionutils.h"
18
19int check_vgem(int fd)
20{
21 drm_version_t version = { 0 };
22 char name[5];
23 int ret;
24
25 version.name_len = 4;
26 version.name = name;
27
28 ret = ioctl(fd, DRM_IOCTL_VERSION, &version);
29 if (ret)
30 return 1;
31
32 return strcmp(name, "vgem");
33}
34
35int open_vgem(void)
36{
37 int i, fd;
38 const char *drmstr = "/dev/dri/card";
39
40 fd = -1;
41 for (i = 0; i < 16; i++) {
42 char name[80];
43
44 sprintf(name, "%s%u", drmstr, i);
45
46 fd = open(name, O_RDWR);
47 if (fd < 0)
48 continue;
49
50 if (check_vgem(fd)) {
51 close(fd);
52 continue;
53 } else {
54 break;
55 }
56
57 }
58 return fd;
59}
60
61int import_vgem_fd(int vgem_fd, int dma_buf_fd, uint32_t *handle)
62{
63 struct drm_prime_handle import_handle = { 0 };
64 int ret;
65
66 import_handle.fd = dma_buf_fd;
67 import_handle.flags = 0;
68 import_handle.handle = 0;
69
70 ret = ioctl(vgem_fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &import_handle);
71 if (ret == 0)
72 *handle = import_handle.handle;
73 return ret;
74}
75
76void close_handle(int vgem_fd, uint32_t handle)
77{
78 struct drm_gem_close close = { 0 };
79
80 close.handle = handle;
81 ioctl(vgem_fd, DRM_IOCTL_GEM_CLOSE, &close);
82}
83
84int main()
85{
86 int ret, vgem_fd;
87 struct ion_buffer_info info;
88 uint32_t handle = 0;
89 struct dma_buf_sync sync = { 0 };
90
91 info.heap_type = ION_HEAP_TYPE_SYSTEM;
92 info.heap_size = 4096;
93 info.flag_type = ION_FLAG_CACHED;
94
95 ret = ion_export_buffer_fd(&info);
96 if (ret < 0) {
97 printf("ion buffer alloc failed\n");
98 return -1;
99 }
100
101 vgem_fd = open_vgem();
102 if (vgem_fd < 0) {
103 ret = vgem_fd;
104 printf("Failed to open vgem\n");
105 goto out_ion;
106 }
107
108 ret = import_vgem_fd(vgem_fd, info.buffd, &handle);
109
110 if (ret < 0) {
111 printf("Failed to import buffer\n");
112 goto out_vgem;
113 }
114
115 sync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW;
116 ret = ioctl(info.buffd, DMA_BUF_IOCTL_SYNC, &sync);
117 if (ret)
118 printf("sync start failed %d\n", errno);
119
120 memset(info.buffer, 0xff, 4096);
121
122 sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW;
123 ret = ioctl(info.buffd, DMA_BUF_IOCTL_SYNC, &sync);
124 if (ret)
125 printf("sync end failed %d\n", errno);
126
127 close_handle(vgem_fd, handle);
128 ret = 0;
129
130out_vgem:
131 close(vgem_fd);
132out_ion:
133 ion_close_buffer_fd(&info);
134 printf("done.\n");
135 return ret;
136}
diff --git a/tools/testing/selftests/android/ion/ionutils.c b/tools/testing/selftests/android/ion/ionutils.c
index ce69c14f51fa..7d1d37c4ef6a 100644
--- a/tools/testing/selftests/android/ion/ionutils.c
+++ b/tools/testing/selftests/android/ion/ionutils.c
@@ -80,11 +80,6 @@ int ion_export_buffer_fd(struct ion_buffer_info *ion_info)
80 heap_id = MAX_HEAP_COUNT + 1; 80 heap_id = MAX_HEAP_COUNT + 1;
81 for (i = 0; i < query.cnt; i++) { 81 for (i = 0; i < query.cnt; i++) {
82 if (heap_data[i].type == ion_info->heap_type) { 82 if (heap_data[i].type == ion_info->heap_type) {
83 printf("--------------------------------------\n");
84 printf("heap type: %d\n", heap_data[i].type);
85 printf(" heap id: %d\n", heap_data[i].heap_id);
86 printf("heap name: %s\n", heap_data[i].name);
87 printf("--------------------------------------\n");
88 heap_id = heap_data[i].heap_id; 83 heap_id = heap_data[i].heap_id;
89 break; 84 break;
90 } 85 }
@@ -204,7 +199,6 @@ void ion_close_buffer_fd(struct ion_buffer_info *ion_info)
204 /* Finally, close the client fd */ 199 /* Finally, close the client fd */
205 if (ion_info->ionfd > 0) 200 if (ion_info->ionfd > 0)
206 close(ion_info->ionfd); 201 close(ion_info->ionfd);
207 printf("<%s>: buffer release successfully....\n", __func__);
208 } 202 }
209} 203}
210 204
diff --git a/tools/testing/selftests/ftrace/test.d/functions b/tools/testing/selftests/ftrace/test.d/functions
index df3dd7fe5f9b..2a4f16fc9819 100644
--- a/tools/testing/selftests/ftrace/test.d/functions
+++ b/tools/testing/selftests/ftrace/test.d/functions
@@ -59,6 +59,13 @@ disable_events() {
59 echo 0 > events/enable 59 echo 0 > events/enable
60} 60}
61 61
62clear_synthetic_events() { # reset all current synthetic events
63 grep -v ^# synthetic_events |
64 while read line; do
65 echo "!$line" >> synthetic_events
66 done
67}
68
62initialize_ftrace() { # Reset ftrace to initial-state 69initialize_ftrace() { # Reset ftrace to initial-state
63# As the initial state, ftrace will be set to nop tracer, 70# As the initial state, ftrace will be set to nop tracer,
64# no events, no triggers, no filters, no function filters, 71# no events, no triggers, no filters, no function filters,
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-extended-error-support.tc b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-extended-error-support.tc
new file mode 100644
index 000000000000..786dce7e48be
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-extended-error-support.tc
@@ -0,0 +1,39 @@
1#!/bin/sh
2# description: event trigger - test extended error support
3
4
5do_reset() {
6 reset_trigger
7 echo > set_event
8 clear_trace
9}
10
11fail() { #msg
12 do_reset
13 echo $1
14 exit_fail
15}
16
17if [ ! -f set_event ]; then
18 echo "event tracing is not supported"
19 exit_unsupported
20fi
21
22if [ ! -f synthetic_events ]; then
23 echo "synthetic event is not supported"
24 exit_unsupported
25fi
26
27reset_tracer
28do_reset
29
30echo "Test extended error support"
31echo 'hist:keys=pid:ts0=common_timestamp.usecs if comm=="ping"' > events/sched/sched_wakeup/trigger
32echo 'hist:keys=pid:ts0=common_timestamp.usecs if comm=="ping"' >> events/sched/sched_wakeup/trigger &>/dev/null
33if ! grep -q "ERROR:" events/sched/sched_wakeup/hist; then
34 fail "Failed to generate extended error in histogram"
35fi
36
37do_reset
38
39exit 0
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-field-variable-support.tc b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-field-variable-support.tc
new file mode 100644
index 000000000000..7fd5b4a8f060
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-field-variable-support.tc
@@ -0,0 +1,54 @@
1#!/bin/sh
2# description: event trigger - test field variable support
3
4do_reset() {
5 reset_trigger
6 echo > set_event
7 clear_trace
8}
9
10fail() { #msg
11 do_reset
12 echo $1
13 exit_fail
14}
15
16if [ ! -f set_event ]; then
17 echo "event tracing is not supported"
18 exit_unsupported
19fi
20
21if [ ! -f synthetic_events ]; then
22 echo "synthetic event is not supported"
23 exit_unsupported
24fi
25
26clear_synthetic_events
27reset_tracer
28do_reset
29
30echo "Test field variable support"
31
32echo 'wakeup_latency u64 lat; pid_t pid; int prio; char comm[16]' > synthetic_events
33echo 'hist:keys=comm:ts0=common_timestamp.usecs if comm=="ping"' > events/sched/sched_waking/trigger
34echo 'hist:keys=next_comm:wakeup_lat=common_timestamp.usecs-$ts0:onmatch(sched.sched_waking).wakeup_latency($wakeup_lat,next_pid,sched.sched_waking.prio,next_comm) if next_comm=="ping"' > events/sched/sched_switch/trigger
35echo 'hist:keys=pid,prio,comm:vals=lat:sort=pid,prio' > events/synthetic/wakeup_latency/trigger
36
37ping localhost -c 3
38if ! grep -q "ping" events/synthetic/wakeup_latency/hist; then
39 fail "Failed to create inter-event histogram"
40fi
41
42if ! grep -q "synthetic_prio=prio" events/sched/sched_waking/hist; then
43 fail "Failed to create histogram with field variable"
44fi
45
46echo '!hist:keys=next_comm:wakeup_lat=common_timestamp.usecs-$ts0:onmatch(sched.sched_waking).wakeup_latency($wakeup_lat,next_pid,sched.sched_waking.prio,next_comm) if next_comm=="ping"' >> events/sched/sched_switch/trigger
47
48if grep -q "synthetic_prio=prio" events/sched/sched_waking/hist; then
49 fail "Failed to remove histogram with field variable"
50fi
51
52do_reset
53
54exit 0
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-inter-event-combined-hist.tc b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-inter-event-combined-hist.tc
new file mode 100644
index 000000000000..c93dbe38b5df
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-inter-event-combined-hist.tc
@@ -0,0 +1,58 @@
1#!/bin/sh
2# description: event trigger - test inter-event combined histogram trigger
3
4do_reset() {
5 reset_trigger
6 echo > set_event
7 clear_trace
8}
9
10fail() { #msg
11 do_reset
12 echo $1
13 exit_fail
14}
15
16if [ ! -f set_event ]; then
17 echo "event tracing is not supported"
18 exit_unsupported
19fi
20
21if [ ! -f synthetic_events ]; then
22 echo "synthetic event is not supported"
23 exit_unsupported
24fi
25
26reset_tracer
27do_reset
28clear_synthetic_events
29
30echo "Test create synthetic event"
31
32echo 'waking_latency u64 lat pid_t pid' > synthetic_events
33if [ ! -d events/synthetic/waking_latency ]; then
34 fail "Failed to create waking_latency synthetic event"
35fi
36
37echo "Test combined histogram"
38
39echo 'hist:keys=pid:ts0=common_timestamp.usecs if comm=="ping"' > events/sched/sched_waking/trigger
40echo 'hist:keys=pid:waking_lat=common_timestamp.usecs-$ts0:onmatch(sched.sched_waking).waking_latency($waking_lat,pid) if comm=="ping"' > events/sched/sched_wakeup/trigger
41echo 'hist:keys=pid,lat:sort=pid,lat' > events/synthetic/waking_latency/trigger
42
43echo 'wakeup_latency u64 lat pid_t pid' >> synthetic_events
44echo 'hist:keys=pid:ts1=common_timestamp.usecs if comm=="ping"' >> events/sched/sched_wakeup/trigger
45echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts1:onmatch(sched.sched_wakeup).wakeup_latency($wakeup_lat,next_pid) if next_comm=="ping"' > events/sched/sched_switch/trigger
46
47echo 'waking+wakeup_latency u64 lat; pid_t pid' >> synthetic_events
48echo 'hist:keys=pid,lat:sort=pid,lat:ww_lat=$waking_lat+$wakeup_lat:onmatch(synthetic.wakeup_latency).waking+wakeup_latency($ww_lat,pid)' >> events/synthetic/wakeup_latency/trigger
49echo 'hist:keys=pid,lat:sort=pid,lat' >> events/synthetic/waking+wakeup_latency/trigger
50
51ping localhost -c 3
52if ! grep -q "pid:" events/synthetic/waking+wakeup_latency/hist; then
53 fail "Failed to create combined histogram"
54fi
55
56do_reset
57
58exit 0
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmatch-action-hist.tc b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmatch-action-hist.tc
new file mode 100644
index 000000000000..e84e7d048566
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmatch-action-hist.tc
@@ -0,0 +1,50 @@
1#!/bin/sh
2# description: event trigger - test inter-event histogram trigger onmatch action
3
4do_reset() {
5 reset_trigger
6 echo > set_event
7 clear_trace
8}
9
10fail() { #msg
11 do_reset
12 echo $1
13 exit_fail
14}
15
16if [ ! -f set_event ]; then
17 echo "event tracing is not supported"
18 exit_unsupported
19fi
20
21if [ ! -f synthetic_events ]; then
22 echo "synthetic event is not supported"
23 exit_unsupported
24fi
25
26clear_synthetic_events
27reset_tracer
28do_reset
29
30echo "Test create synthetic event"
31
32echo 'wakeup_latency u64 lat pid_t pid char comm[16]' > synthetic_events
33if [ ! -d events/synthetic/wakeup_latency ]; then
34 fail "Failed to create wakeup_latency synthetic event"
35fi
36
37echo "Test create histogram for synthetic event"
38echo "Test histogram variables,simple expression support and onmatch action"
39
40echo 'hist:keys=pid:ts0=common_timestamp.usecs if comm=="ping"' > events/sched/sched_wakeup/trigger
41echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0:onmatch(sched.sched_wakeup).wakeup_latency($wakeup_lat,next_pid,next_comm) if next_comm=="ping"' > events/sched/sched_switch/trigger
42echo 'hist:keys=comm,pid,lat:wakeup_lat=lat:sort=lat' > events/synthetic/wakeup_latency/trigger
43ping localhost -c 5
44if ! grep -q "ping" events/synthetic/wakeup_latency/hist; then
45 fail "Failed to create onmatch action inter-event histogram"
46fi
47
48do_reset
49
50exit 0
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmatch-onmax-action-hist.tc b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmatch-onmax-action-hist.tc
new file mode 100644
index 000000000000..7907d8aacde3
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmatch-onmax-action-hist.tc
@@ -0,0 +1,50 @@
1#!/bin/sh
2# description: event trigger - test inter-event histogram trigger onmatch-onmax action
3
4do_reset() {
5 reset_trigger
6 echo > set_event
7 clear_trace
8}
9
10fail() { #msg
11 do_reset
12 echo $1
13 exit_fail
14}
15
16if [ ! -f set_event ]; then
17 echo "event tracing is not supported"
18 exit_unsupported
19fi
20
21if [ ! -f synthetic_events ]; then
22 echo "synthetic event is not supported"
23 exit_unsupported
24fi
25
26clear_synthetic_events
27reset_tracer
28do_reset
29
30echo "Test create synthetic event"
31
32echo 'wakeup_latency u64 lat pid_t pid char comm[16]' > synthetic_events
33if [ ! -d events/synthetic/wakeup_latency ]; then
34 fail "Failed to create wakeup_latency synthetic event"
35fi
36
37echo "Test create histogram for synthetic event"
38echo "Test histogram variables,simple expression support and onmatch-onmax action"
39
40echo 'hist:keys=pid:ts0=common_timestamp.usecs if comm=="ping"' > events/sched/sched_wakeup/trigger
41echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0:onmatch(sched.sched_wakeup).wakeup_latency($wakeup_lat,next_pid,next_comm):onmax($wakeup_lat).save(next_comm,prev_pid,prev_prio,prev_comm) if next_comm=="ping"' >> events/sched/sched_switch/trigger
42echo 'hist:keys=comm,pid,lat:wakeup_lat=lat:sort=lat' > events/synthetic/wakeup_latency/trigger
43ping localhost -c 5
44if [ ! grep -q "ping" events/synthetic/wakeup_latency/hist -o ! grep -q "max:" events/sched/sched_switch/hist]; then
45 fail "Failed to create onmatch-onmax action inter-event histogram"
46fi
47
48do_reset
49
50exit 0
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmax-action-hist.tc b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmax-action-hist.tc
new file mode 100644
index 000000000000..38b7ed6242b2
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmax-action-hist.tc
@@ -0,0 +1,48 @@
1#!/bin/sh
2# description: event trigger - test inter-event histogram trigger onmax action
3
4do_reset() {
5 reset_trigger
6 echo > set_event
7 clear_trace
8}
9
10fail() { #msg
11 do_reset
12 echo $1
13 exit_fail
14}
15
16if [ ! -f set_event ]; then
17 echo "event tracing is not supported"
18 exit_unsupported
19fi
20
21if [ ! -f synthetic_events ]; then
22 echo "synthetic event is not supported"
23 exit_unsupported
24fi
25
26clear_synthetic_events
27reset_tracer
28do_reset
29
30echo "Test create synthetic event"
31
32echo 'wakeup_latency u64 lat pid_t pid char comm[16]' > synthetic_events
33if [ ! -d events/synthetic/wakeup_latency ]; then
34 fail "Failed to create wakeup_latency synthetic event"
35fi
36
37echo "Test onmax action"
38
39echo 'hist:keys=pid:ts0=common_timestamp.usecs if comm=="ping"' >> events/sched/sched_waking/trigger
40echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0:onmax($wakeup_lat).save(next_comm,prev_pid,prev_prio,prev_comm) if next_comm=="ping"' >> events/sched/sched_switch/trigger
41ping localhost -c 3
42if ! grep -q "max:" events/sched/sched_switch/hist; then
43 fail "Failed to create onmax action inter-event histogram"
44fi
45
46do_reset
47
48exit 0
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-event-createremove.tc b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-event-createremove.tc
new file mode 100644
index 000000000000..cef11377dcbd
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-event-createremove.tc
@@ -0,0 +1,54 @@
1#!/bin/sh
2# description: event trigger - test synthetic event create remove
3do_reset() {
4 reset_trigger
5 echo > set_event
6 clear_trace
7}
8
9fail() { #msg
10 do_reset
11 echo $1
12 exit_fail
13}
14
15if [ ! -f set_event ]; then
16 echo "event tracing is not supported"
17 exit_unsupported
18fi
19
20if [ ! -f synthetic_events ]; then
21 echo "synthetic event is not supported"
22 exit_unsupported
23fi
24
25clear_synthetic_events
26reset_tracer
27do_reset
28
29echo "Test create synthetic event"
30
31echo 'wakeup_latency u64 lat pid_t pid char comm[16]' > synthetic_events
32if [ ! -d events/synthetic/wakeup_latency ]; then
33 fail "Failed to create wakeup_latency synthetic event"
34fi
35
36reset_trigger
37
38echo "Test create synthetic event with an error"
39echo 'wakeup_latency u64 lat pid_t pid char' > synthetic_events > /dev/null
40if [ -d events/synthetic/wakeup_latency ]; then
41 fail "Created wakeup_latency synthetic event with an invalid format"
42fi
43
44reset_trigger
45
46echo "Test remove synthetic event"
47echo '!wakeup_latency u64 lat pid_t pid char comm[16]' > synthetic_events
48if [ -d events/synthetic/wakeup_latency ]; then
49 fail "Failed to delete wakeup_latency synthetic event"
50fi
51
52do_reset
53
54exit 0
diff --git a/tools/testing/selftests/futex/Makefile b/tools/testing/selftests/futex/Makefile
index a63e8453984d..8497a376ef9d 100644
--- a/tools/testing/selftests/futex/Makefile
+++ b/tools/testing/selftests/futex/Makefile
@@ -18,6 +18,10 @@ all:
18 done 18 done
19 19
20override define RUN_TESTS 20override define RUN_TESTS
21 @export KSFT_TAP_LEVEL=`echo 1`;
22 @echo "TAP version 13";
23 @echo "selftests: futex";
24 @echo "========================================";
21 @cd $(OUTPUT); ./run.sh 25 @cd $(OUTPUT); ./run.sh
22endef 26endef
23 27
diff --git a/tools/testing/selftests/intel_pstate/Makefile b/tools/testing/selftests/intel_pstate/Makefile
index 5a3f7d37e912..7340fd6a9a9f 100644
--- a/tools/testing/selftests/intel_pstate/Makefile
+++ b/tools/testing/selftests/intel_pstate/Makefile
@@ -2,7 +2,10 @@
2CFLAGS := $(CFLAGS) -Wall -D_GNU_SOURCE 2CFLAGS := $(CFLAGS) -Wall -D_GNU_SOURCE
3LDLIBS := $(LDLIBS) -lm 3LDLIBS := $(LDLIBS) -lm
4 4
5ifeq (,$(filter $(ARCH),x86)) 5uname_M := $(shell uname -m 2>/dev/null || echo not)
6ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
7
8ifeq (x86,$(ARCH))
6TEST_GEN_FILES := msr aperf 9TEST_GEN_FILES := msr aperf
7endif 10endif
8 11
diff --git a/tools/testing/selftests/kselftest.h b/tools/testing/selftests/kselftest.h
index 1a52b03962a3..1b9d8ecdebce 100644
--- a/tools/testing/selftests/kselftest.h
+++ b/tools/testing/selftests/kselftest.h
@@ -57,7 +57,8 @@ static inline int ksft_get_error_cnt(void) { return ksft_cnt.ksft_error; }
57 57
58static inline void ksft_print_header(void) 58static inline void ksft_print_header(void)
59{ 59{
60 printf("TAP version 13\n"); 60 if (!(getenv("KSFT_TAP_LEVEL")))
61 printf("TAP version 13\n");
61} 62}
62 63
63static inline void ksft_print_cnts(void) 64static inline void ksft_print_cnts(void)
diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h
index e81bd28bdd89..6ae3730c4ee3 100644
--- a/tools/testing/selftests/kselftest_harness.h
+++ b/tools/testing/selftests/kselftest_harness.h
@@ -107,6 +107,27 @@
107 __FILE__, __LINE__, _metadata->name, ##__VA_ARGS__) 107 __FILE__, __LINE__, _metadata->name, ##__VA_ARGS__)
108 108
109/** 109/**
110 * XFAIL(statement, fmt, ...)
111 *
112 * @statement: statement to run after reporting XFAIL
113 * @fmt: format string
114 * @...: optional arguments
115 *
116 * This forces a "pass" after reporting a failure with an XFAIL prefix,
117 * and runs "statement", which is usually "return" or "goto skip".
118 */
119#define XFAIL(statement, fmt, ...) do { \
120 if (TH_LOG_ENABLED) { \
121 fprintf(TH_LOG_STREAM, "[ XFAIL! ] " fmt "\n", \
122 ##__VA_ARGS__); \
123 } \
124 /* TODO: find a way to pass xfail to test runner process. */ \
125 _metadata->passed = 1; \
126 _metadata->trigger = 0; \
127 statement; \
128} while (0)
129
130/**
110 * TEST(test_name) - Defines the test function and creates the registration 131 * TEST(test_name) - Defines the test function and creates the registration
111 * stub 132 * stub
112 * 133 *
@@ -198,7 +219,7 @@
198 219
199/** 220/**
200 * FIXTURE_SETUP(fixture_name) - Prepares the setup function for the fixture. 221 * FIXTURE_SETUP(fixture_name) - Prepares the setup function for the fixture.
201 * *_metadata* is included so that ASSERT_* work as a convenience 222 * *_metadata* is included so that EXPECT_* and ASSERT_* work correctly.
202 * 223 *
203 * @fixture_name: fixture name 224 * @fixture_name: fixture name
204 * 225 *
@@ -221,6 +242,7 @@
221 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) 242 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self)
222/** 243/**
223 * FIXTURE_TEARDOWN(fixture_name) 244 * FIXTURE_TEARDOWN(fixture_name)
245 * *_metadata* is included so that EXPECT_* and ASSERT_* work correctly.
224 * 246 *
225 * @fixture_name: fixture name 247 * @fixture_name: fixture name
226 * 248 *
@@ -253,6 +275,8 @@
253 * Defines a test that depends on a fixture (e.g., is part of a test case). 275 * Defines a test that depends on a fixture (e.g., is part of a test case).
254 * Very similar to TEST() except that *self* is the setup instance of fixture's 276 * Very similar to TEST() except that *self* is the setup instance of fixture's
255 * datatype exposed for use by the implementation. 277 * datatype exposed for use by the implementation.
278 *
279 * Warning: use of ASSERT_* here will skip TEARDOWN.
256 */ 280 */
257/* TODO(wad) register fixtures on dedicated test lists. */ 281/* TODO(wad) register fixtures on dedicated test lists. */
258#define TEST_F(fixture_name, test_name) \ 282#define TEST_F(fixture_name, test_name) \
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
new file mode 100644
index 000000000000..2ddcc96ae456
--- /dev/null
+++ b/tools/testing/selftests/kvm/Makefile
@@ -0,0 +1,40 @@
1all:
2
3top_srcdir = ../../../../
4UNAME_M := $(shell uname -m)
5
6LIBKVM = lib/assert.c lib/elf.c lib/io.c lib/kvm_util.c lib/sparsebit.c
7LIBKVM_x86_64 = lib/x86.c lib/vmx.c
8
9TEST_GEN_PROGS_x86_64 = set_sregs_test
10TEST_GEN_PROGS_x86_64 += sync_regs_test
11TEST_GEN_PROGS_x86_64 += vmx_tsc_adjust_test
12
13TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(UNAME_M))
14LIBKVM += $(LIBKVM_$(UNAME_M))
15
16INSTALL_HDR_PATH = $(top_srcdir)/usr
17LINUX_HDR_PATH = $(INSTALL_HDR_PATH)/include/
18CFLAGS += -O2 -g -std=gnu99 -I$(LINUX_HDR_PATH) -Iinclude -I$(<D)
19
20# After inclusion, $(OUTPUT) is defined and
21# $(TEST_GEN_PROGS) starts with $(OUTPUT)/
22include ../lib.mk
23
24STATIC_LIBS := $(OUTPUT)/libkvm.a
25LIBKVM_OBJ := $(patsubst %.c, $(OUTPUT)/%.o, $(LIBKVM))
26EXTRA_CLEAN += $(LIBKVM_OBJ) $(STATIC_LIBS)
27
28x := $(shell mkdir -p $(sort $(dir $(LIBKVM_OBJ))))
29$(LIBKVM_OBJ): $(OUTPUT)/%.o: %.c
30 $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
31
32$(OUTPUT)/libkvm.a: $(LIBKVM_OBJ)
33 $(AR) crs $@ $^
34
35$(LINUX_HDR_PATH):
36 make -C $(top_srcdir) headers_install
37
38all: $(STATIC_LIBS) $(LINUX_HDR_PATH)
39$(TEST_GEN_PROGS): $(STATIC_LIBS)
40$(TEST_GEN_PROGS) $(LIBKVM_OBJ): | $(LINUX_HDR_PATH)
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
new file mode 100644
index 000000000000..637b7017b6ee
--- /dev/null
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -0,0 +1,145 @@
1/*
2 * tools/testing/selftests/kvm/include/kvm_util.h
3 *
4 * Copyright (C) 2018, Google LLC.
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2.
7 *
8 */
9#ifndef SELFTEST_KVM_UTIL_H
10#define SELFTEST_KVM_UTIL_H 1
11
12#include "test_util.h"
13
14#include "asm/kvm.h"
15#include "linux/kvm.h"
16#include <sys/ioctl.h>
17
18#include "sparsebit.h"
19
20/*
21 * Memslots can't cover the gfn starting at this gpa otherwise vCPUs can't be
22 * created. Only applies to VMs using EPT.
23 */
24#define KVM_DEFAULT_IDENTITY_MAP_ADDRESS 0xfffbc000ul
25
26
27/* Callers of kvm_util only have an incomplete/opaque description of the
28 * structure kvm_util is using to maintain the state of a VM.
29 */
30struct kvm_vm;
31
32typedef uint64_t vm_paddr_t; /* Virtual Machine (Guest) physical address */
33typedef uint64_t vm_vaddr_t; /* Virtual Machine (Guest) virtual address */
34
35/* Minimum allocated guest virtual and physical addresses */
36#define KVM_UTIL_MIN_VADDR 0x2000
37
38#define DEFAULT_GUEST_PHY_PAGES 512
39#define DEFAULT_GUEST_STACK_VADDR_MIN 0xab6000
40#define DEFAULT_STACK_PGS 5
41
42enum vm_guest_mode {
43 VM_MODE_FLAT48PG,
44};
45
46enum vm_mem_backing_src_type {
47 VM_MEM_SRC_ANONYMOUS,
48 VM_MEM_SRC_ANONYMOUS_THP,
49 VM_MEM_SRC_ANONYMOUS_HUGETLB,
50};
51
52int kvm_check_cap(long cap);
53
54struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm);
55void kvm_vm_free(struct kvm_vm *vmp);
56
57int kvm_memcmp_hva_gva(void *hva,
58 struct kvm_vm *vm, const vm_vaddr_t gva, size_t len);
59
60void kvm_vm_elf_load(struct kvm_vm *vm, const char *filename,
61 uint32_t data_memslot, uint32_t pgd_memslot);
62
63void vm_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent);
64void vcpu_dump(FILE *stream, struct kvm_vm *vm,
65 uint32_t vcpuid, uint8_t indent);
66
67void vm_create_irqchip(struct kvm_vm *vm);
68
69void vm_userspace_mem_region_add(struct kvm_vm *vm,
70 enum vm_mem_backing_src_type src_type,
71 uint64_t guest_paddr, uint32_t slot, uint64_t npages,
72 uint32_t flags);
73
74void vcpu_ioctl(struct kvm_vm *vm,
75 uint32_t vcpuid, unsigned long ioctl, void *arg);
76void vm_ioctl(struct kvm_vm *vm, unsigned long ioctl, void *arg);
77void vm_mem_region_set_flags(struct kvm_vm *vm, uint32_t slot, uint32_t flags);
78void vm_vcpu_add(struct kvm_vm *vm, uint32_t vcpuid);
79vm_vaddr_t vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min,
80 uint32_t data_memslot, uint32_t pgd_memslot);
81void *addr_gpa2hva(struct kvm_vm *vm, vm_paddr_t gpa);
82void *addr_gva2hva(struct kvm_vm *vm, vm_vaddr_t gva);
83vm_paddr_t addr_hva2gpa(struct kvm_vm *vm, void *hva);
84vm_paddr_t addr_gva2gpa(struct kvm_vm *vm, vm_vaddr_t gva);
85
86struct kvm_run *vcpu_state(struct kvm_vm *vm, uint32_t vcpuid);
87void vcpu_run(struct kvm_vm *vm, uint32_t vcpuid);
88int _vcpu_run(struct kvm_vm *vm, uint32_t vcpuid);
89void vcpu_set_mp_state(struct kvm_vm *vm, uint32_t vcpuid,
90 struct kvm_mp_state *mp_state);
91void vcpu_regs_get(struct kvm_vm *vm,
92 uint32_t vcpuid, struct kvm_regs *regs);
93void vcpu_regs_set(struct kvm_vm *vm,
94 uint32_t vcpuid, struct kvm_regs *regs);
95void vcpu_args_set(struct kvm_vm *vm, uint32_t vcpuid, unsigned int num, ...);
96void vcpu_sregs_get(struct kvm_vm *vm,
97 uint32_t vcpuid, struct kvm_sregs *sregs);
98void vcpu_sregs_set(struct kvm_vm *vm,
99 uint32_t vcpuid, struct kvm_sregs *sregs);
100int _vcpu_sregs_set(struct kvm_vm *vm,
101 uint32_t vcpuid, struct kvm_sregs *sregs);
102void vcpu_events_get(struct kvm_vm *vm, uint32_t vcpuid,
103 struct kvm_vcpu_events *events);
104void vcpu_events_set(struct kvm_vm *vm, uint32_t vcpuid,
105 struct kvm_vcpu_events *events);
106
107const char *exit_reason_str(unsigned int exit_reason);
108
109void virt_pgd_alloc(struct kvm_vm *vm, uint32_t pgd_memslot);
110void virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr,
111 uint32_t pgd_memslot);
112vm_paddr_t vm_phy_page_alloc(struct kvm_vm *vm,
113 vm_paddr_t paddr_min, uint32_t memslot);
114
115struct kvm_cpuid2 *kvm_get_supported_cpuid(void);
116void vcpu_set_cpuid(
117 struct kvm_vm *vm, uint32_t vcpuid, struct kvm_cpuid2 *cpuid);
118
119struct kvm_cpuid_entry2 *
120kvm_get_supported_cpuid_index(uint32_t function, uint32_t index);
121
122static inline struct kvm_cpuid_entry2 *
123kvm_get_supported_cpuid_entry(uint32_t function)
124{
125 return kvm_get_supported_cpuid_index(function, 0);
126}
127
128struct kvm_vm *vm_create_default(uint32_t vcpuid, void *guest_code);
129void vm_vcpu_add_default(struct kvm_vm *vm, uint32_t vcpuid, void *guest_code);
130
131typedef void (*vmx_guest_code_t)(vm_vaddr_t vmxon_vaddr,
132 vm_paddr_t vmxon_paddr,
133 vm_vaddr_t vmcs_vaddr,
134 vm_paddr_t vmcs_paddr);
135
136struct kvm_userspace_memory_region *
137kvm_userspace_memory_region_find(struct kvm_vm *vm, uint64_t start,
138 uint64_t end);
139
140struct kvm_dirty_log *
141allocate_kvm_dirty_log(struct kvm_userspace_memory_region *region);
142
143int vm_create_device(struct kvm_vm *vm, struct kvm_create_device *cd);
144
145#endif /* SELFTEST_KVM_UTIL_H */
diff --git a/tools/testing/selftests/kvm/include/sparsebit.h b/tools/testing/selftests/kvm/include/sparsebit.h
new file mode 100644
index 000000000000..54cfeb6568d3
--- /dev/null
+++ b/tools/testing/selftests/kvm/include/sparsebit.h
@@ -0,0 +1,75 @@
1/*
2 * tools/testing/selftests/kvm/include/sparsebit.h
3 *
4 * Copyright (C) 2018, Google LLC.
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2.
7 *
8 *
9 * Header file that describes API to the sparsebit library.
10 * This library provides a memory efficient means of storing
11 * the settings of bits indexed via a uint64_t. Memory usage
12 * is reasonable, significantly less than (2^64 / 8) bytes, as
13 * long as bits that are mostly set or mostly cleared are close
14 * to each other. This library is efficient in memory usage
15 * even in the case where most bits are set.
16 */
17
18#ifndef _TEST_SPARSEBIT_H_
19#define _TEST_SPARSEBIT_H_
20
21#include <stdbool.h>
22#include <stdint.h>
23#include <stdio.h>
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29struct sparsebit;
30typedef uint64_t sparsebit_idx_t;
31typedef uint64_t sparsebit_num_t;
32
33struct sparsebit *sparsebit_alloc(void);
34void sparsebit_free(struct sparsebit **sbitp);
35void sparsebit_copy(struct sparsebit *dstp, struct sparsebit *src);
36
37bool sparsebit_is_set(struct sparsebit *sbit, sparsebit_idx_t idx);
38bool sparsebit_is_set_num(struct sparsebit *sbit,
39 sparsebit_idx_t idx, sparsebit_num_t num);
40bool sparsebit_is_clear(struct sparsebit *sbit, sparsebit_idx_t idx);
41bool sparsebit_is_clear_num(struct sparsebit *sbit,
42 sparsebit_idx_t idx, sparsebit_num_t num);
43sparsebit_num_t sparsebit_num_set(struct sparsebit *sbit);
44bool sparsebit_any_set(struct sparsebit *sbit);
45bool sparsebit_any_clear(struct sparsebit *sbit);
46bool sparsebit_all_set(struct sparsebit *sbit);
47bool sparsebit_all_clear(struct sparsebit *sbit);
48sparsebit_idx_t sparsebit_first_set(struct sparsebit *sbit);
49sparsebit_idx_t sparsebit_first_clear(struct sparsebit *sbit);
50sparsebit_idx_t sparsebit_next_set(struct sparsebit *sbit, sparsebit_idx_t prev);
51sparsebit_idx_t sparsebit_next_clear(struct sparsebit *sbit, sparsebit_idx_t prev);
52sparsebit_idx_t sparsebit_next_set_num(struct sparsebit *sbit,
53 sparsebit_idx_t start, sparsebit_num_t num);
54sparsebit_idx_t sparsebit_next_clear_num(struct sparsebit *sbit,
55 sparsebit_idx_t start, sparsebit_num_t num);
56
57void sparsebit_set(struct sparsebit *sbitp, sparsebit_idx_t idx);
58void sparsebit_set_num(struct sparsebit *sbitp, sparsebit_idx_t start,
59 sparsebit_num_t num);
60void sparsebit_set_all(struct sparsebit *sbitp);
61
62void sparsebit_clear(struct sparsebit *sbitp, sparsebit_idx_t idx);
63void sparsebit_clear_num(struct sparsebit *sbitp,
64 sparsebit_idx_t start, sparsebit_num_t num);
65void sparsebit_clear_all(struct sparsebit *sbitp);
66
67void sparsebit_dump(FILE *stream, struct sparsebit *sbit,
68 unsigned int indent);
69void sparsebit_validate_internal(struct sparsebit *sbit);
70
71#ifdef __cplusplus
72}
73#endif
74
75#endif /* _TEST_SPARSEBIT_H_ */
diff --git a/tools/testing/selftests/kvm/include/test_util.h b/tools/testing/selftests/kvm/include/test_util.h
new file mode 100644
index 000000000000..7ab98e41324f
--- /dev/null
+++ b/tools/testing/selftests/kvm/include/test_util.h
@@ -0,0 +1,45 @@
1/*
2 * tools/testing/selftests/kvm/include/test_util.h
3 *
4 * Copyright (C) 2018, Google LLC.
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2.
7 *
8 */
9
10#ifndef TEST_UTIL_H
11#define TEST_UTIL_H 1
12
13#include <stdlib.h>
14#include <stdarg.h>
15#include <stdbool.h>
16#include <stdio.h>
17#include <string.h>
18#include <inttypes.h>
19#include <errno.h>
20#include <unistd.h>
21#include <fcntl.h>
22
23ssize_t test_write(int fd, const void *buf, size_t count);
24ssize_t test_read(int fd, void *buf, size_t count);
25int test_seq_read(const char *path, char **bufp, size_t *sizep);
26
27void test_assert(bool exp, const char *exp_str,
28 const char *file, unsigned int line, const char *fmt, ...);
29
30#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
31
32#define TEST_ASSERT(e, fmt, ...) \
33 test_assert((e), #e, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
34
35#define ASSERT_EQ(a, b) do { \
36 typeof(a) __a = (a); \
37 typeof(b) __b = (b); \
38 TEST_ASSERT(__a == __b, \
39 "ASSERT_EQ(%s, %s) failed.\n" \
40 "\t%s is %#lx\n" \
41 "\t%s is %#lx", \
42 #a, #b, #a, (unsigned long) __a, #b, (unsigned long) __b); \
43} while (0)
44
45#endif /* TEST_UTIL_H */
diff --git a/tools/testing/selftests/kvm/include/vmx.h b/tools/testing/selftests/kvm/include/vmx.h
new file mode 100644
index 000000000000..6ed8499807fd
--- /dev/null
+++ b/tools/testing/selftests/kvm/include/vmx.h
@@ -0,0 +1,494 @@
1/*
2 * tools/testing/selftests/kvm/include/vmx.h
3 *
4 * Copyright (C) 2018, Google LLC.
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2.
7 *
8 */
9
10#ifndef SELFTEST_KVM_VMX_H
11#define SELFTEST_KVM_VMX_H
12
13#include <stdint.h>
14#include "x86.h"
15
16#define CPUID_VMX_BIT 5
17
18#define CPUID_VMX (1 << 5)
19
20/*
21 * Definitions of Primary Processor-Based VM-Execution Controls.
22 */
23#define CPU_BASED_VIRTUAL_INTR_PENDING 0x00000004
24#define CPU_BASED_USE_TSC_OFFSETING 0x00000008
25#define CPU_BASED_HLT_EXITING 0x00000080
26#define CPU_BASED_INVLPG_EXITING 0x00000200
27#define CPU_BASED_MWAIT_EXITING 0x00000400
28#define CPU_BASED_RDPMC_EXITING 0x00000800
29#define CPU_BASED_RDTSC_EXITING 0x00001000
30#define CPU_BASED_CR3_LOAD_EXITING 0x00008000
31#define CPU_BASED_CR3_STORE_EXITING 0x00010000
32#define CPU_BASED_CR8_LOAD_EXITING 0x00080000
33#define CPU_BASED_CR8_STORE_EXITING 0x00100000
34#define CPU_BASED_TPR_SHADOW 0x00200000
35#define CPU_BASED_VIRTUAL_NMI_PENDING 0x00400000
36#define CPU_BASED_MOV_DR_EXITING 0x00800000
37#define CPU_BASED_UNCOND_IO_EXITING 0x01000000
38#define CPU_BASED_USE_IO_BITMAPS 0x02000000
39#define CPU_BASED_MONITOR_TRAP 0x08000000
40#define CPU_BASED_USE_MSR_BITMAPS 0x10000000
41#define CPU_BASED_MONITOR_EXITING 0x20000000
42#define CPU_BASED_PAUSE_EXITING 0x40000000
43#define CPU_BASED_ACTIVATE_SECONDARY_CONTROLS 0x80000000
44
45#define CPU_BASED_ALWAYSON_WITHOUT_TRUE_MSR 0x0401e172
46
47/*
48 * Definitions of Secondary Processor-Based VM-Execution Controls.
49 */
50#define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001
51#define SECONDARY_EXEC_ENABLE_EPT 0x00000002
52#define SECONDARY_EXEC_DESC 0x00000004
53#define SECONDARY_EXEC_RDTSCP 0x00000008
54#define SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE 0x00000010
55#define SECONDARY_EXEC_ENABLE_VPID 0x00000020
56#define SECONDARY_EXEC_WBINVD_EXITING 0x00000040
57#define SECONDARY_EXEC_UNRESTRICTED_GUEST 0x00000080
58#define SECONDARY_EXEC_APIC_REGISTER_VIRT 0x00000100
59#define SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY 0x00000200
60#define SECONDARY_EXEC_PAUSE_LOOP_EXITING 0x00000400
61#define SECONDARY_EXEC_RDRAND_EXITING 0x00000800
62#define SECONDARY_EXEC_ENABLE_INVPCID 0x00001000
63#define SECONDARY_EXEC_ENABLE_VMFUNC 0x00002000
64#define SECONDARY_EXEC_SHADOW_VMCS 0x00004000
65#define SECONDARY_EXEC_RDSEED_EXITING 0x00010000
66#define SECONDARY_EXEC_ENABLE_PML 0x00020000
67#define SECONDARY_EPT_VE 0x00040000
68#define SECONDARY_ENABLE_XSAV_RESTORE 0x00100000
69#define SECONDARY_EXEC_TSC_SCALING 0x02000000
70
71#define PIN_BASED_EXT_INTR_MASK 0x00000001
72#define PIN_BASED_NMI_EXITING 0x00000008
73#define PIN_BASED_VIRTUAL_NMIS 0x00000020
74#define PIN_BASED_VMX_PREEMPTION_TIMER 0x00000040
75#define PIN_BASED_POSTED_INTR 0x00000080
76
77#define PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR 0x00000016
78
79#define VM_EXIT_SAVE_DEBUG_CONTROLS 0x00000004
80#define VM_EXIT_HOST_ADDR_SPACE_SIZE 0x00000200
81#define VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL 0x00001000
82#define VM_EXIT_ACK_INTR_ON_EXIT 0x00008000
83#define VM_EXIT_SAVE_IA32_PAT 0x00040000
84#define VM_EXIT_LOAD_IA32_PAT 0x00080000
85#define VM_EXIT_SAVE_IA32_EFER 0x00100000
86#define VM_EXIT_LOAD_IA32_EFER 0x00200000
87#define VM_EXIT_SAVE_VMX_PREEMPTION_TIMER 0x00400000
88
89#define VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR 0x00036dff
90
91#define VM_ENTRY_LOAD_DEBUG_CONTROLS 0x00000004
92#define VM_ENTRY_IA32E_MODE 0x00000200
93#define VM_ENTRY_SMM 0x00000400
94#define VM_ENTRY_DEACT_DUAL_MONITOR 0x00000800
95#define VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL 0x00002000
96#define VM_ENTRY_LOAD_IA32_PAT 0x00004000
97#define VM_ENTRY_LOAD_IA32_EFER 0x00008000
98
99#define VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR 0x000011ff
100
101#define VMX_MISC_PREEMPTION_TIMER_RATE_MASK 0x0000001f
102#define VMX_MISC_SAVE_EFER_LMA 0x00000020
103
104#define EXIT_REASON_FAILED_VMENTRY 0x80000000
105#define EXIT_REASON_EXCEPTION_NMI 0
106#define EXIT_REASON_EXTERNAL_INTERRUPT 1
107#define EXIT_REASON_TRIPLE_FAULT 2
108#define EXIT_REASON_PENDING_INTERRUPT 7
109#define EXIT_REASON_NMI_WINDOW 8
110#define EXIT_REASON_TASK_SWITCH 9
111#define EXIT_REASON_CPUID 10
112#define EXIT_REASON_HLT 12
113#define EXIT_REASON_INVD 13
114#define EXIT_REASON_INVLPG 14
115#define EXIT_REASON_RDPMC 15
116#define EXIT_REASON_RDTSC 16
117#define EXIT_REASON_VMCALL 18
118#define EXIT_REASON_VMCLEAR 19
119#define EXIT_REASON_VMLAUNCH 20
120#define EXIT_REASON_VMPTRLD 21
121#define EXIT_REASON_VMPTRST 22
122#define EXIT_REASON_VMREAD 23
123#define EXIT_REASON_VMRESUME 24
124#define EXIT_REASON_VMWRITE 25
125#define EXIT_REASON_VMOFF 26
126#define EXIT_REASON_VMON 27
127#define EXIT_REASON_CR_ACCESS 28
128#define EXIT_REASON_DR_ACCESS 29
129#define EXIT_REASON_IO_INSTRUCTION 30
130#define EXIT_REASON_MSR_READ 31
131#define EXIT_REASON_MSR_WRITE 32
132#define EXIT_REASON_INVALID_STATE 33
133#define EXIT_REASON_MWAIT_INSTRUCTION 36
134#define EXIT_REASON_MONITOR_INSTRUCTION 39
135#define EXIT_REASON_PAUSE_INSTRUCTION 40
136#define EXIT_REASON_MCE_DURING_VMENTRY 41
137#define EXIT_REASON_TPR_BELOW_THRESHOLD 43
138#define EXIT_REASON_APIC_ACCESS 44
139#define EXIT_REASON_EOI_INDUCED 45
140#define EXIT_REASON_EPT_VIOLATION 48
141#define EXIT_REASON_EPT_MISCONFIG 49
142#define EXIT_REASON_INVEPT 50
143#define EXIT_REASON_RDTSCP 51
144#define EXIT_REASON_PREEMPTION_TIMER 52
145#define EXIT_REASON_INVVPID 53
146#define EXIT_REASON_WBINVD 54
147#define EXIT_REASON_XSETBV 55
148#define EXIT_REASON_APIC_WRITE 56
149#define EXIT_REASON_INVPCID 58
150#define EXIT_REASON_PML_FULL 62
151#define EXIT_REASON_XSAVES 63
152#define EXIT_REASON_XRSTORS 64
153#define LAST_EXIT_REASON 64
154
155enum vmcs_field {
156 VIRTUAL_PROCESSOR_ID = 0x00000000,
157 POSTED_INTR_NV = 0x00000002,
158 GUEST_ES_SELECTOR = 0x00000800,
159 GUEST_CS_SELECTOR = 0x00000802,
160 GUEST_SS_SELECTOR = 0x00000804,
161 GUEST_DS_SELECTOR = 0x00000806,
162 GUEST_FS_SELECTOR = 0x00000808,
163 GUEST_GS_SELECTOR = 0x0000080a,
164 GUEST_LDTR_SELECTOR = 0x0000080c,
165 GUEST_TR_SELECTOR = 0x0000080e,
166 GUEST_INTR_STATUS = 0x00000810,
167 GUEST_PML_INDEX = 0x00000812,
168 HOST_ES_SELECTOR = 0x00000c00,
169 HOST_CS_SELECTOR = 0x00000c02,
170 HOST_SS_SELECTOR = 0x00000c04,
171 HOST_DS_SELECTOR = 0x00000c06,
172 HOST_FS_SELECTOR = 0x00000c08,
173 HOST_GS_SELECTOR = 0x00000c0a,
174 HOST_TR_SELECTOR = 0x00000c0c,
175 IO_BITMAP_A = 0x00002000,
176 IO_BITMAP_A_HIGH = 0x00002001,
177 IO_BITMAP_B = 0x00002002,
178 IO_BITMAP_B_HIGH = 0x00002003,
179 MSR_BITMAP = 0x00002004,
180 MSR_BITMAP_HIGH = 0x00002005,
181 VM_EXIT_MSR_STORE_ADDR = 0x00002006,
182 VM_EXIT_MSR_STORE_ADDR_HIGH = 0x00002007,
183 VM_EXIT_MSR_LOAD_ADDR = 0x00002008,
184 VM_EXIT_MSR_LOAD_ADDR_HIGH = 0x00002009,
185 VM_ENTRY_MSR_LOAD_ADDR = 0x0000200a,
186 VM_ENTRY_MSR_LOAD_ADDR_HIGH = 0x0000200b,
187 PML_ADDRESS = 0x0000200e,
188 PML_ADDRESS_HIGH = 0x0000200f,
189 TSC_OFFSET = 0x00002010,
190 TSC_OFFSET_HIGH = 0x00002011,
191 VIRTUAL_APIC_PAGE_ADDR = 0x00002012,
192 VIRTUAL_APIC_PAGE_ADDR_HIGH = 0x00002013,
193 APIC_ACCESS_ADDR = 0x00002014,
194 APIC_ACCESS_ADDR_HIGH = 0x00002015,
195 POSTED_INTR_DESC_ADDR = 0x00002016,
196 POSTED_INTR_DESC_ADDR_HIGH = 0x00002017,
197 EPT_POINTER = 0x0000201a,
198 EPT_POINTER_HIGH = 0x0000201b,
199 EOI_EXIT_BITMAP0 = 0x0000201c,
200 EOI_EXIT_BITMAP0_HIGH = 0x0000201d,
201 EOI_EXIT_BITMAP1 = 0x0000201e,
202 EOI_EXIT_BITMAP1_HIGH = 0x0000201f,
203 EOI_EXIT_BITMAP2 = 0x00002020,
204 EOI_EXIT_BITMAP2_HIGH = 0x00002021,
205 EOI_EXIT_BITMAP3 = 0x00002022,
206 EOI_EXIT_BITMAP3_HIGH = 0x00002023,
207 VMREAD_BITMAP = 0x00002026,
208 VMREAD_BITMAP_HIGH = 0x00002027,
209 VMWRITE_BITMAP = 0x00002028,
210 VMWRITE_BITMAP_HIGH = 0x00002029,
211 XSS_EXIT_BITMAP = 0x0000202C,
212 XSS_EXIT_BITMAP_HIGH = 0x0000202D,
213 TSC_MULTIPLIER = 0x00002032,
214 TSC_MULTIPLIER_HIGH = 0x00002033,
215 GUEST_PHYSICAL_ADDRESS = 0x00002400,
216 GUEST_PHYSICAL_ADDRESS_HIGH = 0x00002401,
217 VMCS_LINK_POINTER = 0x00002800,
218 VMCS_LINK_POINTER_HIGH = 0x00002801,
219 GUEST_IA32_DEBUGCTL = 0x00002802,
220 GUEST_IA32_DEBUGCTL_HIGH = 0x00002803,
221 GUEST_IA32_PAT = 0x00002804,
222 GUEST_IA32_PAT_HIGH = 0x00002805,
223 GUEST_IA32_EFER = 0x00002806,
224 GUEST_IA32_EFER_HIGH = 0x00002807,
225 GUEST_IA32_PERF_GLOBAL_CTRL = 0x00002808,
226 GUEST_IA32_PERF_GLOBAL_CTRL_HIGH= 0x00002809,
227 GUEST_PDPTR0 = 0x0000280a,
228 GUEST_PDPTR0_HIGH = 0x0000280b,
229 GUEST_PDPTR1 = 0x0000280c,
230 GUEST_PDPTR1_HIGH = 0x0000280d,
231 GUEST_PDPTR2 = 0x0000280e,
232 GUEST_PDPTR2_HIGH = 0x0000280f,
233 GUEST_PDPTR3 = 0x00002810,
234 GUEST_PDPTR3_HIGH = 0x00002811,
235 GUEST_BNDCFGS = 0x00002812,
236 GUEST_BNDCFGS_HIGH = 0x00002813,
237 HOST_IA32_PAT = 0x00002c00,
238 HOST_IA32_PAT_HIGH = 0x00002c01,
239 HOST_IA32_EFER = 0x00002c02,
240 HOST_IA32_EFER_HIGH = 0x00002c03,
241 HOST_IA32_PERF_GLOBAL_CTRL = 0x00002c04,
242 HOST_IA32_PERF_GLOBAL_CTRL_HIGH = 0x00002c05,
243 PIN_BASED_VM_EXEC_CONTROL = 0x00004000,
244 CPU_BASED_VM_EXEC_CONTROL = 0x00004002,
245 EXCEPTION_BITMAP = 0x00004004,
246 PAGE_FAULT_ERROR_CODE_MASK = 0x00004006,
247 PAGE_FAULT_ERROR_CODE_MATCH = 0x00004008,
248 CR3_TARGET_COUNT = 0x0000400a,
249 VM_EXIT_CONTROLS = 0x0000400c,
250 VM_EXIT_MSR_STORE_COUNT = 0x0000400e,
251 VM_EXIT_MSR_LOAD_COUNT = 0x00004010,
252 VM_ENTRY_CONTROLS = 0x00004012,
253 VM_ENTRY_MSR_LOAD_COUNT = 0x00004014,
254 VM_ENTRY_INTR_INFO_FIELD = 0x00004016,
255 VM_ENTRY_EXCEPTION_ERROR_CODE = 0x00004018,
256 VM_ENTRY_INSTRUCTION_LEN = 0x0000401a,
257 TPR_THRESHOLD = 0x0000401c,
258 SECONDARY_VM_EXEC_CONTROL = 0x0000401e,
259 PLE_GAP = 0x00004020,
260 PLE_WINDOW = 0x00004022,
261 VM_INSTRUCTION_ERROR = 0x00004400,
262 VM_EXIT_REASON = 0x00004402,
263 VM_EXIT_INTR_INFO = 0x00004404,
264 VM_EXIT_INTR_ERROR_CODE = 0x00004406,
265 IDT_VECTORING_INFO_FIELD = 0x00004408,
266 IDT_VECTORING_ERROR_CODE = 0x0000440a,
267 VM_EXIT_INSTRUCTION_LEN = 0x0000440c,
268 VMX_INSTRUCTION_INFO = 0x0000440e,
269 GUEST_ES_LIMIT = 0x00004800,
270 GUEST_CS_LIMIT = 0x00004802,
271 GUEST_SS_LIMIT = 0x00004804,
272 GUEST_DS_LIMIT = 0x00004806,
273 GUEST_FS_LIMIT = 0x00004808,
274 GUEST_GS_LIMIT = 0x0000480a,
275 GUEST_LDTR_LIMIT = 0x0000480c,
276 GUEST_TR_LIMIT = 0x0000480e,
277 GUEST_GDTR_LIMIT = 0x00004810,
278 GUEST_IDTR_LIMIT = 0x00004812,
279 GUEST_ES_AR_BYTES = 0x00004814,
280 GUEST_CS_AR_BYTES = 0x00004816,
281 GUEST_SS_AR_BYTES = 0x00004818,
282 GUEST_DS_AR_BYTES = 0x0000481a,
283 GUEST_FS_AR_BYTES = 0x0000481c,
284 GUEST_GS_AR_BYTES = 0x0000481e,
285 GUEST_LDTR_AR_BYTES = 0x00004820,
286 GUEST_TR_AR_BYTES = 0x00004822,
287 GUEST_INTERRUPTIBILITY_INFO = 0x00004824,
288 GUEST_ACTIVITY_STATE = 0X00004826,
289 GUEST_SYSENTER_CS = 0x0000482A,
290 VMX_PREEMPTION_TIMER_VALUE = 0x0000482E,
291 HOST_IA32_SYSENTER_CS = 0x00004c00,
292 CR0_GUEST_HOST_MASK = 0x00006000,
293 CR4_GUEST_HOST_MASK = 0x00006002,
294 CR0_READ_SHADOW = 0x00006004,
295 CR4_READ_SHADOW = 0x00006006,
296 CR3_TARGET_VALUE0 = 0x00006008,
297 CR3_TARGET_VALUE1 = 0x0000600a,
298 CR3_TARGET_VALUE2 = 0x0000600c,
299 CR3_TARGET_VALUE3 = 0x0000600e,
300 EXIT_QUALIFICATION = 0x00006400,
301 GUEST_LINEAR_ADDRESS = 0x0000640a,
302 GUEST_CR0 = 0x00006800,
303 GUEST_CR3 = 0x00006802,
304 GUEST_CR4 = 0x00006804,
305 GUEST_ES_BASE = 0x00006806,
306 GUEST_CS_BASE = 0x00006808,
307 GUEST_SS_BASE = 0x0000680a,
308 GUEST_DS_BASE = 0x0000680c,
309 GUEST_FS_BASE = 0x0000680e,
310 GUEST_GS_BASE = 0x00006810,
311 GUEST_LDTR_BASE = 0x00006812,
312 GUEST_TR_BASE = 0x00006814,
313 GUEST_GDTR_BASE = 0x00006816,
314 GUEST_IDTR_BASE = 0x00006818,
315 GUEST_DR7 = 0x0000681a,
316 GUEST_RSP = 0x0000681c,
317 GUEST_RIP = 0x0000681e,
318 GUEST_RFLAGS = 0x00006820,
319 GUEST_PENDING_DBG_EXCEPTIONS = 0x00006822,
320 GUEST_SYSENTER_ESP = 0x00006824,
321 GUEST_SYSENTER_EIP = 0x00006826,
322 HOST_CR0 = 0x00006c00,
323 HOST_CR3 = 0x00006c02,
324 HOST_CR4 = 0x00006c04,
325 HOST_FS_BASE = 0x00006c06,
326 HOST_GS_BASE = 0x00006c08,
327 HOST_TR_BASE = 0x00006c0a,
328 HOST_GDTR_BASE = 0x00006c0c,
329 HOST_IDTR_BASE = 0x00006c0e,
330 HOST_IA32_SYSENTER_ESP = 0x00006c10,
331 HOST_IA32_SYSENTER_EIP = 0x00006c12,
332 HOST_RSP = 0x00006c14,
333 HOST_RIP = 0x00006c16,
334};
335
336struct vmx_msr_entry {
337 uint32_t index;
338 uint32_t reserved;
339 uint64_t value;
340} __attribute__ ((aligned(16)));
341
342static inline int vmxon(uint64_t phys)
343{
344 uint8_t ret;
345
346 __asm__ __volatile__ ("vmxon %[pa]; setna %[ret]"
347 : [ret]"=rm"(ret)
348 : [pa]"m"(phys)
349 : "cc", "memory");
350
351 return ret;
352}
353
354static inline void vmxoff(void)
355{
356 __asm__ __volatile__("vmxoff");
357}
358
359static inline int vmclear(uint64_t vmcs_pa)
360{
361 uint8_t ret;
362
363 __asm__ __volatile__ ("vmclear %[pa]; setna %[ret]"
364 : [ret]"=rm"(ret)
365 : [pa]"m"(vmcs_pa)
366 : "cc", "memory");
367
368 return ret;
369}
370
371static inline int vmptrld(uint64_t vmcs_pa)
372{
373 uint8_t ret;
374
375 __asm__ __volatile__ ("vmptrld %[pa]; setna %[ret]"
376 : [ret]"=rm"(ret)
377 : [pa]"m"(vmcs_pa)
378 : "cc", "memory");
379
380 return ret;
381}
382
383/*
384 * No guest state (e.g. GPRs) is established by this vmlaunch.
385 */
386static inline int vmlaunch(void)
387{
388 int ret;
389
390 __asm__ __volatile__("push %%rbp;"
391 "push %%rcx;"
392 "push %%rdx;"
393 "push %%rsi;"
394 "push %%rdi;"
395 "push $0;"
396 "vmwrite %%rsp, %[host_rsp];"
397 "lea 1f(%%rip), %%rax;"
398 "vmwrite %%rax, %[host_rip];"
399 "vmlaunch;"
400 "incq (%%rsp);"
401 "1: pop %%rax;"
402 "pop %%rdi;"
403 "pop %%rsi;"
404 "pop %%rdx;"
405 "pop %%rcx;"
406 "pop %%rbp;"
407 : [ret]"=&a"(ret)
408 : [host_rsp]"r"((uint64_t)HOST_RSP),
409 [host_rip]"r"((uint64_t)HOST_RIP)
410 : "memory", "cc", "rbx", "r8", "r9", "r10",
411 "r11", "r12", "r13", "r14", "r15");
412 return ret;
413}
414
415/*
416 * No guest state (e.g. GPRs) is established by this vmresume.
417 */
418static inline int vmresume(void)
419{
420 int ret;
421
422 __asm__ __volatile__("push %%rbp;"
423 "push %%rcx;"
424 "push %%rdx;"
425 "push %%rsi;"
426 "push %%rdi;"
427 "push $0;"
428 "vmwrite %%rsp, %[host_rsp];"
429 "lea 1f(%%rip), %%rax;"
430 "vmwrite %%rax, %[host_rip];"
431 "vmresume;"
432 "incq (%%rsp);"
433 "1: pop %%rax;"
434 "pop %%rdi;"
435 "pop %%rsi;"
436 "pop %%rdx;"
437 "pop %%rcx;"
438 "pop %%rbp;"
439 : [ret]"=&a"(ret)
440 : [host_rsp]"r"((uint64_t)HOST_RSP),
441 [host_rip]"r"((uint64_t)HOST_RIP)
442 : "memory", "cc", "rbx", "r8", "r9", "r10",
443 "r11", "r12", "r13", "r14", "r15");
444 return ret;
445}
446
447static inline int vmread(uint64_t encoding, uint64_t *value)
448{
449 uint64_t tmp;
450 uint8_t ret;
451
452 __asm__ __volatile__("vmread %[encoding], %[value]; setna %[ret]"
453 : [value]"=rm"(tmp), [ret]"=rm"(ret)
454 : [encoding]"r"(encoding)
455 : "cc", "memory");
456
457 *value = tmp;
458 return ret;
459}
460
461/*
462 * A wrapper around vmread that ignores errors and returns zero if the
463 * vmread instruction fails.
464 */
465static inline uint64_t vmreadz(uint64_t encoding)
466{
467 uint64_t value = 0;
468 vmread(encoding, &value);
469 return value;
470}
471
472static inline int vmwrite(uint64_t encoding, uint64_t value)
473{
474 uint8_t ret;
475
476 __asm__ __volatile__ ("vmwrite %[value], %[encoding]; setna %[ret]"
477 : [ret]"=rm"(ret)
478 : [value]"rm"(value), [encoding]"r"(encoding)
479 : "cc", "memory");
480
481 return ret;
482}
483
484static inline uint32_t vmcs_revision(void)
485{
486 return rdmsr(MSR_IA32_VMX_BASIC);
487}
488
489void prepare_for_vmx_operation(void);
490void prepare_vmcs(void *guest_rip, void *guest_rsp);
491struct kvm_vm *vm_create_default_vmx(uint32_t vcpuid,
492 vmx_guest_code_t guest_code);
493
494#endif /* !SELFTEST_KVM_VMX_H */
diff --git a/tools/testing/selftests/kvm/include/x86.h b/tools/testing/selftests/kvm/include/x86.h
new file mode 100644
index 000000000000..4a5b2c4c1a0f
--- /dev/null
+++ b/tools/testing/selftests/kvm/include/x86.h
@@ -0,0 +1,1043 @@
1/*
2 * tools/testing/selftests/kvm/include/x86.h
3 *
4 * Copyright (C) 2018, Google LLC.
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2.
7 *
8 */
9
10#ifndef SELFTEST_KVM_X86_H
11#define SELFTEST_KVM_X86_H
12
13#include <assert.h>
14#include <stdint.h>
15
16#define X86_EFLAGS_FIXED (1u << 1)
17
18#define X86_CR4_VME (1ul << 0)
19#define X86_CR4_PVI (1ul << 1)
20#define X86_CR4_TSD (1ul << 2)
21#define X86_CR4_DE (1ul << 3)
22#define X86_CR4_PSE (1ul << 4)
23#define X86_CR4_PAE (1ul << 5)
24#define X86_CR4_MCE (1ul << 6)
25#define X86_CR4_PGE (1ul << 7)
26#define X86_CR4_PCE (1ul << 8)
27#define X86_CR4_OSFXSR (1ul << 9)
28#define X86_CR4_OSXMMEXCPT (1ul << 10)
29#define X86_CR4_UMIP (1ul << 11)
30#define X86_CR4_VMXE (1ul << 13)
31#define X86_CR4_SMXE (1ul << 14)
32#define X86_CR4_FSGSBASE (1ul << 16)
33#define X86_CR4_PCIDE (1ul << 17)
34#define X86_CR4_OSXSAVE (1ul << 18)
35#define X86_CR4_SMEP (1ul << 20)
36#define X86_CR4_SMAP (1ul << 21)
37#define X86_CR4_PKE (1ul << 22)
38
39/* The enum values match the intruction encoding of each register */
40enum x86_register {
41 RAX = 0,
42 RCX,
43 RDX,
44 RBX,
45 RSP,
46 RBP,
47 RSI,
48 RDI,
49 R8,
50 R9,
51 R10,
52 R11,
53 R12,
54 R13,
55 R14,
56 R15,
57};
58
59struct desc64 {
60 uint16_t limit0;
61 uint16_t base0;
62 unsigned base1:8, type:5, dpl:2, p:1;
63 unsigned limit1:4, zero0:3, g:1, base2:8;
64 uint32_t base3;
65 uint32_t zero1;
66} __attribute__((packed));
67
68struct desc_ptr {
69 uint16_t size;
70 uint64_t address;
71} __attribute__((packed));
72
73static inline uint64_t get_desc64_base(const struct desc64 *desc)
74{
75 return ((uint64_t)desc->base3 << 32) |
76 (desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24));
77}
78
79static inline uint64_t rdtsc(void)
80{
81 uint32_t eax, edx;
82
83 /*
84 * The lfence is to wait (on Intel CPUs) until all previous
85 * instructions have been executed.
86 */
87 __asm__ __volatile__("lfence; rdtsc" : "=a"(eax), "=d"(edx));
88 return ((uint64_t)edx) << 32 | eax;
89}
90
91static inline uint64_t rdtscp(uint32_t *aux)
92{
93 uint32_t eax, edx;
94
95 __asm__ __volatile__("rdtscp" : "=a"(eax), "=d"(edx), "=c"(*aux));
96 return ((uint64_t)edx) << 32 | eax;
97}
98
99static inline uint64_t rdmsr(uint32_t msr)
100{
101 uint32_t a, d;
102
103 __asm__ __volatile__("rdmsr" : "=a"(a), "=d"(d) : "c"(msr) : "memory");
104
105 return a | ((uint64_t) d << 32);
106}
107
108static inline void wrmsr(uint32_t msr, uint64_t value)
109{
110 uint32_t a = value;
111 uint32_t d = value >> 32;
112
113 __asm__ __volatile__("wrmsr" :: "a"(a), "d"(d), "c"(msr) : "memory");
114}
115
116
117static inline uint16_t inw(uint16_t port)
118{
119 uint16_t tmp;
120
121 __asm__ __volatile__("in %%dx, %%ax"
122 : /* output */ "=a" (tmp)
123 : /* input */ "d" (port));
124
125 return tmp;
126}
127
128static inline uint16_t get_es(void)
129{
130 uint16_t es;
131
132 __asm__ __volatile__("mov %%es, %[es]"
133 : /* output */ [es]"=rm"(es));
134 return es;
135}
136
137static inline uint16_t get_cs(void)
138{
139 uint16_t cs;
140
141 __asm__ __volatile__("mov %%cs, %[cs]"
142 : /* output */ [cs]"=rm"(cs));
143 return cs;
144}
145
146static inline uint16_t get_ss(void)
147{
148 uint16_t ss;
149
150 __asm__ __volatile__("mov %%ss, %[ss]"
151 : /* output */ [ss]"=rm"(ss));
152 return ss;
153}
154
155static inline uint16_t get_ds(void)
156{
157 uint16_t ds;
158
159 __asm__ __volatile__("mov %%ds, %[ds]"
160 : /* output */ [ds]"=rm"(ds));
161 return ds;
162}
163
164static inline uint16_t get_fs(void)
165{
166 uint16_t fs;
167
168 __asm__ __volatile__("mov %%fs, %[fs]"
169 : /* output */ [fs]"=rm"(fs));
170 return fs;
171}
172
173static inline uint16_t get_gs(void)
174{
175 uint16_t gs;
176
177 __asm__ __volatile__("mov %%gs, %[gs]"
178 : /* output */ [gs]"=rm"(gs));
179 return gs;
180}
181
182static inline uint16_t get_tr(void)
183{
184 uint16_t tr;
185
186 __asm__ __volatile__("str %[tr]"
187 : /* output */ [tr]"=rm"(tr));
188 return tr;
189}
190
191static inline uint64_t get_cr0(void)
192{
193 uint64_t cr0;
194
195 __asm__ __volatile__("mov %%cr0, %[cr0]"
196 : /* output */ [cr0]"=r"(cr0));
197 return cr0;
198}
199
200static inline uint64_t get_cr3(void)
201{
202 uint64_t cr3;
203
204 __asm__ __volatile__("mov %%cr3, %[cr3]"
205 : /* output */ [cr3]"=r"(cr3));
206 return cr3;
207}
208
209static inline uint64_t get_cr4(void)
210{
211 uint64_t cr4;
212
213 __asm__ __volatile__("mov %%cr4, %[cr4]"
214 : /* output */ [cr4]"=r"(cr4));
215 return cr4;
216}
217
218static inline void set_cr4(uint64_t val)
219{
220 __asm__ __volatile__("mov %0, %%cr4" : : "r" (val) : "memory");
221}
222
223static inline uint64_t get_gdt_base(void)
224{
225 struct desc_ptr gdt;
226 __asm__ __volatile__("sgdt %[gdt]"
227 : /* output */ [gdt]"=m"(gdt));
228 return gdt.address;
229}
230
231static inline uint64_t get_idt_base(void)
232{
233 struct desc_ptr idt;
234 __asm__ __volatile__("sidt %[idt]"
235 : /* output */ [idt]"=m"(idt));
236 return idt.address;
237}
238
239#define SET_XMM(__var, __xmm) \
240 asm volatile("movq %0, %%"#__xmm : : "r"(__var) : #__xmm)
241
242static inline void set_xmm(int n, unsigned long val)
243{
244 switch (n) {
245 case 0:
246 SET_XMM(val, xmm0);
247 break;
248 case 1:
249 SET_XMM(val, xmm1);
250 break;
251 case 2:
252 SET_XMM(val, xmm2);
253 break;
254 case 3:
255 SET_XMM(val, xmm3);
256 break;
257 case 4:
258 SET_XMM(val, xmm4);
259 break;
260 case 5:
261 SET_XMM(val, xmm5);
262 break;
263 case 6:
264 SET_XMM(val, xmm6);
265 break;
266 case 7:
267 SET_XMM(val, xmm7);
268 break;
269 }
270}
271
272typedef unsigned long v1di __attribute__ ((vector_size (8)));
273static inline unsigned long get_xmm(int n)
274{
275 assert(n >= 0 && n <= 7);
276
277 register v1di xmm0 __asm__("%xmm0");
278 register v1di xmm1 __asm__("%xmm1");
279 register v1di xmm2 __asm__("%xmm2");
280 register v1di xmm3 __asm__("%xmm3");
281 register v1di xmm4 __asm__("%xmm4");
282 register v1di xmm5 __asm__("%xmm5");
283 register v1di xmm6 __asm__("%xmm6");
284 register v1di xmm7 __asm__("%xmm7");
285 switch (n) {
286 case 0:
287 return (unsigned long)xmm0;
288 case 1:
289 return (unsigned long)xmm1;
290 case 2:
291 return (unsigned long)xmm2;
292 case 3:
293 return (unsigned long)xmm3;
294 case 4:
295 return (unsigned long)xmm4;
296 case 5:
297 return (unsigned long)xmm5;
298 case 6:
299 return (unsigned long)xmm6;
300 case 7:
301 return (unsigned long)xmm7;
302 }
303 return 0;
304}
305
306/*
307 * Basic CPU control in CR0
308 */
309#define X86_CR0_PE (1UL<<0) /* Protection Enable */
310#define X86_CR0_MP (1UL<<1) /* Monitor Coprocessor */
311#define X86_CR0_EM (1UL<<2) /* Emulation */
312#define X86_CR0_TS (1UL<<3) /* Task Switched */
313#define X86_CR0_ET (1UL<<4) /* Extension Type */
314#define X86_CR0_NE (1UL<<5) /* Numeric Error */
315#define X86_CR0_WP (1UL<<16) /* Write Protect */
316#define X86_CR0_AM (1UL<<18) /* Alignment Mask */
317#define X86_CR0_NW (1UL<<29) /* Not Write-through */
318#define X86_CR0_CD (1UL<<30) /* Cache Disable */
319#define X86_CR0_PG (1UL<<31) /* Paging */
320
321/*
322 * CPU model specific register (MSR) numbers.
323 */
324
325/* x86-64 specific MSRs */
326#define MSR_EFER 0xc0000080 /* extended feature register */
327#define MSR_STAR 0xc0000081 /* legacy mode SYSCALL target */
328#define MSR_LSTAR 0xc0000082 /* long mode SYSCALL target */
329#define MSR_CSTAR 0xc0000083 /* compat mode SYSCALL target */
330#define MSR_SYSCALL_MASK 0xc0000084 /* EFLAGS mask for syscall */
331#define MSR_FS_BASE 0xc0000100 /* 64bit FS base */
332#define MSR_GS_BASE 0xc0000101 /* 64bit GS base */
333#define MSR_KERNEL_GS_BASE 0xc0000102 /* SwapGS GS shadow */
334#define MSR_TSC_AUX 0xc0000103 /* Auxiliary TSC */
335
336/* EFER bits: */
337#define EFER_SCE (1<<0) /* SYSCALL/SYSRET */
338#define EFER_LME (1<<8) /* Long mode enable */
339#define EFER_LMA (1<<10) /* Long mode active (read-only) */
340#define EFER_NX (1<<11) /* No execute enable */
341#define EFER_SVME (1<<12) /* Enable virtualization */
342#define EFER_LMSLE (1<<13) /* Long Mode Segment Limit Enable */
343#define EFER_FFXSR (1<<14) /* Enable Fast FXSAVE/FXRSTOR */
344
345/* Intel MSRs. Some also available on other CPUs */
346
347#define MSR_PPIN_CTL 0x0000004e
348#define MSR_PPIN 0x0000004f
349
350#define MSR_IA32_PERFCTR0 0x000000c1
351#define MSR_IA32_PERFCTR1 0x000000c2
352#define MSR_FSB_FREQ 0x000000cd
353#define MSR_PLATFORM_INFO 0x000000ce
354#define MSR_PLATFORM_INFO_CPUID_FAULT_BIT 31
355#define MSR_PLATFORM_INFO_CPUID_FAULT BIT_ULL(MSR_PLATFORM_INFO_CPUID_FAULT_BIT)
356
357#define MSR_PKG_CST_CONFIG_CONTROL 0x000000e2
358#define NHM_C3_AUTO_DEMOTE (1UL << 25)
359#define NHM_C1_AUTO_DEMOTE (1UL << 26)
360#define ATM_LNC_C6_AUTO_DEMOTE (1UL << 25)
361#define SNB_C1_AUTO_UNDEMOTE (1UL << 27)
362#define SNB_C3_AUTO_UNDEMOTE (1UL << 28)
363
364#define MSR_MTRRcap 0x000000fe
365#define MSR_IA32_BBL_CR_CTL 0x00000119
366#define MSR_IA32_BBL_CR_CTL3 0x0000011e
367
368#define MSR_IA32_SYSENTER_CS 0x00000174
369#define MSR_IA32_SYSENTER_ESP 0x00000175
370#define MSR_IA32_SYSENTER_EIP 0x00000176
371
372#define MSR_IA32_MCG_CAP 0x00000179
373#define MSR_IA32_MCG_STATUS 0x0000017a
374#define MSR_IA32_MCG_CTL 0x0000017b
375#define MSR_IA32_MCG_EXT_CTL 0x000004d0
376
377#define MSR_OFFCORE_RSP_0 0x000001a6
378#define MSR_OFFCORE_RSP_1 0x000001a7
379#define MSR_TURBO_RATIO_LIMIT 0x000001ad
380#define MSR_TURBO_RATIO_LIMIT1 0x000001ae
381#define MSR_TURBO_RATIO_LIMIT2 0x000001af
382
383#define MSR_LBR_SELECT 0x000001c8
384#define MSR_LBR_TOS 0x000001c9
385#define MSR_LBR_NHM_FROM 0x00000680
386#define MSR_LBR_NHM_TO 0x000006c0
387#define MSR_LBR_CORE_FROM 0x00000040
388#define MSR_LBR_CORE_TO 0x00000060
389
390#define MSR_LBR_INFO_0 0x00000dc0 /* ... 0xddf for _31 */
391#define LBR_INFO_MISPRED BIT_ULL(63)
392#define LBR_INFO_IN_TX BIT_ULL(62)
393#define LBR_INFO_ABORT BIT_ULL(61)
394#define LBR_INFO_CYCLES 0xffff
395
396#define MSR_IA32_PEBS_ENABLE 0x000003f1
397#define MSR_IA32_DS_AREA 0x00000600
398#define MSR_IA32_PERF_CAPABILITIES 0x00000345
399#define MSR_PEBS_LD_LAT_THRESHOLD 0x000003f6
400
401#define MSR_IA32_RTIT_CTL 0x00000570
402#define MSR_IA32_RTIT_STATUS 0x00000571
403#define MSR_IA32_RTIT_ADDR0_A 0x00000580
404#define MSR_IA32_RTIT_ADDR0_B 0x00000581
405#define MSR_IA32_RTIT_ADDR1_A 0x00000582
406#define MSR_IA32_RTIT_ADDR1_B 0x00000583
407#define MSR_IA32_RTIT_ADDR2_A 0x00000584
408#define MSR_IA32_RTIT_ADDR2_B 0x00000585
409#define MSR_IA32_RTIT_ADDR3_A 0x00000586
410#define MSR_IA32_RTIT_ADDR3_B 0x00000587
411#define MSR_IA32_RTIT_CR3_MATCH 0x00000572
412#define MSR_IA32_RTIT_OUTPUT_BASE 0x00000560
413#define MSR_IA32_RTIT_OUTPUT_MASK 0x00000561
414
415#define MSR_MTRRfix64K_00000 0x00000250
416#define MSR_MTRRfix16K_80000 0x00000258
417#define MSR_MTRRfix16K_A0000 0x00000259
418#define MSR_MTRRfix4K_C0000 0x00000268
419#define MSR_MTRRfix4K_C8000 0x00000269
420#define MSR_MTRRfix4K_D0000 0x0000026a
421#define MSR_MTRRfix4K_D8000 0x0000026b
422#define MSR_MTRRfix4K_E0000 0x0000026c
423#define MSR_MTRRfix4K_E8000 0x0000026d
424#define MSR_MTRRfix4K_F0000 0x0000026e
425#define MSR_MTRRfix4K_F8000 0x0000026f
426#define MSR_MTRRdefType 0x000002ff
427
428#define MSR_IA32_CR_PAT 0x00000277
429
430#define MSR_IA32_DEBUGCTLMSR 0x000001d9
431#define MSR_IA32_LASTBRANCHFROMIP 0x000001db
432#define MSR_IA32_LASTBRANCHTOIP 0x000001dc
433#define MSR_IA32_LASTINTFROMIP 0x000001dd
434#define MSR_IA32_LASTINTTOIP 0x000001de
435
436/* DEBUGCTLMSR bits (others vary by model): */
437#define DEBUGCTLMSR_LBR (1UL << 0) /* last branch recording */
438#define DEBUGCTLMSR_BTF_SHIFT 1
439#define DEBUGCTLMSR_BTF (1UL << 1) /* single-step on branches */
440#define DEBUGCTLMSR_TR (1UL << 6)
441#define DEBUGCTLMSR_BTS (1UL << 7)
442#define DEBUGCTLMSR_BTINT (1UL << 8)
443#define DEBUGCTLMSR_BTS_OFF_OS (1UL << 9)
444#define DEBUGCTLMSR_BTS_OFF_USR (1UL << 10)
445#define DEBUGCTLMSR_FREEZE_LBRS_ON_PMI (1UL << 11)
446#define DEBUGCTLMSR_FREEZE_IN_SMM_BIT 14
447#define DEBUGCTLMSR_FREEZE_IN_SMM (1UL << DEBUGCTLMSR_FREEZE_IN_SMM_BIT)
448
449#define MSR_PEBS_FRONTEND 0x000003f7
450
451#define MSR_IA32_POWER_CTL 0x000001fc
452
453#define MSR_IA32_MC0_CTL 0x00000400
454#define MSR_IA32_MC0_STATUS 0x00000401
455#define MSR_IA32_MC0_ADDR 0x00000402
456#define MSR_IA32_MC0_MISC 0x00000403
457
458/* C-state Residency Counters */
459#define MSR_PKG_C3_RESIDENCY 0x000003f8
460#define MSR_PKG_C6_RESIDENCY 0x000003f9
461#define MSR_ATOM_PKG_C6_RESIDENCY 0x000003fa
462#define MSR_PKG_C7_RESIDENCY 0x000003fa
463#define MSR_CORE_C3_RESIDENCY 0x000003fc
464#define MSR_CORE_C6_RESIDENCY 0x000003fd
465#define MSR_CORE_C7_RESIDENCY 0x000003fe
466#define MSR_KNL_CORE_C6_RESIDENCY 0x000003ff
467#define MSR_PKG_C2_RESIDENCY 0x0000060d
468#define MSR_PKG_C8_RESIDENCY 0x00000630
469#define MSR_PKG_C9_RESIDENCY 0x00000631
470#define MSR_PKG_C10_RESIDENCY 0x00000632
471
472/* Interrupt Response Limit */
473#define MSR_PKGC3_IRTL 0x0000060a
474#define MSR_PKGC6_IRTL 0x0000060b
475#define MSR_PKGC7_IRTL 0x0000060c
476#define MSR_PKGC8_IRTL 0x00000633
477#define MSR_PKGC9_IRTL 0x00000634
478#define MSR_PKGC10_IRTL 0x00000635
479
480/* Run Time Average Power Limiting (RAPL) Interface */
481
482#define MSR_RAPL_POWER_UNIT 0x00000606
483
484#define MSR_PKG_POWER_LIMIT 0x00000610
485#define MSR_PKG_ENERGY_STATUS 0x00000611
486#define MSR_PKG_PERF_STATUS 0x00000613
487#define MSR_PKG_POWER_INFO 0x00000614
488
489#define MSR_DRAM_POWER_LIMIT 0x00000618
490#define MSR_DRAM_ENERGY_STATUS 0x00000619
491#define MSR_DRAM_PERF_STATUS 0x0000061b
492#define MSR_DRAM_POWER_INFO 0x0000061c
493
494#define MSR_PP0_POWER_LIMIT 0x00000638
495#define MSR_PP0_ENERGY_STATUS 0x00000639
496#define MSR_PP0_POLICY 0x0000063a
497#define MSR_PP0_PERF_STATUS 0x0000063b
498
499#define MSR_PP1_POWER_LIMIT 0x00000640
500#define MSR_PP1_ENERGY_STATUS 0x00000641
501#define MSR_PP1_POLICY 0x00000642
502
503/* Config TDP MSRs */
504#define MSR_CONFIG_TDP_NOMINAL 0x00000648
505#define MSR_CONFIG_TDP_LEVEL_1 0x00000649
506#define MSR_CONFIG_TDP_LEVEL_2 0x0000064A
507#define MSR_CONFIG_TDP_CONTROL 0x0000064B
508#define MSR_TURBO_ACTIVATION_RATIO 0x0000064C
509
510#define MSR_PLATFORM_ENERGY_STATUS 0x0000064D
511
512#define MSR_PKG_WEIGHTED_CORE_C0_RES 0x00000658
513#define MSR_PKG_ANY_CORE_C0_RES 0x00000659
514#define MSR_PKG_ANY_GFXE_C0_RES 0x0000065A
515#define MSR_PKG_BOTH_CORE_GFXE_C0_RES 0x0000065B
516
517#define MSR_CORE_C1_RES 0x00000660
518#define MSR_MODULE_C6_RES_MS 0x00000664
519
520#define MSR_CC6_DEMOTION_POLICY_CONFIG 0x00000668
521#define MSR_MC6_DEMOTION_POLICY_CONFIG 0x00000669
522
523#define MSR_ATOM_CORE_RATIOS 0x0000066a
524#define MSR_ATOM_CORE_VIDS 0x0000066b
525#define MSR_ATOM_CORE_TURBO_RATIOS 0x0000066c
526#define MSR_ATOM_CORE_TURBO_VIDS 0x0000066d
527
528
529#define MSR_CORE_PERF_LIMIT_REASONS 0x00000690
530#define MSR_GFX_PERF_LIMIT_REASONS 0x000006B0
531#define MSR_RING_PERF_LIMIT_REASONS 0x000006B1
532
533/* Hardware P state interface */
534#define MSR_PPERF 0x0000064e
535#define MSR_PERF_LIMIT_REASONS 0x0000064f
536#define MSR_PM_ENABLE 0x00000770
537#define MSR_HWP_CAPABILITIES 0x00000771
538#define MSR_HWP_REQUEST_PKG 0x00000772
539#define MSR_HWP_INTERRUPT 0x00000773
540#define MSR_HWP_REQUEST 0x00000774
541#define MSR_HWP_STATUS 0x00000777
542
543/* CPUID.6.EAX */
544#define HWP_BASE_BIT (1<<7)
545#define HWP_NOTIFICATIONS_BIT (1<<8)
546#define HWP_ACTIVITY_WINDOW_BIT (1<<9)
547#define HWP_ENERGY_PERF_PREFERENCE_BIT (1<<10)
548#define HWP_PACKAGE_LEVEL_REQUEST_BIT (1<<11)
549
550/* IA32_HWP_CAPABILITIES */
551#define HWP_HIGHEST_PERF(x) (((x) >> 0) & 0xff)
552#define HWP_GUARANTEED_PERF(x) (((x) >> 8) & 0xff)
553#define HWP_MOSTEFFICIENT_PERF(x) (((x) >> 16) & 0xff)
554#define HWP_LOWEST_PERF(x) (((x) >> 24) & 0xff)
555
556/* IA32_HWP_REQUEST */
557#define HWP_MIN_PERF(x) (x & 0xff)
558#define HWP_MAX_PERF(x) ((x & 0xff) << 8)
559#define HWP_DESIRED_PERF(x) ((x & 0xff) << 16)
560#define HWP_ENERGY_PERF_PREFERENCE(x) (((unsigned long long) x & 0xff) << 24)
561#define HWP_EPP_PERFORMANCE 0x00
562#define HWP_EPP_BALANCE_PERFORMANCE 0x80
563#define HWP_EPP_BALANCE_POWERSAVE 0xC0
564#define HWP_EPP_POWERSAVE 0xFF
565#define HWP_ACTIVITY_WINDOW(x) ((unsigned long long)(x & 0xff3) << 32)
566#define HWP_PACKAGE_CONTROL(x) ((unsigned long long)(x & 0x1) << 42)
567
568/* IA32_HWP_STATUS */
569#define HWP_GUARANTEED_CHANGE(x) (x & 0x1)
570#define HWP_EXCURSION_TO_MINIMUM(x) (x & 0x4)
571
572/* IA32_HWP_INTERRUPT */
573#define HWP_CHANGE_TO_GUARANTEED_INT(x) (x & 0x1)
574#define HWP_EXCURSION_TO_MINIMUM_INT(x) (x & 0x2)
575
576#define MSR_AMD64_MC0_MASK 0xc0010044
577
578#define MSR_IA32_MCx_CTL(x) (MSR_IA32_MC0_CTL + 4*(x))
579#define MSR_IA32_MCx_STATUS(x) (MSR_IA32_MC0_STATUS + 4*(x))
580#define MSR_IA32_MCx_ADDR(x) (MSR_IA32_MC0_ADDR + 4*(x))
581#define MSR_IA32_MCx_MISC(x) (MSR_IA32_MC0_MISC + 4*(x))
582
583#define MSR_AMD64_MCx_MASK(x) (MSR_AMD64_MC0_MASK + (x))
584
585/* These are consecutive and not in the normal 4er MCE bank block */
586#define MSR_IA32_MC0_CTL2 0x00000280
587#define MSR_IA32_MCx_CTL2(x) (MSR_IA32_MC0_CTL2 + (x))
588
589#define MSR_P6_PERFCTR0 0x000000c1
590#define MSR_P6_PERFCTR1 0x000000c2
591#define MSR_P6_EVNTSEL0 0x00000186
592#define MSR_P6_EVNTSEL1 0x00000187
593
594#define MSR_KNC_PERFCTR0 0x00000020
595#define MSR_KNC_PERFCTR1 0x00000021
596#define MSR_KNC_EVNTSEL0 0x00000028
597#define MSR_KNC_EVNTSEL1 0x00000029
598
599/* Alternative perfctr range with full access. */
600#define MSR_IA32_PMC0 0x000004c1
601
602/* AMD64 MSRs. Not complete. See the architecture manual for a more
603 complete list. */
604
605#define MSR_AMD64_PATCH_LEVEL 0x0000008b
606#define MSR_AMD64_TSC_RATIO 0xc0000104
607#define MSR_AMD64_NB_CFG 0xc001001f
608#define MSR_AMD64_PATCH_LOADER 0xc0010020
609#define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140
610#define MSR_AMD64_OSVW_STATUS 0xc0010141
611#define MSR_AMD64_LS_CFG 0xc0011020
612#define MSR_AMD64_DC_CFG 0xc0011022
613#define MSR_AMD64_BU_CFG2 0xc001102a
614#define MSR_AMD64_IBSFETCHCTL 0xc0011030
615#define MSR_AMD64_IBSFETCHLINAD 0xc0011031
616#define MSR_AMD64_IBSFETCHPHYSAD 0xc0011032
617#define MSR_AMD64_IBSFETCH_REG_COUNT 3
618#define MSR_AMD64_IBSFETCH_REG_MASK ((1UL<<MSR_AMD64_IBSFETCH_REG_COUNT)-1)
619#define MSR_AMD64_IBSOPCTL 0xc0011033
620#define MSR_AMD64_IBSOPRIP 0xc0011034
621#define MSR_AMD64_IBSOPDATA 0xc0011035
622#define MSR_AMD64_IBSOPDATA2 0xc0011036
623#define MSR_AMD64_IBSOPDATA3 0xc0011037
624#define MSR_AMD64_IBSDCLINAD 0xc0011038
625#define MSR_AMD64_IBSDCPHYSAD 0xc0011039
626#define MSR_AMD64_IBSOP_REG_COUNT 7
627#define MSR_AMD64_IBSOP_REG_MASK ((1UL<<MSR_AMD64_IBSOP_REG_COUNT)-1)
628#define MSR_AMD64_IBSCTL 0xc001103a
629#define MSR_AMD64_IBSBRTARGET 0xc001103b
630#define MSR_AMD64_IBSOPDATA4 0xc001103d
631#define MSR_AMD64_IBS_REG_COUNT_MAX 8 /* includes MSR_AMD64_IBSBRTARGET */
632#define MSR_AMD64_SEV 0xc0010131
633#define MSR_AMD64_SEV_ENABLED_BIT 0
634#define MSR_AMD64_SEV_ENABLED BIT_ULL(MSR_AMD64_SEV_ENABLED_BIT)
635
636/* Fam 17h MSRs */
637#define MSR_F17H_IRPERF 0xc00000e9
638
639/* Fam 16h MSRs */
640#define MSR_F16H_L2I_PERF_CTL 0xc0010230
641#define MSR_F16H_L2I_PERF_CTR 0xc0010231
642#define MSR_F16H_DR1_ADDR_MASK 0xc0011019
643#define MSR_F16H_DR2_ADDR_MASK 0xc001101a
644#define MSR_F16H_DR3_ADDR_MASK 0xc001101b
645#define MSR_F16H_DR0_ADDR_MASK 0xc0011027
646
647/* Fam 15h MSRs */
648#define MSR_F15H_PERF_CTL 0xc0010200
649#define MSR_F15H_PERF_CTR 0xc0010201
650#define MSR_F15H_NB_PERF_CTL 0xc0010240
651#define MSR_F15H_NB_PERF_CTR 0xc0010241
652#define MSR_F15H_PTSC 0xc0010280
653#define MSR_F15H_IC_CFG 0xc0011021
654
655/* Fam 10h MSRs */
656#define MSR_FAM10H_MMIO_CONF_BASE 0xc0010058
657#define FAM10H_MMIO_CONF_ENABLE (1<<0)
658#define FAM10H_MMIO_CONF_BUSRANGE_MASK 0xf
659#define FAM10H_MMIO_CONF_BUSRANGE_SHIFT 2
660#define FAM10H_MMIO_CONF_BASE_MASK 0xfffffffULL
661#define FAM10H_MMIO_CONF_BASE_SHIFT 20
662#define MSR_FAM10H_NODE_ID 0xc001100c
663#define MSR_F10H_DECFG 0xc0011029
664#define MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT 1
665#define MSR_F10H_DECFG_LFENCE_SERIALIZE BIT_ULL(MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT)
666
667/* K8 MSRs */
668#define MSR_K8_TOP_MEM1 0xc001001a
669#define MSR_K8_TOP_MEM2 0xc001001d
670#define MSR_K8_SYSCFG 0xc0010010
671#define MSR_K8_SYSCFG_MEM_ENCRYPT_BIT 23
672#define MSR_K8_SYSCFG_MEM_ENCRYPT BIT_ULL(MSR_K8_SYSCFG_MEM_ENCRYPT_BIT)
673#define MSR_K8_INT_PENDING_MSG 0xc0010055
674/* C1E active bits in int pending message */
675#define K8_INTP_C1E_ACTIVE_MASK 0x18000000
676#define MSR_K8_TSEG_ADDR 0xc0010112
677#define MSR_K8_TSEG_MASK 0xc0010113
678#define K8_MTRRFIXRANGE_DRAM_ENABLE 0x00040000 /* MtrrFixDramEn bit */
679#define K8_MTRRFIXRANGE_DRAM_MODIFY 0x00080000 /* MtrrFixDramModEn bit */
680#define K8_MTRR_RDMEM_WRMEM_MASK 0x18181818 /* Mask: RdMem|WrMem */
681
682/* K7 MSRs */
683#define MSR_K7_EVNTSEL0 0xc0010000
684#define MSR_K7_PERFCTR0 0xc0010004
685#define MSR_K7_EVNTSEL1 0xc0010001
686#define MSR_K7_PERFCTR1 0xc0010005
687#define MSR_K7_EVNTSEL2 0xc0010002
688#define MSR_K7_PERFCTR2 0xc0010006
689#define MSR_K7_EVNTSEL3 0xc0010003
690#define MSR_K7_PERFCTR3 0xc0010007
691#define MSR_K7_CLK_CTL 0xc001001b
692#define MSR_K7_HWCR 0xc0010015
693#define MSR_K7_HWCR_SMMLOCK_BIT 0
694#define MSR_K7_HWCR_SMMLOCK BIT_ULL(MSR_K7_HWCR_SMMLOCK_BIT)
695#define MSR_K7_FID_VID_CTL 0xc0010041
696#define MSR_K7_FID_VID_STATUS 0xc0010042
697
698/* K6 MSRs */
699#define MSR_K6_WHCR 0xc0000082
700#define MSR_K6_UWCCR 0xc0000085
701#define MSR_K6_EPMR 0xc0000086
702#define MSR_K6_PSOR 0xc0000087
703#define MSR_K6_PFIR 0xc0000088
704
705/* Centaur-Hauls/IDT defined MSRs. */
706#define MSR_IDT_FCR1 0x00000107
707#define MSR_IDT_FCR2 0x00000108
708#define MSR_IDT_FCR3 0x00000109
709#define MSR_IDT_FCR4 0x0000010a
710
711#define MSR_IDT_MCR0 0x00000110
712#define MSR_IDT_MCR1 0x00000111
713#define MSR_IDT_MCR2 0x00000112
714#define MSR_IDT_MCR3 0x00000113
715#define MSR_IDT_MCR4 0x00000114
716#define MSR_IDT_MCR5 0x00000115
717#define MSR_IDT_MCR6 0x00000116
718#define MSR_IDT_MCR7 0x00000117
719#define MSR_IDT_MCR_CTRL 0x00000120
720
721/* VIA Cyrix defined MSRs*/
722#define MSR_VIA_FCR 0x00001107
723#define MSR_VIA_LONGHAUL 0x0000110a
724#define MSR_VIA_RNG 0x0000110b
725#define MSR_VIA_BCR2 0x00001147
726
727/* Transmeta defined MSRs */
728#define MSR_TMTA_LONGRUN_CTRL 0x80868010
729#define MSR_TMTA_LONGRUN_FLAGS 0x80868011
730#define MSR_TMTA_LRTI_READOUT 0x80868018
731#define MSR_TMTA_LRTI_VOLT_MHZ 0x8086801a
732
733/* Intel defined MSRs. */
734#define MSR_IA32_P5_MC_ADDR 0x00000000
735#define MSR_IA32_P5_MC_TYPE 0x00000001
736#define MSR_IA32_TSC 0x00000010
737#define MSR_IA32_PLATFORM_ID 0x00000017
738#define MSR_IA32_EBL_CR_POWERON 0x0000002a
739#define MSR_EBC_FREQUENCY_ID 0x0000002c
740#define MSR_SMI_COUNT 0x00000034
741#define MSR_IA32_FEATURE_CONTROL 0x0000003a
742#define MSR_IA32_TSC_ADJUST 0x0000003b
743#define MSR_IA32_BNDCFGS 0x00000d90
744
745#define MSR_IA32_BNDCFGS_RSVD 0x00000ffc
746
747#define MSR_IA32_XSS 0x00000da0
748
749#define FEATURE_CONTROL_LOCKED (1<<0)
750#define FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX (1<<1)
751#define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX (1<<2)
752#define FEATURE_CONTROL_LMCE (1<<20)
753
754#define MSR_IA32_APICBASE 0x0000001b
755#define MSR_IA32_APICBASE_BSP (1<<8)
756#define MSR_IA32_APICBASE_ENABLE (1<<11)
757#define MSR_IA32_APICBASE_BASE (0xfffff<<12)
758
759#define MSR_IA32_TSCDEADLINE 0x000006e0
760
761#define MSR_IA32_UCODE_WRITE 0x00000079
762#define MSR_IA32_UCODE_REV 0x0000008b
763
764#define MSR_IA32_SMM_MONITOR_CTL 0x0000009b
765#define MSR_IA32_SMBASE 0x0000009e
766
767#define MSR_IA32_PERF_STATUS 0x00000198
768#define MSR_IA32_PERF_CTL 0x00000199
769#define INTEL_PERF_CTL_MASK 0xffff
770#define MSR_AMD_PSTATE_DEF_BASE 0xc0010064
771#define MSR_AMD_PERF_STATUS 0xc0010063
772#define MSR_AMD_PERF_CTL 0xc0010062
773
774#define MSR_IA32_MPERF 0x000000e7
775#define MSR_IA32_APERF 0x000000e8
776
777#define MSR_IA32_THERM_CONTROL 0x0000019a
778#define MSR_IA32_THERM_INTERRUPT 0x0000019b
779
780#define THERM_INT_HIGH_ENABLE (1 << 0)
781#define THERM_INT_LOW_ENABLE (1 << 1)
782#define THERM_INT_PLN_ENABLE (1 << 24)
783
784#define MSR_IA32_THERM_STATUS 0x0000019c
785
786#define THERM_STATUS_PROCHOT (1 << 0)
787#define THERM_STATUS_POWER_LIMIT (1 << 10)
788
789#define MSR_THERM2_CTL 0x0000019d
790
791#define MSR_THERM2_CTL_TM_SELECT (1ULL << 16)
792
793#define MSR_IA32_MISC_ENABLE 0x000001a0
794
795#define MSR_IA32_TEMPERATURE_TARGET 0x000001a2
796
797#define MSR_MISC_FEATURE_CONTROL 0x000001a4
798#define MSR_MISC_PWR_MGMT 0x000001aa
799
800#define MSR_IA32_ENERGY_PERF_BIAS 0x000001b0
801#define ENERGY_PERF_BIAS_PERFORMANCE 0
802#define ENERGY_PERF_BIAS_BALANCE_PERFORMANCE 4
803#define ENERGY_PERF_BIAS_NORMAL 6
804#define ENERGY_PERF_BIAS_BALANCE_POWERSAVE 8
805#define ENERGY_PERF_BIAS_POWERSAVE 15
806
807#define MSR_IA32_PACKAGE_THERM_STATUS 0x000001b1
808
809#define PACKAGE_THERM_STATUS_PROCHOT (1 << 0)
810#define PACKAGE_THERM_STATUS_POWER_LIMIT (1 << 10)
811
812#define MSR_IA32_PACKAGE_THERM_INTERRUPT 0x000001b2
813
814#define PACKAGE_THERM_INT_HIGH_ENABLE (1 << 0)
815#define PACKAGE_THERM_INT_LOW_ENABLE (1 << 1)
816#define PACKAGE_THERM_INT_PLN_ENABLE (1 << 24)
817
818/* Thermal Thresholds Support */
819#define THERM_INT_THRESHOLD0_ENABLE (1 << 15)
820#define THERM_SHIFT_THRESHOLD0 8
821#define THERM_MASK_THRESHOLD0 (0x7f << THERM_SHIFT_THRESHOLD0)
822#define THERM_INT_THRESHOLD1_ENABLE (1 << 23)
823#define THERM_SHIFT_THRESHOLD1 16
824#define THERM_MASK_THRESHOLD1 (0x7f << THERM_SHIFT_THRESHOLD1)
825#define THERM_STATUS_THRESHOLD0 (1 << 6)
826#define THERM_LOG_THRESHOLD0 (1 << 7)
827#define THERM_STATUS_THRESHOLD1 (1 << 8)
828#define THERM_LOG_THRESHOLD1 (1 << 9)
829
830/* MISC_ENABLE bits: architectural */
831#define MSR_IA32_MISC_ENABLE_FAST_STRING_BIT 0
832#define MSR_IA32_MISC_ENABLE_FAST_STRING (1ULL << MSR_IA32_MISC_ENABLE_FAST_STRING_BIT)
833#define MSR_IA32_MISC_ENABLE_TCC_BIT 1
834#define MSR_IA32_MISC_ENABLE_TCC (1ULL << MSR_IA32_MISC_ENABLE_TCC_BIT)
835#define MSR_IA32_MISC_ENABLE_EMON_BIT 7
836#define MSR_IA32_MISC_ENABLE_EMON (1ULL << MSR_IA32_MISC_ENABLE_EMON_BIT)
837#define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL_BIT 11
838#define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL (1ULL << MSR_IA32_MISC_ENABLE_BTS_UNAVAIL_BIT)
839#define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL_BIT 12
840#define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL (1ULL << MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL_BIT)
841#define MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP_BIT 16
842#define MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP (1ULL << MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP_BIT)
843#define MSR_IA32_MISC_ENABLE_MWAIT_BIT 18
844#define MSR_IA32_MISC_ENABLE_MWAIT (1ULL << MSR_IA32_MISC_ENABLE_MWAIT_BIT)
845#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT 22
846#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID (1ULL << MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT)
847#define MSR_IA32_MISC_ENABLE_XTPR_DISABLE_BIT 23
848#define MSR_IA32_MISC_ENABLE_XTPR_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_XTPR_DISABLE_BIT)
849#define MSR_IA32_MISC_ENABLE_XD_DISABLE_BIT 34
850#define MSR_IA32_MISC_ENABLE_XD_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_XD_DISABLE_BIT)
851
852/* MISC_ENABLE bits: model-specific, meaning may vary from core to core */
853#define MSR_IA32_MISC_ENABLE_X87_COMPAT_BIT 2
854#define MSR_IA32_MISC_ENABLE_X87_COMPAT (1ULL << MSR_IA32_MISC_ENABLE_X87_COMPAT_BIT)
855#define MSR_IA32_MISC_ENABLE_TM1_BIT 3
856#define MSR_IA32_MISC_ENABLE_TM1 (1ULL << MSR_IA32_MISC_ENABLE_TM1_BIT)
857#define MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE_BIT 4
858#define MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE_BIT)
859#define MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE_BIT 6
860#define MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE_BIT)
861#define MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK_BIT 8
862#define MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK (1ULL << MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK_BIT)
863#define MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE_BIT 9
864#define MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE_BIT)
865#define MSR_IA32_MISC_ENABLE_FERR_BIT 10
866#define MSR_IA32_MISC_ENABLE_FERR (1ULL << MSR_IA32_MISC_ENABLE_FERR_BIT)
867#define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX_BIT 10
868#define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX (1ULL << MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX_BIT)
869#define MSR_IA32_MISC_ENABLE_TM2_BIT 13
870#define MSR_IA32_MISC_ENABLE_TM2 (1ULL << MSR_IA32_MISC_ENABLE_TM2_BIT)
871#define MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE_BIT 19
872#define MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE_BIT)
873#define MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK_BIT 20
874#define MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK (1ULL << MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK_BIT)
875#define MSR_IA32_MISC_ENABLE_L1D_CONTEXT_BIT 24
876#define MSR_IA32_MISC_ENABLE_L1D_CONTEXT (1ULL << MSR_IA32_MISC_ENABLE_L1D_CONTEXT_BIT)
877#define MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE_BIT 37
878#define MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE_BIT)
879#define MSR_IA32_MISC_ENABLE_TURBO_DISABLE_BIT 38
880#define MSR_IA32_MISC_ENABLE_TURBO_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_TURBO_DISABLE_BIT)
881#define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE_BIT 39
882#define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE_BIT)
883
884/* MISC_FEATURES_ENABLES non-architectural features */
885#define MSR_MISC_FEATURES_ENABLES 0x00000140
886
887#define MSR_MISC_FEATURES_ENABLES_CPUID_FAULT_BIT 0
888#define MSR_MISC_FEATURES_ENABLES_CPUID_FAULT BIT_ULL(MSR_MISC_FEATURES_ENABLES_CPUID_FAULT_BIT)
889#define MSR_MISC_FEATURES_ENABLES_RING3MWAIT_BIT 1
890
891#define MSR_IA32_TSC_DEADLINE 0x000006E0
892
893/* P4/Xeon+ specific */
894#define MSR_IA32_MCG_EAX 0x00000180
895#define MSR_IA32_MCG_EBX 0x00000181
896#define MSR_IA32_MCG_ECX 0x00000182
897#define MSR_IA32_MCG_EDX 0x00000183
898#define MSR_IA32_MCG_ESI 0x00000184
899#define MSR_IA32_MCG_EDI 0x00000185
900#define MSR_IA32_MCG_EBP 0x00000186
901#define MSR_IA32_MCG_ESP 0x00000187
902#define MSR_IA32_MCG_EFLAGS 0x00000188
903#define MSR_IA32_MCG_EIP 0x00000189
904#define MSR_IA32_MCG_RESERVED 0x0000018a
905
906/* Pentium IV performance counter MSRs */
907#define MSR_P4_BPU_PERFCTR0 0x00000300
908#define MSR_P4_BPU_PERFCTR1 0x00000301
909#define MSR_P4_BPU_PERFCTR2 0x00000302
910#define MSR_P4_BPU_PERFCTR3 0x00000303
911#define MSR_P4_MS_PERFCTR0 0x00000304
912#define MSR_P4_MS_PERFCTR1 0x00000305
913#define MSR_P4_MS_PERFCTR2 0x00000306
914#define MSR_P4_MS_PERFCTR3 0x00000307
915#define MSR_P4_FLAME_PERFCTR0 0x00000308
916#define MSR_P4_FLAME_PERFCTR1 0x00000309
917#define MSR_P4_FLAME_PERFCTR2 0x0000030a
918#define MSR_P4_FLAME_PERFCTR3 0x0000030b
919#define MSR_P4_IQ_PERFCTR0 0x0000030c
920#define MSR_P4_IQ_PERFCTR1 0x0000030d
921#define MSR_P4_IQ_PERFCTR2 0x0000030e
922#define MSR_P4_IQ_PERFCTR3 0x0000030f
923#define MSR_P4_IQ_PERFCTR4 0x00000310
924#define MSR_P4_IQ_PERFCTR5 0x00000311
925#define MSR_P4_BPU_CCCR0 0x00000360
926#define MSR_P4_BPU_CCCR1 0x00000361
927#define MSR_P4_BPU_CCCR2 0x00000362
928#define MSR_P4_BPU_CCCR3 0x00000363
929#define MSR_P4_MS_CCCR0 0x00000364
930#define MSR_P4_MS_CCCR1 0x00000365
931#define MSR_P4_MS_CCCR2 0x00000366
932#define MSR_P4_MS_CCCR3 0x00000367
933#define MSR_P4_FLAME_CCCR0 0x00000368
934#define MSR_P4_FLAME_CCCR1 0x00000369
935#define MSR_P4_FLAME_CCCR2 0x0000036a
936#define MSR_P4_FLAME_CCCR3 0x0000036b
937#define MSR_P4_IQ_CCCR0 0x0000036c
938#define MSR_P4_IQ_CCCR1 0x0000036d
939#define MSR_P4_IQ_CCCR2 0x0000036e
940#define MSR_P4_IQ_CCCR3 0x0000036f
941#define MSR_P4_IQ_CCCR4 0x00000370
942#define MSR_P4_IQ_CCCR5 0x00000371
943#define MSR_P4_ALF_ESCR0 0x000003ca
944#define MSR_P4_ALF_ESCR1 0x000003cb
945#define MSR_P4_BPU_ESCR0 0x000003b2
946#define MSR_P4_BPU_ESCR1 0x000003b3
947#define MSR_P4_BSU_ESCR0 0x000003a0
948#define MSR_P4_BSU_ESCR1 0x000003a1
949#define MSR_P4_CRU_ESCR0 0x000003b8
950#define MSR_P4_CRU_ESCR1 0x000003b9
951#define MSR_P4_CRU_ESCR2 0x000003cc
952#define MSR_P4_CRU_ESCR3 0x000003cd
953#define MSR_P4_CRU_ESCR4 0x000003e0
954#define MSR_P4_CRU_ESCR5 0x000003e1
955#define MSR_P4_DAC_ESCR0 0x000003a8
956#define MSR_P4_DAC_ESCR1 0x000003a9
957#define MSR_P4_FIRM_ESCR0 0x000003a4
958#define MSR_P4_FIRM_ESCR1 0x000003a5
959#define MSR_P4_FLAME_ESCR0 0x000003a6
960#define MSR_P4_FLAME_ESCR1 0x000003a7
961#define MSR_P4_FSB_ESCR0 0x000003a2
962#define MSR_P4_FSB_ESCR1 0x000003a3
963#define MSR_P4_IQ_ESCR0 0x000003ba
964#define MSR_P4_IQ_ESCR1 0x000003bb
965#define MSR_P4_IS_ESCR0 0x000003b4
966#define MSR_P4_IS_ESCR1 0x000003b5
967#define MSR_P4_ITLB_ESCR0 0x000003b6
968#define MSR_P4_ITLB_ESCR1 0x000003b7
969#define MSR_P4_IX_ESCR0 0x000003c8
970#define MSR_P4_IX_ESCR1 0x000003c9
971#define MSR_P4_MOB_ESCR0 0x000003aa
972#define MSR_P4_MOB_ESCR1 0x000003ab
973#define MSR_P4_MS_ESCR0 0x000003c0
974#define MSR_P4_MS_ESCR1 0x000003c1
975#define MSR_P4_PMH_ESCR0 0x000003ac
976#define MSR_P4_PMH_ESCR1 0x000003ad
977#define MSR_P4_RAT_ESCR0 0x000003bc
978#define MSR_P4_RAT_ESCR1 0x000003bd
979#define MSR_P4_SAAT_ESCR0 0x000003ae
980#define MSR_P4_SAAT_ESCR1 0x000003af
981#define MSR_P4_SSU_ESCR0 0x000003be
982#define MSR_P4_SSU_ESCR1 0x000003bf /* guess: not in manual */
983
984#define MSR_P4_TBPU_ESCR0 0x000003c2
985#define MSR_P4_TBPU_ESCR1 0x000003c3
986#define MSR_P4_TC_ESCR0 0x000003c4
987#define MSR_P4_TC_ESCR1 0x000003c5
988#define MSR_P4_U2L_ESCR0 0x000003b0
989#define MSR_P4_U2L_ESCR1 0x000003b1
990
991#define MSR_P4_PEBS_MATRIX_VERT 0x000003f2
992
993/* Intel Core-based CPU performance counters */
994#define MSR_CORE_PERF_FIXED_CTR0 0x00000309
995#define MSR_CORE_PERF_FIXED_CTR1 0x0000030a
996#define MSR_CORE_PERF_FIXED_CTR2 0x0000030b
997#define MSR_CORE_PERF_FIXED_CTR_CTRL 0x0000038d
998#define MSR_CORE_PERF_GLOBAL_STATUS 0x0000038e
999#define MSR_CORE_PERF_GLOBAL_CTRL 0x0000038f
1000#define MSR_CORE_PERF_GLOBAL_OVF_CTRL 0x00000390
1001
1002/* Geode defined MSRs */
1003#define MSR_GEODE_BUSCONT_CONF0 0x00001900
1004
1005/* Intel VT MSRs */
1006#define MSR_IA32_VMX_BASIC 0x00000480
1007#define MSR_IA32_VMX_PINBASED_CTLS 0x00000481
1008#define MSR_IA32_VMX_PROCBASED_CTLS 0x00000482
1009#define MSR_IA32_VMX_EXIT_CTLS 0x00000483
1010#define MSR_IA32_VMX_ENTRY_CTLS 0x00000484
1011#define MSR_IA32_VMX_MISC 0x00000485
1012#define MSR_IA32_VMX_CR0_FIXED0 0x00000486
1013#define MSR_IA32_VMX_CR0_FIXED1 0x00000487
1014#define MSR_IA32_VMX_CR4_FIXED0 0x00000488
1015#define MSR_IA32_VMX_CR4_FIXED1 0x00000489
1016#define MSR_IA32_VMX_VMCS_ENUM 0x0000048a
1017#define MSR_IA32_VMX_PROCBASED_CTLS2 0x0000048b
1018#define MSR_IA32_VMX_EPT_VPID_CAP 0x0000048c
1019#define MSR_IA32_VMX_TRUE_PINBASED_CTLS 0x0000048d
1020#define MSR_IA32_VMX_TRUE_PROCBASED_CTLS 0x0000048e
1021#define MSR_IA32_VMX_TRUE_EXIT_CTLS 0x0000048f
1022#define MSR_IA32_VMX_TRUE_ENTRY_CTLS 0x00000490
1023#define MSR_IA32_VMX_VMFUNC 0x00000491
1024
1025/* VMX_BASIC bits and bitmasks */
1026#define VMX_BASIC_VMCS_SIZE_SHIFT 32
1027#define VMX_BASIC_TRUE_CTLS (1ULL << 55)
1028#define VMX_BASIC_64 0x0001000000000000LLU
1029#define VMX_BASIC_MEM_TYPE_SHIFT 50
1030#define VMX_BASIC_MEM_TYPE_MASK 0x003c000000000000LLU
1031#define VMX_BASIC_MEM_TYPE_WB 6LLU
1032#define VMX_BASIC_INOUT 0x0040000000000000LLU
1033
1034/* MSR_IA32_VMX_MISC bits */
1035#define MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS (1ULL << 29)
1036#define MSR_IA32_VMX_MISC_PREEMPTION_TIMER_SCALE 0x1F
1037/* AMD-V MSRs */
1038
1039#define MSR_VM_CR 0xc0010114
1040#define MSR_VM_IGNNE 0xc0010115
1041#define MSR_VM_HSAVE_PA 0xc0010117
1042
1043#endif /* !SELFTEST_KVM_X86_H */
diff --git a/tools/testing/selftests/kvm/lib/assert.c b/tools/testing/selftests/kvm/lib/assert.c
new file mode 100644
index 000000000000..c9f5b7d4ce38
--- /dev/null
+++ b/tools/testing/selftests/kvm/lib/assert.c
@@ -0,0 +1,87 @@
1/*
2 * tools/testing/selftests/kvm/lib/assert.c
3 *
4 * Copyright (C) 2018, Google LLC.
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2.
7 */
8
9#define _GNU_SOURCE /* for getline(3) and strchrnul(3)*/
10
11#include "test_util.h"
12
13#include <execinfo.h>
14#include <sys/syscall.h>
15
16/* Dumps the current stack trace to stderr. */
17static void __attribute__((noinline)) test_dump_stack(void);
18static void test_dump_stack(void)
19{
20 /*
21 * Build and run this command:
22 *
23 * addr2line -s -e /proc/$PPID/exe -fpai {backtrace addresses} | \
24 * grep -v test_dump_stack | cat -n 1>&2
25 *
26 * Note that the spacing is different and there's no newline.
27 */
28 size_t i;
29 size_t n = 20;
30 void *stack[n];
31 const char *addr2line = "addr2line -s -e /proc/$PPID/exe -fpai";
32 const char *pipeline = "|cat -n 1>&2";
33 char cmd[strlen(addr2line) + strlen(pipeline) +
34 /* N bytes per addr * 2 digits per byte + 1 space per addr: */
35 n * (((sizeof(void *)) * 2) + 1) +
36 /* Null terminator: */
37 1];
38 char *c;
39
40 n = backtrace(stack, n);
41 c = &cmd[0];
42 c += sprintf(c, "%s", addr2line);
43 /*
44 * Skip the first 3 frames: backtrace, test_dump_stack, and
45 * test_assert. We hope that backtrace isn't inlined and the other two
46 * we've declared noinline.
47 */
48 for (i = 2; i < n; i++)
49 c += sprintf(c, " %lx", ((unsigned long) stack[i]) - 1);
50 c += sprintf(c, "%s", pipeline);
51#pragma GCC diagnostic push
52#pragma GCC diagnostic ignored "-Wunused-result"
53 system(cmd);
54#pragma GCC diagnostic pop
55}
56
57static pid_t gettid(void)
58{
59 return syscall(SYS_gettid);
60}
61
62void __attribute__((noinline))
63test_assert(bool exp, const char *exp_str,
64 const char *file, unsigned int line, const char *fmt, ...)
65{
66 va_list ap;
67
68 if (!(exp)) {
69 va_start(ap, fmt);
70
71 fprintf(stderr, "==== Test Assertion Failure ====\n"
72 " %s:%u: %s\n"
73 " pid=%d tid=%d\n",
74 file, line, exp_str, getpid(), gettid());
75 test_dump_stack();
76 if (fmt) {
77 fputs(" ", stderr);
78 vfprintf(stderr, fmt, ap);
79 fputs("\n", stderr);
80 }
81 va_end(ap);
82
83 exit(254);
84 }
85
86 return;
87}
diff --git a/tools/testing/selftests/kvm/lib/elf.c b/tools/testing/selftests/kvm/lib/elf.c
new file mode 100644
index 000000000000..5eb857584aa3
--- /dev/null
+++ b/tools/testing/selftests/kvm/lib/elf.c
@@ -0,0 +1,197 @@
1/*
2 * tools/testing/selftests/kvm/lib/elf.c
3 *
4 * Copyright (C) 2018, Google LLC.
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2.
7 */
8
9#include "test_util.h"
10
11#include <bits/endian.h>
12#include <linux/elf.h>
13
14#include "kvm_util.h"
15#include "kvm_util_internal.h"
16
17static void elfhdr_get(const char *filename, Elf64_Ehdr *hdrp)
18{
19 off_t offset_rv;
20
21 /* Open the ELF file. */
22 int fd;
23 fd = open(filename, O_RDONLY);
24 TEST_ASSERT(fd >= 0, "Failed to open ELF file,\n"
25 " filename: %s\n"
26 " rv: %i errno: %i", filename, fd, errno);
27
28 /* Read in and validate ELF Identification Record.
29 * The ELF Identification record is the first 16 (EI_NIDENT) bytes
30 * of the ELF header, which is at the beginning of the ELF file.
31 * For now it is only safe to read the first EI_NIDENT bytes. Once
32 * read and validated, the value of e_ehsize can be used to determine
33 * the real size of the ELF header.
34 */
35 unsigned char ident[EI_NIDENT];
36 test_read(fd, ident, sizeof(ident));
37 TEST_ASSERT((ident[EI_MAG0] == ELFMAG0) && (ident[EI_MAG1] == ELFMAG1)
38 && (ident[EI_MAG2] == ELFMAG2) && (ident[EI_MAG3] == ELFMAG3),
39 "ELF MAGIC Mismatch,\n"
40 " filename: %s\n"
41 " ident[EI_MAG0 - EI_MAG3]: %02x %02x %02x %02x\n"
42 " Expected: %02x %02x %02x %02x",
43 filename,
44 ident[EI_MAG0], ident[EI_MAG1], ident[EI_MAG2], ident[EI_MAG3],
45 ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3);
46 TEST_ASSERT(ident[EI_CLASS] == ELFCLASS64,
47 "Current implementation only able to handle ELFCLASS64,\n"
48 " filename: %s\n"
49 " ident[EI_CLASS]: %02x\n"
50 " expected: %02x",
51 filename,
52 ident[EI_CLASS], ELFCLASS64);
53 TEST_ASSERT(((BYTE_ORDER == LITTLE_ENDIAN)
54 && (ident[EI_DATA] == ELFDATA2LSB))
55 || ((BYTE_ORDER == BIG_ENDIAN)
56 && (ident[EI_DATA] == ELFDATA2MSB)), "Current "
57 "implementation only able to handle\n"
58 "cases where the host and ELF file endianness\n"
59 "is the same:\n"
60 " host BYTE_ORDER: %u\n"
61 " host LITTLE_ENDIAN: %u\n"
62 " host BIG_ENDIAN: %u\n"
63 " ident[EI_DATA]: %u\n"
64 " ELFDATA2LSB: %u\n"
65 " ELFDATA2MSB: %u",
66 BYTE_ORDER, LITTLE_ENDIAN, BIG_ENDIAN,
67 ident[EI_DATA], ELFDATA2LSB, ELFDATA2MSB);
68 TEST_ASSERT(ident[EI_VERSION] == EV_CURRENT,
69 "Current implementation only able to handle current "
70 "ELF version,\n"
71 " filename: %s\n"
72 " ident[EI_VERSION]: %02x\n"
73 " expected: %02x",
74 filename, ident[EI_VERSION], EV_CURRENT);
75
76 /* Read in the ELF header.
77 * With the ELF Identification portion of the ELF header
78 * validated, especially that the value at EI_VERSION is
79 * as expected, it is now safe to read the entire ELF header.
80 */
81 offset_rv = lseek(fd, 0, SEEK_SET);
82 TEST_ASSERT(offset_rv == 0, "Seek to ELF header failed,\n"
83 " rv: %zi expected: %i", offset_rv, 0);
84 test_read(fd, hdrp, sizeof(*hdrp));
85 TEST_ASSERT(hdrp->e_phentsize == sizeof(Elf64_Phdr),
86 "Unexpected physical header size,\n"
87 " hdrp->e_phentsize: %x\n"
88 " expected: %zx",
89 hdrp->e_phentsize, sizeof(Elf64_Phdr));
90 TEST_ASSERT(hdrp->e_shentsize == sizeof(Elf64_Shdr),
91 "Unexpected section header size,\n"
92 " hdrp->e_shentsize: %x\n"
93 " expected: %zx",
94 hdrp->e_shentsize, sizeof(Elf64_Shdr));
95}
96
97/* VM ELF Load
98 *
99 * Input Args:
100 * filename - Path to ELF file
101 *
102 * Output Args: None
103 *
104 * Input/Output Args:
105 * vm - Pointer to opaque type that describes the VM.
106 *
107 * Return: None, TEST_ASSERT failures for all error conditions
108 *
109 * Loads the program image of the ELF file specified by filename,
110 * into the virtual address space of the VM pointed to by vm. On entry
111 * the VM needs to not be using any of the virtual address space used
112 * by the image and it needs to have sufficient available physical pages, to
113 * back the virtual pages used to load the image.
114 */
115void kvm_vm_elf_load(struct kvm_vm *vm, const char *filename,
116 uint32_t data_memslot, uint32_t pgd_memslot)
117{
118 off_t offset, offset_rv;
119 Elf64_Ehdr hdr;
120
121 /* Open the ELF file. */
122 int fd;
123 fd = open(filename, O_RDONLY);
124 TEST_ASSERT(fd >= 0, "Failed to open ELF file,\n"
125 " filename: %s\n"
126 " rv: %i errno: %i", filename, fd, errno);
127
128 /* Read in the ELF header. */
129 elfhdr_get(filename, &hdr);
130
131 /* For each program header.
132 * The following ELF header members specify the location
133 * and size of the program headers:
134 *
135 * e_phoff - File offset to start of program headers
136 * e_phentsize - Size of each program header
137 * e_phnum - Number of program header entries
138 */
139 for (unsigned int n1 = 0; n1 < hdr.e_phnum; n1++) {
140 /* Seek to the beginning of the program header. */
141 offset = hdr.e_phoff + (n1 * hdr.e_phentsize);
142 offset_rv = lseek(fd, offset, SEEK_SET);
143 TEST_ASSERT(offset_rv == offset,
144 "Failed to seek to begining of program header %u,\n"
145 " filename: %s\n"
146 " rv: %jd errno: %i",
147 n1, filename, (intmax_t) offset_rv, errno);
148
149 /* Read in the program header. */
150 Elf64_Phdr phdr;
151 test_read(fd, &phdr, sizeof(phdr));
152
153 /* Skip if this header doesn't describe a loadable segment. */
154 if (phdr.p_type != PT_LOAD)
155 continue;
156
157 /* Allocate memory for this segment within the VM. */
158 TEST_ASSERT(phdr.p_memsz > 0, "Unexpected loadable segment "
159 "memsize of 0,\n"
160 " phdr index: %u p_memsz: 0x%" PRIx64,
161 n1, (uint64_t) phdr.p_memsz);
162 vm_vaddr_t seg_vstart = phdr.p_vaddr;
163 seg_vstart &= ~(vm_vaddr_t)(vm->page_size - 1);
164 vm_vaddr_t seg_vend = phdr.p_vaddr + phdr.p_memsz - 1;
165 seg_vend |= vm->page_size - 1;
166 size_t seg_size = seg_vend - seg_vstart + 1;
167
168 vm_vaddr_t vaddr = vm_vaddr_alloc(vm, seg_size, seg_vstart,
169 data_memslot, pgd_memslot);
170 TEST_ASSERT(vaddr == seg_vstart, "Unable to allocate "
171 "virtual memory for segment at requested min addr,\n"
172 " segment idx: %u\n"
173 " seg_vstart: 0x%lx\n"
174 " vaddr: 0x%lx",
175 n1, seg_vstart, vaddr);
176 memset(addr_gva2hva(vm, vaddr), 0, seg_size);
177 /* TODO(lhuemill): Set permissions of each memory segment
178 * based on the least-significant 3 bits of phdr.p_flags.
179 */
180
181 /* Load portion of initial state that is contained within
182 * the ELF file.
183 */
184 if (phdr.p_filesz) {
185 offset_rv = lseek(fd, phdr.p_offset, SEEK_SET);
186 TEST_ASSERT(offset_rv == phdr.p_offset,
187 "Seek to program segment offset failed,\n"
188 " program header idx: %u errno: %i\n"
189 " offset_rv: 0x%jx\n"
190 " expected: 0x%jx\n",
191 n1, errno, (intmax_t) offset_rv,
192 (intmax_t) phdr.p_offset);
193 test_read(fd, addr_gva2hva(vm, phdr.p_vaddr),
194 phdr.p_filesz);
195 }
196 }
197}
diff --git a/tools/testing/selftests/kvm/lib/io.c b/tools/testing/selftests/kvm/lib/io.c
new file mode 100644
index 000000000000..cff869ffe6ee
--- /dev/null
+++ b/tools/testing/selftests/kvm/lib/io.c
@@ -0,0 +1,158 @@
1/*
2 * tools/testing/selftests/kvm/lib/io.c
3 *
4 * Copyright (C) 2018, Google LLC.
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2.
7 */
8
9#include "test_util.h"
10
11/* Test Write
12 *
13 * A wrapper for write(2), that automatically handles the following
14 * special conditions:
15 *
16 * + Interrupted system call (EINTR)
17 * + Write of less than requested amount
18 * + Non-block return (EAGAIN)
19 *
20 * For each of the above, an additional write is performed to automatically
21 * continue writing the requested data.
22 * There are also many cases where write(2) can return an unexpected
23 * error (e.g. EIO). Such errors cause a TEST_ASSERT failure.
24 *
25 * Note, for function signature compatibility with write(2), this function
26 * returns the number of bytes written, but that value will always be equal
27 * to the number of requested bytes. All other conditions in this and
28 * future enhancements to this function either automatically issue another
29 * write(2) or cause a TEST_ASSERT failure.
30 *
31 * Args:
32 * fd - Opened file descriptor to file to be written.
33 * count - Number of bytes to write.
34 *
35 * Output:
36 * buf - Starting address of data to be written.
37 *
38 * Return:
39 * On success, number of bytes written.
40 * On failure, a TEST_ASSERT failure is caused.
41 */
42ssize_t test_write(int fd, const void *buf, size_t count)
43{
44 ssize_t rc;
45 ssize_t num_written = 0;
46 size_t num_left = count;
47 const char *ptr = buf;
48
49 /* Note: Count of zero is allowed (see "RETURN VALUE" portion of
50 * write(2) manpage for details.
51 */
52 TEST_ASSERT(count >= 0, "Unexpected count, count: %li", count);
53
54 do {
55 rc = write(fd, ptr, num_left);
56
57 switch (rc) {
58 case -1:
59 TEST_ASSERT(errno == EAGAIN || errno == EINTR,
60 "Unexpected write failure,\n"
61 " rc: %zi errno: %i", rc, errno);
62 continue;
63
64 case 0:
65 TEST_ASSERT(false, "Unexpected EOF,\n"
66 " rc: %zi num_written: %zi num_left: %zu",
67 rc, num_written, num_left);
68 break;
69
70 default:
71 TEST_ASSERT(rc >= 0, "Unexpected ret from write,\n"
72 " rc: %zi errno: %i", rc, errno);
73 num_written += rc;
74 num_left -= rc;
75 ptr += rc;
76 break;
77 }
78 } while (num_written < count);
79
80 return num_written;
81}
82
83/* Test Read
84 *
85 * A wrapper for read(2), that automatically handles the following
86 * special conditions:
87 *
88 * + Interrupted system call (EINTR)
89 * + Read of less than requested amount
90 * + Non-block return (EAGAIN)
91 *
92 * For each of the above, an additional read is performed to automatically
93 * continue reading the requested data.
94 * There are also many cases where read(2) can return an unexpected
95 * error (e.g. EIO). Such errors cause a TEST_ASSERT failure. Note,
96 * it is expected that the file opened by fd at the current file position
97 * contains at least the number of requested bytes to be read. A TEST_ASSERT
98 * failure is produced if an End-Of-File condition occurs, before all the
99 * data is read. It is the callers responsibility to assure that sufficient
100 * data exists.
101 *
102 * Note, for function signature compatibility with read(2), this function
103 * returns the number of bytes read, but that value will always be equal
104 * to the number of requested bytes. All other conditions in this and
105 * future enhancements to this function either automatically issue another
106 * read(2) or cause a TEST_ASSERT failure.
107 *
108 * Args:
109 * fd - Opened file descriptor to file to be read.
110 * count - Number of bytes to read.
111 *
112 * Output:
113 * buf - Starting address of where to write the bytes read.
114 *
115 * Return:
116 * On success, number of bytes read.
117 * On failure, a TEST_ASSERT failure is caused.
118 */
119ssize_t test_read(int fd, void *buf, size_t count)
120{
121 ssize_t rc;
122 ssize_t num_read = 0;
123 size_t num_left = count;
124 char *ptr = buf;
125
126 /* Note: Count of zero is allowed (see "If count is zero" portion of
127 * read(2) manpage for details.
128 */
129 TEST_ASSERT(count >= 0, "Unexpected count, count: %li", count);
130
131 do {
132 rc = read(fd, ptr, num_left);
133
134 switch (rc) {
135 case -1:
136 TEST_ASSERT(errno == EAGAIN || errno == EINTR,
137 "Unexpected read failure,\n"
138 " rc: %zi errno: %i", rc, errno);
139 break;
140
141 case 0:
142 TEST_ASSERT(false, "Unexpected EOF,\n"
143 " rc: %zi num_read: %zi num_left: %zu",
144 rc, num_read, num_left);
145 break;
146
147 default:
148 TEST_ASSERT(rc > 0, "Unexpected ret from read,\n"
149 " rc: %zi errno: %i", rc, errno);
150 num_read += rc;
151 num_left -= rc;
152 ptr += rc;
153 break;
154 }
155 } while (num_read < count);
156
157 return num_read;
158}
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
new file mode 100644
index 000000000000..2cedfda181d4
--- /dev/null
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -0,0 +1,1486 @@
1/*
2 * tools/testing/selftests/kvm/lib/kvm_util.c
3 *
4 * Copyright (C) 2018, Google LLC.
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2.
7 */
8
9#include "test_util.h"
10#include "kvm_util.h"
11#include "kvm_util_internal.h"
12
13#include <assert.h>
14#include <sys/mman.h>
15#include <sys/types.h>
16#include <sys/stat.h>
17
18#define KVM_DEV_PATH "/dev/kvm"
19
20#define KVM_UTIL_PGS_PER_HUGEPG 512
21#define KVM_UTIL_MIN_PADDR 0x2000
22
23/* Aligns x up to the next multiple of size. Size must be a power of 2. */
24static void *align(void *x, size_t size)
25{
26 size_t mask = size - 1;
27 TEST_ASSERT(size != 0 && !(size & (size - 1)),
28 "size not a power of 2: %lu", size);
29 return (void *) (((size_t) x + mask) & ~mask);
30}
31
32/* Capability
33 *
34 * Input Args:
35 * cap - Capability
36 *
37 * Output Args: None
38 *
39 * Return:
40 * On success, the Value corresponding to the capability (KVM_CAP_*)
41 * specified by the value of cap. On failure a TEST_ASSERT failure
42 * is produced.
43 *
44 * Looks up and returns the value corresponding to the capability
45 * (KVM_CAP_*) given by cap.
46 */
47int kvm_check_cap(long cap)
48{
49 int ret;
50 int kvm_fd;
51
52 kvm_fd = open(KVM_DEV_PATH, O_RDONLY);
53 TEST_ASSERT(kvm_fd >= 0, "open %s failed, rc: %i errno: %i",
54 KVM_DEV_PATH, kvm_fd, errno);
55
56 ret = ioctl(kvm_fd, KVM_CHECK_EXTENSION, cap);
57 TEST_ASSERT(ret != -1, "KVM_CHECK_EXTENSION IOCTL failed,\n"
58 " rc: %i errno: %i", ret, errno);
59
60 close(kvm_fd);
61
62 return ret;
63}
64
65/* VM Create
66 *
67 * Input Args:
68 * mode - VM Mode (e.g. VM_MODE_FLAT48PG)
69 * phy_pages - Physical memory pages
70 * perm - permission
71 *
72 * Output Args: None
73 *
74 * Return:
75 * Pointer to opaque structure that describes the created VM.
76 *
77 * Creates a VM with the mode specified by mode (e.g. VM_MODE_FLAT48PG).
78 * When phy_pages is non-zero, a memory region of phy_pages physical pages
79 * is created and mapped starting at guest physical address 0. The file
80 * descriptor to control the created VM is created with the permissions
81 * given by perm (e.g. O_RDWR).
82 */
83struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm)
84{
85 struct kvm_vm *vm;
86 int kvm_fd;
87
88 /* Allocate memory. */
89 vm = calloc(1, sizeof(*vm));
90 TEST_ASSERT(vm != NULL, "Insufficent Memory");
91
92 vm->mode = mode;
93 kvm_fd = open(KVM_DEV_PATH, perm);
94 TEST_ASSERT(kvm_fd >= 0, "open %s failed, rc: %i errno: %i",
95 KVM_DEV_PATH, kvm_fd, errno);
96
97 /* Create VM. */
98 vm->fd = ioctl(kvm_fd, KVM_CREATE_VM, NULL);
99 TEST_ASSERT(vm->fd >= 0, "KVM_CREATE_VM ioctl failed, "
100 "rc: %i errno: %i", vm->fd, errno);
101
102 close(kvm_fd);
103
104 /* Setup mode specific traits. */
105 switch (vm->mode) {
106 case VM_MODE_FLAT48PG:
107 vm->page_size = 0x1000;
108 vm->page_shift = 12;
109
110 /* Limit to 48-bit canonical virtual addresses. */
111 vm->vpages_valid = sparsebit_alloc();
112 sparsebit_set_num(vm->vpages_valid,
113 0, (1ULL << (48 - 1)) >> vm->page_shift);
114 sparsebit_set_num(vm->vpages_valid,
115 (~((1ULL << (48 - 1)) - 1)) >> vm->page_shift,
116 (1ULL << (48 - 1)) >> vm->page_shift);
117
118 /* Limit physical addresses to 52-bits. */
119 vm->max_gfn = ((1ULL << 52) >> vm->page_shift) - 1;
120 break;
121
122 default:
123 TEST_ASSERT(false, "Unknown guest mode, mode: 0x%x", mode);
124 }
125
126 /* Allocate and setup memory for guest. */
127 vm->vpages_mapped = sparsebit_alloc();
128 if (phy_pages != 0)
129 vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS,
130 0, 0, phy_pages, 0);
131
132 return vm;
133}
134
135/* Userspace Memory Region Find
136 *
137 * Input Args:
138 * vm - Virtual Machine
139 * start - Starting VM physical address
140 * end - Ending VM physical address, inclusive.
141 *
142 * Output Args: None
143 *
144 * Return:
145 * Pointer to overlapping region, NULL if no such region.
146 *
147 * Searches for a region with any physical memory that overlaps with
148 * any portion of the guest physical addresses from start to end
149 * inclusive. If multiple overlapping regions exist, a pointer to any
150 * of the regions is returned. Null is returned only when no overlapping
151 * region exists.
152 */
153static struct userspace_mem_region *userspace_mem_region_find(
154 struct kvm_vm *vm, uint64_t start, uint64_t end)
155{
156 struct userspace_mem_region *region;
157
158 for (region = vm->userspace_mem_region_head; region;
159 region = region->next) {
160 uint64_t existing_start = region->region.guest_phys_addr;
161 uint64_t existing_end = region->region.guest_phys_addr
162 + region->region.memory_size - 1;
163 if (start <= existing_end && end >= existing_start)
164 return region;
165 }
166
167 return NULL;
168}
169
170/* KVM Userspace Memory Region Find
171 *
172 * Input Args:
173 * vm - Virtual Machine
174 * start - Starting VM physical address
175 * end - Ending VM physical address, inclusive.
176 *
177 * Output Args: None
178 *
179 * Return:
180 * Pointer to overlapping region, NULL if no such region.
181 *
182 * Public interface to userspace_mem_region_find. Allows tests to look up
183 * the memslot datastructure for a given range of guest physical memory.
184 */
185struct kvm_userspace_memory_region *
186kvm_userspace_memory_region_find(struct kvm_vm *vm, uint64_t start,
187 uint64_t end)
188{
189 struct userspace_mem_region *region;
190
191 region = userspace_mem_region_find(vm, start, end);
192 if (!region)
193 return NULL;
194
195 return &region->region;
196}
197
198/* VCPU Find
199 *
200 * Input Args:
201 * vm - Virtual Machine
202 * vcpuid - VCPU ID
203 *
204 * Output Args: None
205 *
206 * Return:
207 * Pointer to VCPU structure
208 *
209 * Locates a vcpu structure that describes the VCPU specified by vcpuid and
210 * returns a pointer to it. Returns NULL if the VM doesn't contain a VCPU
211 * for the specified vcpuid.
212 */
213struct vcpu *vcpu_find(struct kvm_vm *vm,
214 uint32_t vcpuid)
215{
216 struct vcpu *vcpup;
217
218 for (vcpup = vm->vcpu_head; vcpup; vcpup = vcpup->next) {
219 if (vcpup->id == vcpuid)
220 return vcpup;
221 }
222
223 return NULL;
224}
225
226/* VM VCPU Remove
227 *
228 * Input Args:
229 * vm - Virtual Machine
230 * vcpuid - VCPU ID
231 *
232 * Output Args: None
233 *
234 * Return: None, TEST_ASSERT failures for all error conditions
235 *
236 * Within the VM specified by vm, removes the VCPU given by vcpuid.
237 */
238static void vm_vcpu_rm(struct kvm_vm *vm, uint32_t vcpuid)
239{
240 struct vcpu *vcpu = vcpu_find(vm, vcpuid);
241
242 int ret = close(vcpu->fd);
243 TEST_ASSERT(ret == 0, "Close of VCPU fd failed, rc: %i "
244 "errno: %i", ret, errno);
245
246 if (vcpu->next)
247 vcpu->next->prev = vcpu->prev;
248 if (vcpu->prev)
249 vcpu->prev->next = vcpu->next;
250 else
251 vm->vcpu_head = vcpu->next;
252 free(vcpu);
253}
254
255
256/* Destroys and frees the VM pointed to by vmp.
257 */
258void kvm_vm_free(struct kvm_vm *vmp)
259{
260 int ret;
261
262 if (vmp == NULL)
263 return;
264
265 /* Free userspace_mem_regions. */
266 while (vmp->userspace_mem_region_head) {
267 struct userspace_mem_region *region
268 = vmp->userspace_mem_region_head;
269
270 region->region.memory_size = 0;
271 ret = ioctl(vmp->fd, KVM_SET_USER_MEMORY_REGION,
272 &region->region);
273 TEST_ASSERT(ret == 0, "KVM_SET_USER_MEMORY_REGION IOCTL failed, "
274 "rc: %i errno: %i", ret, errno);
275
276 vmp->userspace_mem_region_head = region->next;
277 sparsebit_free(&region->unused_phy_pages);
278 ret = munmap(region->mmap_start, region->mmap_size);
279 TEST_ASSERT(ret == 0, "munmap failed, rc: %i errno: %i",
280 ret, errno);
281
282 free(region);
283 }
284
285 /* Free VCPUs. */
286 while (vmp->vcpu_head)
287 vm_vcpu_rm(vmp, vmp->vcpu_head->id);
288
289 /* Free sparsebit arrays. */
290 sparsebit_free(&vmp->vpages_valid);
291 sparsebit_free(&vmp->vpages_mapped);
292
293 /* Close file descriptor for the VM. */
294 ret = close(vmp->fd);
295 TEST_ASSERT(ret == 0, "Close of vm fd failed,\n"
296 " vmp->fd: %i rc: %i errno: %i", vmp->fd, ret, errno);
297
298 /* Free the structure describing the VM. */
299 free(vmp);
300}
301
302/* Memory Compare, host virtual to guest virtual
303 *
304 * Input Args:
305 * hva - Starting host virtual address
306 * vm - Virtual Machine
307 * gva - Starting guest virtual address
308 * len - number of bytes to compare
309 *
310 * Output Args: None
311 *
312 * Input/Output Args: None
313 *
314 * Return:
315 * Returns 0 if the bytes starting at hva for a length of len
316 * are equal the guest virtual bytes starting at gva. Returns
317 * a value < 0, if bytes at hva are less than those at gva.
318 * Otherwise a value > 0 is returned.
319 *
320 * Compares the bytes starting at the host virtual address hva, for
321 * a length of len, to the guest bytes starting at the guest virtual
322 * address given by gva.
323 */
324int kvm_memcmp_hva_gva(void *hva,
325 struct kvm_vm *vm, vm_vaddr_t gva, size_t len)
326{
327 size_t amt;
328
329 /* Compare a batch of bytes until either a match is found
330 * or all the bytes have been compared.
331 */
332 for (uintptr_t offset = 0; offset < len; offset += amt) {
333 uintptr_t ptr1 = (uintptr_t)hva + offset;
334
335 /* Determine host address for guest virtual address
336 * at offset.
337 */
338 uintptr_t ptr2 = (uintptr_t)addr_gva2hva(vm, gva + offset);
339
340 /* Determine amount to compare on this pass.
341 * Don't allow the comparsion to cross a page boundary.
342 */
343 amt = len - offset;
344 if ((ptr1 >> vm->page_shift) != ((ptr1 + amt) >> vm->page_shift))
345 amt = vm->page_size - (ptr1 % vm->page_size);
346 if ((ptr2 >> vm->page_shift) != ((ptr2 + amt) >> vm->page_shift))
347 amt = vm->page_size - (ptr2 % vm->page_size);
348
349 assert((ptr1 >> vm->page_shift) == ((ptr1 + amt - 1) >> vm->page_shift));
350 assert((ptr2 >> vm->page_shift) == ((ptr2 + amt - 1) >> vm->page_shift));
351
352 /* Perform the comparison. If there is a difference
353 * return that result to the caller, otherwise need
354 * to continue on looking for a mismatch.
355 */
356 int ret = memcmp((void *)ptr1, (void *)ptr2, amt);
357 if (ret != 0)
358 return ret;
359 }
360
361 /* No mismatch found. Let the caller know the two memory
362 * areas are equal.
363 */
364 return 0;
365}
366
367/* Allocate an instance of struct kvm_cpuid2
368 *
369 * Input Args: None
370 *
371 * Output Args: None
372 *
373 * Return: A pointer to the allocated struct. The caller is responsible
374 * for freeing this struct.
375 *
376 * Since kvm_cpuid2 uses a 0-length array to allow a the size of the
377 * array to be decided at allocation time, allocation is slightly
378 * complicated. This function uses a reasonable default length for
379 * the array and performs the appropriate allocation.
380 */
381static struct kvm_cpuid2 *allocate_kvm_cpuid2(void)
382{
383 struct kvm_cpuid2 *cpuid;
384 int nent = 100;
385 size_t size;
386
387 size = sizeof(*cpuid);
388 size += nent * sizeof(struct kvm_cpuid_entry2);
389 cpuid = malloc(size);
390 if (!cpuid) {
391 perror("malloc");
392 abort();
393 }
394
395 cpuid->nent = nent;
396
397 return cpuid;
398}
399
400/* KVM Supported CPUID Get
401 *
402 * Input Args: None
403 *
404 * Output Args:
405 *
406 * Return: The supported KVM CPUID
407 *
408 * Get the guest CPUID supported by KVM.
409 */
410struct kvm_cpuid2 *kvm_get_supported_cpuid(void)
411{
412 static struct kvm_cpuid2 *cpuid;
413 int ret;
414 int kvm_fd;
415
416 if (cpuid)
417 return cpuid;
418
419 cpuid = allocate_kvm_cpuid2();
420 kvm_fd = open(KVM_DEV_PATH, O_RDONLY);
421 TEST_ASSERT(kvm_fd >= 0, "open %s failed, rc: %i errno: %i",
422 KVM_DEV_PATH, kvm_fd, errno);
423
424 ret = ioctl(kvm_fd, KVM_GET_SUPPORTED_CPUID, cpuid);
425 TEST_ASSERT(ret == 0, "KVM_GET_SUPPORTED_CPUID failed %d %d\n",
426 ret, errno);
427
428 close(kvm_fd);
429 return cpuid;
430}
431
432/* Locate a cpuid entry.
433 *
434 * Input Args:
435 * cpuid: The cpuid.
436 * function: The function of the cpuid entry to find.
437 *
438 * Output Args: None
439 *
440 * Return: A pointer to the cpuid entry. Never returns NULL.
441 */
442struct kvm_cpuid_entry2 *
443kvm_get_supported_cpuid_index(uint32_t function, uint32_t index)
444{
445 struct kvm_cpuid2 *cpuid;
446 struct kvm_cpuid_entry2 *entry = NULL;
447 int i;
448
449 cpuid = kvm_get_supported_cpuid();
450 for (i = 0; i < cpuid->nent; i++) {
451 if (cpuid->entries[i].function == function &&
452 cpuid->entries[i].index == index) {
453 entry = &cpuid->entries[i];
454 break;
455 }
456 }
457
458 TEST_ASSERT(entry, "Guest CPUID entry not found: (EAX=%x, ECX=%x).",
459 function, index);
460 return entry;
461}
462
463/* VM Userspace Memory Region Add
464 *
465 * Input Args:
466 * vm - Virtual Machine
467 * backing_src - Storage source for this region.
468 * NULL to use anonymous memory.
469 * guest_paddr - Starting guest physical address
470 * slot - KVM region slot
471 * npages - Number of physical pages
472 * flags - KVM memory region flags (e.g. KVM_MEM_LOG_DIRTY_PAGES)
473 *
474 * Output Args: None
475 *
476 * Return: None
477 *
478 * Allocates a memory area of the number of pages specified by npages
479 * and maps it to the VM specified by vm, at a starting physical address
480 * given by guest_paddr. The region is created with a KVM region slot
481 * given by slot, which must be unique and < KVM_MEM_SLOTS_NUM. The
482 * region is created with the flags given by flags.
483 */
484void vm_userspace_mem_region_add(struct kvm_vm *vm,
485 enum vm_mem_backing_src_type src_type,
486 uint64_t guest_paddr, uint32_t slot, uint64_t npages,
487 uint32_t flags)
488{
489 int ret;
490 unsigned long pmem_size = 0;
491 struct userspace_mem_region *region;
492 size_t huge_page_size = KVM_UTIL_PGS_PER_HUGEPG * vm->page_size;
493
494 TEST_ASSERT((guest_paddr % vm->page_size) == 0, "Guest physical "
495 "address not on a page boundary.\n"
496 " guest_paddr: 0x%lx vm->page_size: 0x%x",
497 guest_paddr, vm->page_size);
498 TEST_ASSERT((((guest_paddr >> vm->page_shift) + npages) - 1)
499 <= vm->max_gfn, "Physical range beyond maximum "
500 "supported physical address,\n"
501 " guest_paddr: 0x%lx npages: 0x%lx\n"
502 " vm->max_gfn: 0x%lx vm->page_size: 0x%x",
503 guest_paddr, npages, vm->max_gfn, vm->page_size);
504
505 /* Confirm a mem region with an overlapping address doesn't
506 * already exist.
507 */
508 region = (struct userspace_mem_region *) userspace_mem_region_find(
509 vm, guest_paddr, guest_paddr + npages * vm->page_size);
510 if (region != NULL)
511 TEST_ASSERT(false, "overlapping userspace_mem_region already "
512 "exists\n"
513 " requested guest_paddr: 0x%lx npages: 0x%lx "
514 "page_size: 0x%x\n"
515 " existing guest_paddr: 0x%lx size: 0x%lx",
516 guest_paddr, npages, vm->page_size,
517 (uint64_t) region->region.guest_phys_addr,
518 (uint64_t) region->region.memory_size);
519
520 /* Confirm no region with the requested slot already exists. */
521 for (region = vm->userspace_mem_region_head; region;
522 region = region->next) {
523 if (region->region.slot == slot)
524 break;
525 if ((guest_paddr <= (region->region.guest_phys_addr
526 + region->region.memory_size))
527 && ((guest_paddr + npages * vm->page_size)
528 >= region->region.guest_phys_addr))
529 break;
530 }
531 if (region != NULL)
532 TEST_ASSERT(false, "A mem region with the requested slot "
533 "or overlapping physical memory range already exists.\n"
534 " requested slot: %u paddr: 0x%lx npages: 0x%lx\n"
535 " existing slot: %u paddr: 0x%lx size: 0x%lx",
536 slot, guest_paddr, npages,
537 region->region.slot,
538 (uint64_t) region->region.guest_phys_addr,
539 (uint64_t) region->region.memory_size);
540
541 /* Allocate and initialize new mem region structure. */
542 region = calloc(1, sizeof(*region));
543 TEST_ASSERT(region != NULL, "Insufficient Memory");
544 region->mmap_size = npages * vm->page_size;
545
546 /* Enough memory to align up to a huge page. */
547 if (src_type == VM_MEM_SRC_ANONYMOUS_THP)
548 region->mmap_size += huge_page_size;
549 region->mmap_start = mmap(NULL, region->mmap_size,
550 PROT_READ | PROT_WRITE,
551 MAP_PRIVATE | MAP_ANONYMOUS
552 | (src_type == VM_MEM_SRC_ANONYMOUS_HUGETLB ? MAP_HUGETLB : 0),
553 -1, 0);
554 TEST_ASSERT(region->mmap_start != MAP_FAILED,
555 "test_malloc failed, mmap_start: %p errno: %i",
556 region->mmap_start, errno);
557
558 /* Align THP allocation up to start of a huge page. */
559 region->host_mem = align(region->mmap_start,
560 src_type == VM_MEM_SRC_ANONYMOUS_THP ? huge_page_size : 1);
561
562 /* As needed perform madvise */
563 if (src_type == VM_MEM_SRC_ANONYMOUS || src_type == VM_MEM_SRC_ANONYMOUS_THP) {
564 ret = madvise(region->host_mem, npages * vm->page_size,
565 src_type == VM_MEM_SRC_ANONYMOUS ? MADV_NOHUGEPAGE : MADV_HUGEPAGE);
566 TEST_ASSERT(ret == 0, "madvise failed,\n"
567 " addr: %p\n"
568 " length: 0x%lx\n"
569 " src_type: %x",
570 region->host_mem, npages * vm->page_size, src_type);
571 }
572
573 region->unused_phy_pages = sparsebit_alloc();
574 sparsebit_set_num(region->unused_phy_pages,
575 guest_paddr >> vm->page_shift, npages);
576 region->region.slot = slot;
577 region->region.flags = flags;
578 region->region.guest_phys_addr = guest_paddr;
579 region->region.memory_size = npages * vm->page_size;
580 region->region.userspace_addr = (uintptr_t) region->host_mem;
581 ret = ioctl(vm->fd, KVM_SET_USER_MEMORY_REGION, &region->region);
582 TEST_ASSERT(ret == 0, "KVM_SET_USER_MEMORY_REGION IOCTL failed,\n"
583 " rc: %i errno: %i\n"
584 " slot: %u flags: 0x%x\n"
585 " guest_phys_addr: 0x%lx size: 0x%lx",
586 ret, errno, slot, flags,
587 guest_paddr, (uint64_t) region->region.memory_size);
588
589 /* Add to linked-list of memory regions. */
590 if (vm->userspace_mem_region_head)
591 vm->userspace_mem_region_head->prev = region;
592 region->next = vm->userspace_mem_region_head;
593 vm->userspace_mem_region_head = region;
594}
595
596/* Memslot to region
597 *
598 * Input Args:
599 * vm - Virtual Machine
600 * memslot - KVM memory slot ID
601 *
602 * Output Args: None
603 *
604 * Return:
605 * Pointer to memory region structure that describe memory region
606 * using kvm memory slot ID given by memslot. TEST_ASSERT failure
607 * on error (e.g. currently no memory region using memslot as a KVM
608 * memory slot ID).
609 */
610static struct userspace_mem_region *memslot2region(struct kvm_vm *vm,
611 uint32_t memslot)
612{
613 struct userspace_mem_region *region;
614
615 for (region = vm->userspace_mem_region_head; region;
616 region = region->next) {
617 if (region->region.slot == memslot)
618 break;
619 }
620 if (region == NULL) {
621 fprintf(stderr, "No mem region with the requested slot found,\n"
622 " requested slot: %u\n", memslot);
623 fputs("---- vm dump ----\n", stderr);
624 vm_dump(stderr, vm, 2);
625 TEST_ASSERT(false, "Mem region not found");
626 }
627
628 return region;
629}
630
631/* VM Memory Region Flags Set
632 *
633 * Input Args:
634 * vm - Virtual Machine
635 * flags - Starting guest physical address
636 *
637 * Output Args: None
638 *
639 * Return: None
640 *
641 * Sets the flags of the memory region specified by the value of slot,
642 * to the values given by flags.
643 */
644void vm_mem_region_set_flags(struct kvm_vm *vm, uint32_t slot, uint32_t flags)
645{
646 int ret;
647 struct userspace_mem_region *region;
648
649 /* Locate memory region. */
650 region = memslot2region(vm, slot);
651
652 region->region.flags = flags;
653
654 ret = ioctl(vm->fd, KVM_SET_USER_MEMORY_REGION, &region->region);
655
656 TEST_ASSERT(ret == 0, "KVM_SET_USER_MEMORY_REGION IOCTL failed,\n"
657 " rc: %i errno: %i slot: %u flags: 0x%x",
658 ret, errno, slot, flags);
659}
660
661/* VCPU mmap Size
662 *
663 * Input Args: None
664 *
665 * Output Args: None
666 *
667 * Return:
668 * Size of VCPU state
669 *
670 * Returns the size of the structure pointed to by the return value
671 * of vcpu_state().
672 */
673static int vcpu_mmap_sz(void)
674{
675 int dev_fd, ret;
676
677 dev_fd = open(KVM_DEV_PATH, O_RDONLY);
678 TEST_ASSERT(dev_fd >= 0, "%s open %s failed, rc: %i errno: %i",
679 __func__, KVM_DEV_PATH, dev_fd, errno);
680
681 ret = ioctl(dev_fd, KVM_GET_VCPU_MMAP_SIZE, NULL);
682 TEST_ASSERT(ret >= sizeof(struct kvm_run),
683 "%s KVM_GET_VCPU_MMAP_SIZE ioctl failed, rc: %i errno: %i",
684 __func__, ret, errno);
685
686 close(dev_fd);
687
688 return ret;
689}
690
691/* VM VCPU Add
692 *
693 * Input Args:
694 * vm - Virtual Machine
695 * vcpuid - VCPU ID
696 *
697 * Output Args: None
698 *
699 * Return: None
700 *
701 * Creates and adds to the VM specified by vm and virtual CPU with
702 * the ID given by vcpuid.
703 */
704void vm_vcpu_add(struct kvm_vm *vm, uint32_t vcpuid)
705{
706 struct vcpu *vcpu;
707
708 /* Confirm a vcpu with the specified id doesn't already exist. */
709 vcpu = vcpu_find(vm, vcpuid);
710 if (vcpu != NULL)
711 TEST_ASSERT(false, "vcpu with the specified id "
712 "already exists,\n"
713 " requested vcpuid: %u\n"
714 " existing vcpuid: %u state: %p",
715 vcpuid, vcpu->id, vcpu->state);
716
717 /* Allocate and initialize new vcpu structure. */
718 vcpu = calloc(1, sizeof(*vcpu));
719 TEST_ASSERT(vcpu != NULL, "Insufficient Memory");
720 vcpu->id = vcpuid;
721 vcpu->fd = ioctl(vm->fd, KVM_CREATE_VCPU, vcpuid);
722 TEST_ASSERT(vcpu->fd >= 0, "KVM_CREATE_VCPU failed, rc: %i errno: %i",
723 vcpu->fd, errno);
724
725 TEST_ASSERT(vcpu_mmap_sz() >= sizeof(*vcpu->state), "vcpu mmap size "
726 "smaller than expected, vcpu_mmap_sz: %i expected_min: %zi",
727 vcpu_mmap_sz(), sizeof(*vcpu->state));
728 vcpu->state = (struct kvm_run *) mmap(NULL, sizeof(*vcpu->state),
729 PROT_READ | PROT_WRITE, MAP_SHARED, vcpu->fd, 0);
730 TEST_ASSERT(vcpu->state != MAP_FAILED, "mmap vcpu_state failed, "
731 "vcpu id: %u errno: %i", vcpuid, errno);
732
733 /* Add to linked-list of VCPUs. */
734 if (vm->vcpu_head)
735 vm->vcpu_head->prev = vcpu;
736 vcpu->next = vm->vcpu_head;
737 vm->vcpu_head = vcpu;
738
739 vcpu_setup(vm, vcpuid);
740}
741
742/* VM Virtual Address Unused Gap
743 *
744 * Input Args:
745 * vm - Virtual Machine
746 * sz - Size (bytes)
747 * vaddr_min - Minimum Virtual Address
748 *
749 * Output Args: None
750 *
751 * Return:
752 * Lowest virtual address at or below vaddr_min, with at least
753 * sz unused bytes. TEST_ASSERT failure if no area of at least
754 * size sz is available.
755 *
756 * Within the VM specified by vm, locates the lowest starting virtual
757 * address >= vaddr_min, that has at least sz unallocated bytes. A
758 * TEST_ASSERT failure occurs for invalid input or no area of at least
759 * sz unallocated bytes >= vaddr_min is available.
760 */
761static vm_vaddr_t vm_vaddr_unused_gap(struct kvm_vm *vm, size_t sz,
762 vm_vaddr_t vaddr_min)
763{
764 uint64_t pages = (sz + vm->page_size - 1) >> vm->page_shift;
765
766 /* Determine lowest permitted virtual page index. */
767 uint64_t pgidx_start = (vaddr_min + vm->page_size - 1) >> vm->page_shift;
768 if ((pgidx_start * vm->page_size) < vaddr_min)
769 goto no_va_found;
770
771 /* Loop over section with enough valid virtual page indexes. */
772 if (!sparsebit_is_set_num(vm->vpages_valid,
773 pgidx_start, pages))
774 pgidx_start = sparsebit_next_set_num(vm->vpages_valid,
775 pgidx_start, pages);
776 do {
777 /*
778 * Are there enough unused virtual pages available at
779 * the currently proposed starting virtual page index.
780 * If not, adjust proposed starting index to next
781 * possible.
782 */
783 if (sparsebit_is_clear_num(vm->vpages_mapped,
784 pgidx_start, pages))
785 goto va_found;
786 pgidx_start = sparsebit_next_clear_num(vm->vpages_mapped,
787 pgidx_start, pages);
788 if (pgidx_start == 0)
789 goto no_va_found;
790
791 /*
792 * If needed, adjust proposed starting virtual address,
793 * to next range of valid virtual addresses.
794 */
795 if (!sparsebit_is_set_num(vm->vpages_valid,
796 pgidx_start, pages)) {
797 pgidx_start = sparsebit_next_set_num(
798 vm->vpages_valid, pgidx_start, pages);
799 if (pgidx_start == 0)
800 goto no_va_found;
801 }
802 } while (pgidx_start != 0);
803
804no_va_found:
805 TEST_ASSERT(false, "No vaddr of specified pages available, "
806 "pages: 0x%lx", pages);
807
808 /* NOT REACHED */
809 return -1;
810
811va_found:
812 TEST_ASSERT(sparsebit_is_set_num(vm->vpages_valid,
813 pgidx_start, pages),
814 "Unexpected, invalid virtual page index range,\n"
815 " pgidx_start: 0x%lx\n"
816 " pages: 0x%lx",
817 pgidx_start, pages);
818 TEST_ASSERT(sparsebit_is_clear_num(vm->vpages_mapped,
819 pgidx_start, pages),
820 "Unexpected, pages already mapped,\n"
821 " pgidx_start: 0x%lx\n"
822 " pages: 0x%lx",
823 pgidx_start, pages);
824
825 return pgidx_start * vm->page_size;
826}
827
828/* VM Virtual Address Allocate
829 *
830 * Input Args:
831 * vm - Virtual Machine
832 * sz - Size in bytes
833 * vaddr_min - Minimum starting virtual address
834 * data_memslot - Memory region slot for data pages
835 * pgd_memslot - Memory region slot for new virtual translation tables
836 *
837 * Output Args: None
838 *
839 * Return:
840 * Starting guest virtual address
841 *
842 * Allocates at least sz bytes within the virtual address space of the vm
843 * given by vm. The allocated bytes are mapped to a virtual address >=
844 * the address given by vaddr_min. Note that each allocation uses a
845 * a unique set of pages, with the minimum real allocation being at least
846 * a page.
847 */
848vm_vaddr_t vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min,
849 uint32_t data_memslot, uint32_t pgd_memslot)
850{
851 uint64_t pages = (sz >> vm->page_shift) + ((sz % vm->page_size) != 0);
852
853 virt_pgd_alloc(vm, pgd_memslot);
854
855 /* Find an unused range of virtual page addresses of at least
856 * pages in length.
857 */
858 vm_vaddr_t vaddr_start = vm_vaddr_unused_gap(vm, sz, vaddr_min);
859
860 /* Map the virtual pages. */
861 for (vm_vaddr_t vaddr = vaddr_start; pages > 0;
862 pages--, vaddr += vm->page_size) {
863 vm_paddr_t paddr;
864
865 paddr = vm_phy_page_alloc(vm, KVM_UTIL_MIN_PADDR, data_memslot);
866
867 virt_pg_map(vm, vaddr, paddr, pgd_memslot);
868
869 sparsebit_set(vm->vpages_mapped,
870 vaddr >> vm->page_shift);
871 }
872
873 return vaddr_start;
874}
875
876/* Address VM Physical to Host Virtual
877 *
878 * Input Args:
879 * vm - Virtual Machine
880 * gpa - VM physical address
881 *
882 * Output Args: None
883 *
884 * Return:
885 * Equivalent host virtual address
886 *
887 * Locates the memory region containing the VM physical address given
888 * by gpa, within the VM given by vm. When found, the host virtual
889 * address providing the memory to the vm physical address is returned.
890 * A TEST_ASSERT failure occurs if no region containing gpa exists.
891 */
892void *addr_gpa2hva(struct kvm_vm *vm, vm_paddr_t gpa)
893{
894 struct userspace_mem_region *region;
895 for (region = vm->userspace_mem_region_head; region;
896 region = region->next) {
897 if ((gpa >= region->region.guest_phys_addr)
898 && (gpa <= (region->region.guest_phys_addr
899 + region->region.memory_size - 1)))
900 return (void *) ((uintptr_t) region->host_mem
901 + (gpa - region->region.guest_phys_addr));
902 }
903
904 TEST_ASSERT(false, "No vm physical memory at 0x%lx", gpa);
905 return NULL;
906}
907
908/* Address Host Virtual to VM Physical
909 *
910 * Input Args:
911 * vm - Virtual Machine
912 * hva - Host virtual address
913 *
914 * Output Args: None
915 *
916 * Return:
917 * Equivalent VM physical address
918 *
919 * Locates the memory region containing the host virtual address given
920 * by hva, within the VM given by vm. When found, the equivalent
921 * VM physical address is returned. A TEST_ASSERT failure occurs if no
922 * region containing hva exists.
923 */
924vm_paddr_t addr_hva2gpa(struct kvm_vm *vm, void *hva)
925{
926 struct userspace_mem_region *region;
927 for (region = vm->userspace_mem_region_head; region;
928 region = region->next) {
929 if ((hva >= region->host_mem)
930 && (hva <= (region->host_mem
931 + region->region.memory_size - 1)))
932 return (vm_paddr_t) ((uintptr_t)
933 region->region.guest_phys_addr
934 + (hva - (uintptr_t) region->host_mem));
935 }
936
937 TEST_ASSERT(false, "No mapping to a guest physical address, "
938 "hva: %p", hva);
939 return -1;
940}
941
942/* VM Create IRQ Chip
943 *
944 * Input Args:
945 * vm - Virtual Machine
946 *
947 * Output Args: None
948 *
949 * Return: None
950 *
951 * Creates an interrupt controller chip for the VM specified by vm.
952 */
953void vm_create_irqchip(struct kvm_vm *vm)
954{
955 int ret;
956
957 ret = ioctl(vm->fd, KVM_CREATE_IRQCHIP, 0);
958 TEST_ASSERT(ret == 0, "KVM_CREATE_IRQCHIP IOCTL failed, "
959 "rc: %i errno: %i", ret, errno);
960}
961
962/* VM VCPU State
963 *
964 * Input Args:
965 * vm - Virtual Machine
966 * vcpuid - VCPU ID
967 *
968 * Output Args: None
969 *
970 * Return:
971 * Pointer to structure that describes the state of the VCPU.
972 *
973 * Locates and returns a pointer to a structure that describes the
974 * state of the VCPU with the given vcpuid.
975 */
976struct kvm_run *vcpu_state(struct kvm_vm *vm, uint32_t vcpuid)
977{
978 struct vcpu *vcpu = vcpu_find(vm, vcpuid);
979 TEST_ASSERT(vcpu != NULL, "vcpu not found, vcpuid: %u", vcpuid);
980
981 return vcpu->state;
982}
983
984/* VM VCPU Run
985 *
986 * Input Args:
987 * vm - Virtual Machine
988 * vcpuid - VCPU ID
989 *
990 * Output Args: None
991 *
992 * Return: None
993 *
994 * Switch to executing the code for the VCPU given by vcpuid, within the VM
995 * given by vm.
996 */
997void vcpu_run(struct kvm_vm *vm, uint32_t vcpuid)
998{
999 int ret = _vcpu_run(vm, vcpuid);
1000 TEST_ASSERT(ret == 0, "KVM_RUN IOCTL failed, "
1001 "rc: %i errno: %i", ret, errno);
1002}
1003
1004int _vcpu_run(struct kvm_vm *vm, uint32_t vcpuid)
1005{
1006 struct vcpu *vcpu = vcpu_find(vm, vcpuid);
1007 int rc;
1008
1009 TEST_ASSERT(vcpu != NULL, "vcpu not found, vcpuid: %u", vcpuid);
1010 do {
1011 rc = ioctl(vcpu->fd, KVM_RUN, NULL);
1012 } while (rc == -1 && errno == EINTR);
1013 return rc;
1014}
1015
1016/* VM VCPU Set MP State
1017 *
1018 * Input Args:
1019 * vm - Virtual Machine
1020 * vcpuid - VCPU ID
1021 * mp_state - mp_state to be set
1022 *
1023 * Output Args: None
1024 *
1025 * Return: None
1026 *
1027 * Sets the MP state of the VCPU given by vcpuid, to the state given
1028 * by mp_state.
1029 */
1030void vcpu_set_mp_state(struct kvm_vm *vm, uint32_t vcpuid,
1031 struct kvm_mp_state *mp_state)
1032{
1033 struct vcpu *vcpu = vcpu_find(vm, vcpuid);
1034 int ret;
1035
1036 TEST_ASSERT(vcpu != NULL, "vcpu not found, vcpuid: %u", vcpuid);
1037
1038 ret = ioctl(vcpu->fd, KVM_SET_MP_STATE, mp_state);
1039 TEST_ASSERT(ret == 0, "KVM_SET_MP_STATE IOCTL failed, "
1040 "rc: %i errno: %i", ret, errno);
1041}
1042
1043/* VM VCPU Regs Get
1044 *
1045 * Input Args:
1046 * vm - Virtual Machine
1047 * vcpuid - VCPU ID
1048 *
1049 * Output Args:
1050 * regs - current state of VCPU regs
1051 *
1052 * Return: None
1053 *
1054 * Obtains the current register state for the VCPU specified by vcpuid
1055 * and stores it at the location given by regs.
1056 */
1057void vcpu_regs_get(struct kvm_vm *vm,
1058 uint32_t vcpuid, struct kvm_regs *regs)
1059{
1060 struct vcpu *vcpu = vcpu_find(vm, vcpuid);
1061 int ret;
1062
1063 TEST_ASSERT(vcpu != NULL, "vcpu not found, vcpuid: %u", vcpuid);
1064
1065 /* Get the regs. */
1066 ret = ioctl(vcpu->fd, KVM_GET_REGS, regs);
1067 TEST_ASSERT(ret == 0, "KVM_GET_REGS failed, rc: %i errno: %i",
1068 ret, errno);
1069}
1070
1071/* VM VCPU Regs Set
1072 *
1073 * Input Args:
1074 * vm - Virtual Machine
1075 * vcpuid - VCPU ID
1076 * regs - Values to set VCPU regs to
1077 *
1078 * Output Args: None
1079 *
1080 * Return: None
1081 *
1082 * Sets the regs of the VCPU specified by vcpuid to the values
1083 * given by regs.
1084 */
1085void vcpu_regs_set(struct kvm_vm *vm,
1086 uint32_t vcpuid, struct kvm_regs *regs)
1087{
1088 struct vcpu *vcpu = vcpu_find(vm, vcpuid);
1089 int ret;
1090
1091 TEST_ASSERT(vcpu != NULL, "vcpu not found, vcpuid: %u", vcpuid);
1092
1093 /* Set the regs. */
1094 ret = ioctl(vcpu->fd, KVM_SET_REGS, regs);
1095 TEST_ASSERT(ret == 0, "KVM_SET_REGS failed, rc: %i errno: %i",
1096 ret, errno);
1097}
1098
1099void vcpu_events_get(struct kvm_vm *vm, uint32_t vcpuid,
1100 struct kvm_vcpu_events *events)
1101{
1102 struct vcpu *vcpu = vcpu_find(vm, vcpuid);
1103 int ret;
1104
1105 TEST_ASSERT(vcpu != NULL, "vcpu not found, vcpuid: %u", vcpuid);
1106
1107 /* Get the regs. */
1108 ret = ioctl(vcpu->fd, KVM_GET_VCPU_EVENTS, events);
1109 TEST_ASSERT(ret == 0, "KVM_GET_VCPU_EVENTS, failed, rc: %i errno: %i",
1110 ret, errno);
1111}
1112
1113void vcpu_events_set(struct kvm_vm *vm, uint32_t vcpuid,
1114 struct kvm_vcpu_events *events)
1115{
1116 struct vcpu *vcpu = vcpu_find(vm, vcpuid);
1117 int ret;
1118
1119 TEST_ASSERT(vcpu != NULL, "vcpu not found, vcpuid: %u", vcpuid);
1120
1121 /* Set the regs. */
1122 ret = ioctl(vcpu->fd, KVM_SET_VCPU_EVENTS, events);
1123 TEST_ASSERT(ret == 0, "KVM_SET_VCPU_EVENTS, failed, rc: %i errno: %i",
1124 ret, errno);
1125}
1126
1127/* VM VCPU Args Set
1128 *
1129 * Input Args:
1130 * vm - Virtual Machine
1131 * vcpuid - VCPU ID
1132 * num - number of arguments
1133 * ... - arguments, each of type uint64_t
1134 *
1135 * Output Args: None
1136 *
1137 * Return: None
1138 *
1139 * Sets the first num function input arguments to the values
1140 * given as variable args. Each of the variable args is expected to
1141 * be of type uint64_t.
1142 */
1143void vcpu_args_set(struct kvm_vm *vm, uint32_t vcpuid, unsigned int num, ...)
1144{
1145 va_list ap;
1146 struct kvm_regs regs;
1147
1148 TEST_ASSERT(num >= 1 && num <= 6, "Unsupported number of args,\n"
1149 " num: %u\n",
1150 num);
1151
1152 va_start(ap, num);
1153 vcpu_regs_get(vm, vcpuid, &regs);
1154
1155 if (num >= 1)
1156 regs.rdi = va_arg(ap, uint64_t);
1157
1158 if (num >= 2)
1159 regs.rsi = va_arg(ap, uint64_t);
1160
1161 if (num >= 3)
1162 regs.rdx = va_arg(ap, uint64_t);
1163
1164 if (num >= 4)
1165 regs.rcx = va_arg(ap, uint64_t);
1166
1167 if (num >= 5)
1168 regs.r8 = va_arg(ap, uint64_t);
1169
1170 if (num >= 6)
1171 regs.r9 = va_arg(ap, uint64_t);
1172
1173 vcpu_regs_set(vm, vcpuid, &regs);
1174 va_end(ap);
1175}
1176
1177/* VM VCPU System Regs Get
1178 *
1179 * Input Args:
1180 * vm - Virtual Machine
1181 * vcpuid - VCPU ID
1182 *
1183 * Output Args:
1184 * sregs - current state of VCPU system regs
1185 *
1186 * Return: None
1187 *
1188 * Obtains the current system register state for the VCPU specified by
1189 * vcpuid and stores it at the location given by sregs.
1190 */
1191void vcpu_sregs_get(struct kvm_vm *vm,
1192 uint32_t vcpuid, struct kvm_sregs *sregs)
1193{
1194 struct vcpu *vcpu = vcpu_find(vm, vcpuid);
1195 int ret;
1196
1197 TEST_ASSERT(vcpu != NULL, "vcpu not found, vcpuid: %u", vcpuid);
1198
1199 /* Get the regs. */
1200 /* Get the regs. */
1201 ret = ioctl(vcpu->fd, KVM_GET_SREGS, sregs);
1202 TEST_ASSERT(ret == 0, "KVM_GET_SREGS failed, rc: %i errno: %i",
1203 ret, errno);
1204}
1205
1206/* VM VCPU System Regs Set
1207 *
1208 * Input Args:
1209 * vm - Virtual Machine
1210 * vcpuid - VCPU ID
1211 * sregs - Values to set VCPU system regs to
1212 *
1213 * Output Args: None
1214 *
1215 * Return: None
1216 *
1217 * Sets the system regs of the VCPU specified by vcpuid to the values
1218 * given by sregs.
1219 */
1220void vcpu_sregs_set(struct kvm_vm *vm,
1221 uint32_t vcpuid, struct kvm_sregs *sregs)
1222{
1223 int ret = _vcpu_sregs_set(vm, vcpuid, sregs);
1224 TEST_ASSERT(ret == 0, "KVM_RUN IOCTL failed, "
1225 "rc: %i errno: %i", ret, errno);
1226}
1227
1228int _vcpu_sregs_set(struct kvm_vm *vm,
1229 uint32_t vcpuid, struct kvm_sregs *sregs)
1230{
1231 struct vcpu *vcpu = vcpu_find(vm, vcpuid);
1232 int ret;
1233
1234 TEST_ASSERT(vcpu != NULL, "vcpu not found, vcpuid: %u", vcpuid);
1235
1236 /* Get the regs. */
1237 return ioctl(vcpu->fd, KVM_SET_SREGS, sregs);
1238}
1239
1240/* VCPU Ioctl
1241 *
1242 * Input Args:
1243 * vm - Virtual Machine
1244 * vcpuid - VCPU ID
1245 * cmd - Ioctl number
1246 * arg - Argument to pass to the ioctl
1247 *
1248 * Return: None
1249 *
1250 * Issues an arbitrary ioctl on a VCPU fd.
1251 */
1252void vcpu_ioctl(struct kvm_vm *vm,
1253 uint32_t vcpuid, unsigned long cmd, void *arg)
1254{
1255 struct vcpu *vcpu = vcpu_find(vm, vcpuid);
1256 int ret;
1257
1258 TEST_ASSERT(vcpu != NULL, "vcpu not found, vcpuid: %u", vcpuid);
1259
1260 ret = ioctl(vcpu->fd, cmd, arg);
1261 TEST_ASSERT(ret == 0, "vcpu ioctl %lu failed, rc: %i errno: %i (%s)",
1262 cmd, ret, errno, strerror(errno));
1263}
1264
1265/* VM Ioctl
1266 *
1267 * Input Args:
1268 * vm - Virtual Machine
1269 * cmd - Ioctl number
1270 * arg - Argument to pass to the ioctl
1271 *
1272 * Return: None
1273 *
1274 * Issues an arbitrary ioctl on a VM fd.
1275 */
1276void vm_ioctl(struct kvm_vm *vm, unsigned long cmd, void *arg)
1277{
1278 int ret;
1279
1280 ret = ioctl(vm->fd, cmd, arg);
1281 TEST_ASSERT(ret == 0, "vm ioctl %lu failed, rc: %i errno: %i (%s)",
1282 cmd, ret, errno, strerror(errno));
1283}
1284
1285/* VM Dump
1286 *
1287 * Input Args:
1288 * vm - Virtual Machine
1289 * indent - Left margin indent amount
1290 *
1291 * Output Args:
1292 * stream - Output FILE stream
1293 *
1294 * Return: None
1295 *
1296 * Dumps the current state of the VM given by vm, to the FILE stream
1297 * given by stream.
1298 */
1299void vm_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent)
1300{
1301 struct userspace_mem_region *region;
1302 struct vcpu *vcpu;
1303
1304 fprintf(stream, "%*smode: 0x%x\n", indent, "", vm->mode);
1305 fprintf(stream, "%*sfd: %i\n", indent, "", vm->fd);
1306 fprintf(stream, "%*spage_size: 0x%x\n", indent, "", vm->page_size);
1307 fprintf(stream, "%*sMem Regions:\n", indent, "");
1308 for (region = vm->userspace_mem_region_head; region;
1309 region = region->next) {
1310 fprintf(stream, "%*sguest_phys: 0x%lx size: 0x%lx "
1311 "host_virt: %p\n", indent + 2, "",
1312 (uint64_t) region->region.guest_phys_addr,
1313 (uint64_t) region->region.memory_size,
1314 region->host_mem);
1315 fprintf(stream, "%*sunused_phy_pages: ", indent + 2, "");
1316 sparsebit_dump(stream, region->unused_phy_pages, 0);
1317 }
1318 fprintf(stream, "%*sMapped Virtual Pages:\n", indent, "");
1319 sparsebit_dump(stream, vm->vpages_mapped, indent + 2);
1320 fprintf(stream, "%*spgd_created: %u\n", indent, "",
1321 vm->pgd_created);
1322 if (vm->pgd_created) {
1323 fprintf(stream, "%*sVirtual Translation Tables:\n",
1324 indent + 2, "");
1325 virt_dump(stream, vm, indent + 4);
1326 }
1327 fprintf(stream, "%*sVCPUs:\n", indent, "");
1328 for (vcpu = vm->vcpu_head; vcpu; vcpu = vcpu->next)
1329 vcpu_dump(stream, vm, vcpu->id, indent + 2);
1330}
1331
1332/* VM VCPU Dump
1333 *
1334 * Input Args:
1335 * vm - Virtual Machine
1336 * vcpuid - VCPU ID
1337 * indent - Left margin indent amount
1338 *
1339 * Output Args:
1340 * stream - Output FILE stream
1341 *
1342 * Return: None
1343 *
1344 * Dumps the current state of the VCPU specified by vcpuid, within the VM
1345 * given by vm, to the FILE stream given by stream.
1346 */
1347void vcpu_dump(FILE *stream, struct kvm_vm *vm,
1348 uint32_t vcpuid, uint8_t indent)
1349{
1350 struct kvm_regs regs;
1351 struct kvm_sregs sregs;
1352
1353 fprintf(stream, "%*scpuid: %u\n", indent, "", vcpuid);
1354
1355 fprintf(stream, "%*sregs:\n", indent + 2, "");
1356 vcpu_regs_get(vm, vcpuid, &regs);
1357 regs_dump(stream, &regs, indent + 4);
1358
1359 fprintf(stream, "%*ssregs:\n", indent + 2, "");
1360 vcpu_sregs_get(vm, vcpuid, &sregs);
1361 sregs_dump(stream, &sregs, indent + 4);
1362}
1363
1364/* Known KVM exit reasons */
1365static struct exit_reason {
1366 unsigned int reason;
1367 const char *name;
1368} exit_reasons_known[] = {
1369 {KVM_EXIT_UNKNOWN, "UNKNOWN"},
1370 {KVM_EXIT_EXCEPTION, "EXCEPTION"},
1371 {KVM_EXIT_IO, "IO"},
1372 {KVM_EXIT_HYPERCALL, "HYPERCALL"},
1373 {KVM_EXIT_DEBUG, "DEBUG"},
1374 {KVM_EXIT_HLT, "HLT"},
1375 {KVM_EXIT_MMIO, "MMIO"},
1376 {KVM_EXIT_IRQ_WINDOW_OPEN, "IRQ_WINDOW_OPEN"},
1377 {KVM_EXIT_SHUTDOWN, "SHUTDOWN"},
1378 {KVM_EXIT_FAIL_ENTRY, "FAIL_ENTRY"},
1379 {KVM_EXIT_INTR, "INTR"},
1380 {KVM_EXIT_SET_TPR, "SET_TPR"},
1381 {KVM_EXIT_TPR_ACCESS, "TPR_ACCESS"},
1382 {KVM_EXIT_S390_SIEIC, "S390_SIEIC"},
1383 {KVM_EXIT_S390_RESET, "S390_RESET"},
1384 {KVM_EXIT_DCR, "DCR"},
1385 {KVM_EXIT_NMI, "NMI"},
1386 {KVM_EXIT_INTERNAL_ERROR, "INTERNAL_ERROR"},
1387 {KVM_EXIT_OSI, "OSI"},
1388 {KVM_EXIT_PAPR_HCALL, "PAPR_HCALL"},
1389#ifdef KVM_EXIT_MEMORY_NOT_PRESENT
1390 {KVM_EXIT_MEMORY_NOT_PRESENT, "MEMORY_NOT_PRESENT"},
1391#endif
1392};
1393
1394/* Exit Reason String
1395 *
1396 * Input Args:
1397 * exit_reason - Exit reason
1398 *
1399 * Output Args: None
1400 *
1401 * Return:
1402 * Constant string pointer describing the exit reason.
1403 *
1404 * Locates and returns a constant string that describes the KVM exit
1405 * reason given by exit_reason. If no such string is found, a constant
1406 * string of "Unknown" is returned.
1407 */
1408const char *exit_reason_str(unsigned int exit_reason)
1409{
1410 unsigned int n1;
1411
1412 for (n1 = 0; n1 < ARRAY_SIZE(exit_reasons_known); n1++) {
1413 if (exit_reason == exit_reasons_known[n1].reason)
1414 return exit_reasons_known[n1].name;
1415 }
1416
1417 return "Unknown";
1418}
1419
1420/* Physical Page Allocate
1421 *
1422 * Input Args:
1423 * vm - Virtual Machine
1424 * paddr_min - Physical address minimum
1425 * memslot - Memory region to allocate page from
1426 *
1427 * Output Args: None
1428 *
1429 * Return:
1430 * Starting physical address
1431 *
1432 * Within the VM specified by vm, locates an available physical page
1433 * at or above paddr_min. If found, the page is marked as in use
1434 * and its address is returned. A TEST_ASSERT failure occurs if no
1435 * page is available at or above paddr_min.
1436 */
1437vm_paddr_t vm_phy_page_alloc(struct kvm_vm *vm,
1438 vm_paddr_t paddr_min, uint32_t memslot)
1439{
1440 struct userspace_mem_region *region;
1441 sparsebit_idx_t pg;
1442
1443 TEST_ASSERT((paddr_min % vm->page_size) == 0, "Min physical address "
1444 "not divisible by page size.\n"
1445 " paddr_min: 0x%lx page_size: 0x%x",
1446 paddr_min, vm->page_size);
1447
1448 /* Locate memory region. */
1449 region = memslot2region(vm, memslot);
1450
1451 /* Locate next available physical page at or above paddr_min. */
1452 pg = paddr_min >> vm->page_shift;
1453
1454 if (!sparsebit_is_set(region->unused_phy_pages, pg)) {
1455 pg = sparsebit_next_set(region->unused_phy_pages, pg);
1456 if (pg == 0) {
1457 fprintf(stderr, "No guest physical page available, "
1458 "paddr_min: 0x%lx page_size: 0x%x memslot: %u",
1459 paddr_min, vm->page_size, memslot);
1460 fputs("---- vm dump ----\n", stderr);
1461 vm_dump(stderr, vm, 2);
1462 abort();
1463 }
1464 }
1465
1466 /* Specify page as in use and return its address. */
1467 sparsebit_clear(region->unused_phy_pages, pg);
1468
1469 return pg * vm->page_size;
1470}
1471
1472/* Address Guest Virtual to Host Virtual
1473 *
1474 * Input Args:
1475 * vm - Virtual Machine
1476 * gva - VM virtual address
1477 *
1478 * Output Args: None
1479 *
1480 * Return:
1481 * Equivalent host virtual address
1482 */
1483void *addr_gva2hva(struct kvm_vm *vm, vm_vaddr_t gva)
1484{
1485 return addr_gpa2hva(vm, addr_gva2gpa(vm, gva));
1486}
diff --git a/tools/testing/selftests/kvm/lib/kvm_util_internal.h b/tools/testing/selftests/kvm/lib/kvm_util_internal.h
new file mode 100644
index 000000000000..a0bd1980c81c
--- /dev/null
+++ b/tools/testing/selftests/kvm/lib/kvm_util_internal.h
@@ -0,0 +1,67 @@
1/*
2 * tools/testing/selftests/kvm/lib/kvm_util.c
3 *
4 * Copyright (C) 2018, Google LLC.
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2.
7 */
8
9#ifndef KVM_UTIL_INTERNAL_H
10#define KVM_UTIL_INTERNAL_H 1
11
12#include "sparsebit.h"
13
14#ifndef BITS_PER_BYTE
15#define BITS_PER_BYTE 8
16#endif
17
18#ifndef BITS_PER_LONG
19#define BITS_PER_LONG (BITS_PER_BYTE * sizeof(long))
20#endif
21
22#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
23#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_LONG)
24
25/* Concrete definition of struct kvm_vm. */
26struct userspace_mem_region {
27 struct userspace_mem_region *next, *prev;
28 struct kvm_userspace_memory_region region;
29 struct sparsebit *unused_phy_pages;
30 int fd;
31 off_t offset;
32 void *host_mem;
33 void *mmap_start;
34 size_t mmap_size;
35};
36
37struct vcpu {
38 struct vcpu *next, *prev;
39 uint32_t id;
40 int fd;
41 struct kvm_run *state;
42};
43
44struct kvm_vm {
45 int mode;
46 int fd;
47 unsigned int page_size;
48 unsigned int page_shift;
49 uint64_t max_gfn;
50 struct vcpu *vcpu_head;
51 struct userspace_mem_region *userspace_mem_region_head;
52 struct sparsebit *vpages_valid;
53 struct sparsebit *vpages_mapped;
54 bool pgd_created;
55 vm_paddr_t pgd;
56};
57
58struct vcpu *vcpu_find(struct kvm_vm *vm,
59 uint32_t vcpuid);
60void vcpu_setup(struct kvm_vm *vm, int vcpuid);
61void virt_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent);
62void regs_dump(FILE *stream, struct kvm_regs *regs,
63 uint8_t indent);
64void sregs_dump(FILE *stream, struct kvm_sregs *sregs,
65 uint8_t indent);
66
67#endif
diff --git a/tools/testing/selftests/kvm/lib/sparsebit.c b/tools/testing/selftests/kvm/lib/sparsebit.c
new file mode 100644
index 000000000000..b132bc95d183
--- /dev/null
+++ b/tools/testing/selftests/kvm/lib/sparsebit.c
@@ -0,0 +1,2087 @@
1/*
2 * Sparse bit array
3 *
4 * Copyright (C) 2018, Google LLC.
5 * Copyright (C) 2018, Red Hat, Inc. (code style cleanup and fuzzing driver)
6 *
7 * This work is licensed under the terms of the GNU GPL, version 2.
8 *
9 * This library provides functions to support a memory efficient bit array,
10 * with an index size of 2^64. A sparsebit array is allocated through
11 * the use sparsebit_alloc() and free'd via sparsebit_free(),
12 * such as in the following:
13 *
14 * struct sparsebit *s;
15 * s = sparsebit_alloc();
16 * sparsebit_free(&s);
17 *
18 * The struct sparsebit type resolves down to a struct sparsebit.
19 * Note that, sparsebit_free() takes a pointer to the sparsebit
20 * structure. This is so that sparsebit_free() is able to poison
21 * the pointer (e.g. set it to NULL) to the struct sparsebit before
22 * returning to the caller.
23 *
24 * Between the return of sparsebit_alloc() and the call of
25 * sparsebit_free(), there are multiple query and modifying operations
26 * that can be performed on the allocated sparsebit array. All of
27 * these operations take as a parameter the value returned from
28 * sparsebit_alloc() and most also take a bit index. Frequently
29 * used routines include:
30 *
31 * ---- Query Operations
32 * sparsebit_is_set(s, idx)
33 * sparsebit_is_clear(s, idx)
34 * sparsebit_any_set(s)
35 * sparsebit_first_set(s)
36 * sparsebit_next_set(s, prev_idx)
37 *
38 * ---- Modifying Operations
39 * sparsebit_set(s, idx)
40 * sparsebit_clear(s, idx)
41 * sparsebit_set_num(s, idx, num);
42 * sparsebit_clear_num(s, idx, num);
43 *
44 * A common operation, is to itterate over all the bits set in a test
45 * sparsebit array. This can be done via code with the following structure:
46 *
47 * sparsebit_idx_t idx;
48 * if (sparsebit_any_set(s)) {
49 * idx = sparsebit_first_set(s);
50 * do {
51 * ...
52 * idx = sparsebit_next_set(s, idx);
53 * } while (idx != 0);
54 * }
55 *
56 * The index of the first bit set needs to be obtained via
57 * sparsebit_first_set(), because sparsebit_next_set(), needs
58 * the index of the previously set. The sparsebit_idx_t type is
59 * unsigned, so there is no previous index before 0 that is available.
60 * Also, the call to sparsebit_first_set() is not made unless there
61 * is at least 1 bit in the array set. This is because sparsebit_first_set()
62 * aborts if sparsebit_first_set() is called with no bits set.
63 * It is the callers responsibility to assure that the
64 * sparsebit array has at least a single bit set before calling
65 * sparsebit_first_set().
66 *
67 * ==== Implementation Overview ====
68 * For the most part the internal implementation of sparsebit is
69 * opaque to the caller. One important implementation detail that the
70 * caller may need to be aware of is the spatial complexity of the
71 * implementation. This implementation of a sparsebit array is not
72 * only sparse, in that it uses memory proportional to the number of bits
73 * set. It is also efficient in memory usage when most of the bits are
74 * set.
75 *
76 * At a high-level the state of the bit settings are maintained through
77 * the use of a binary-search tree, where each node contains at least
78 * the following members:
79 *
80 * typedef uint64_t sparsebit_idx_t;
81 * typedef uint64_t sparsebit_num_t;
82 *
83 * sparsebit_idx_t idx;
84 * uint32_t mask;
85 * sparsebit_num_t num_after;
86 *
87 * The idx member contains the bit index of the first bit described by this
88 * node, while the mask member stores the setting of the first 32-bits.
89 * The setting of the bit at idx + n, where 0 <= n < 32, is located in the
90 * mask member at 1 << n.
91 *
92 * Nodes are sorted by idx and the bits described by two nodes will never
93 * overlap. The idx member is always aligned to the mask size, i.e. a
94 * multiple of 32.
95 *
96 * Beyond a typical implementation, the nodes in this implementation also
97 * contains a member named num_after. The num_after member holds the
98 * number of bits immediately after the mask bits that are contiguously set.
99 * The use of the num_after member allows this implementation to efficiently
100 * represent cases where most bits are set. For example, the case of all
101 * but the last two bits set, is represented by the following two nodes:
102 *
103 * node 0 - idx: 0x0 mask: 0xffffffff num_after: 0xffffffffffffffc0
104 * node 1 - idx: 0xffffffffffffffe0 mask: 0x3fffffff num_after: 0
105 *
106 * ==== Invariants ====
107 * This implementation usses the following invariants:
108 *
109 * + Node are only used to represent bits that are set.
110 * Nodes with a mask of 0 and num_after of 0 are not allowed.
111 *
112 * + Sum of bits set in all the nodes is equal to the value of
113 * the struct sparsebit_pvt num_set member.
114 *
115 * + The setting of at least one bit is always described in a nodes
116 * mask (mask >= 1).
117 *
118 * + A node with all mask bits set only occurs when the last bit
119 * described by the previous node is not equal to this nodes
120 * starting index - 1. All such occurences of this condition are
121 * avoided by moving the setting of the nodes mask bits into
122 * the previous nodes num_after setting.
123 *
124 * + Node starting index is evenly divisible by the number of bits
125 * within a nodes mask member.
126 *
127 * + Nodes never represent a range of bits that wrap around the
128 * highest supported index.
129 *
130 * (idx + MASK_BITS + num_after - 1) <= ((sparsebit_idx_t) 0) - 1)
131 *
132 * As a consequence of the above, the num_after member of a node
133 * will always be <=:
134 *
135 * maximum_index - nodes_starting_index - number_of_mask_bits
136 *
137 * + Nodes within the binary search tree are sorted based on each
138 * nodes starting index.
139 *
140 * + The range of bits described by any two nodes do not overlap. The
141 * range of bits described by a single node is:
142 *
143 * start: node->idx
144 * end (inclusive): node->idx + MASK_BITS + node->num_after - 1;
145 *
146 * Note, at times these invariants are temporarily violated for a
147 * specific portion of the code. For example, when setting a mask
148 * bit, there is a small delay between when the mask bit is set and the
149 * value in the struct sparsebit_pvt num_set member is updated. Other
150 * temporary violations occur when node_split() is called with a specified
151 * index and assures that a node where its mask represents the bit
152 * at the specified index exists. At times to do this node_split()
153 * must split an existing node into two nodes or create a node that
154 * has no bits set. Such temporary violations must be corrected before
155 * returning to the caller. These corrections are typically performed
156 * by the local function node_reduce().
157 */
158
159#include "test_util.h"
160#include "sparsebit.h"
161#include <limits.h>
162#include <assert.h>
163
164#define DUMP_LINE_MAX 100 /* Does not include indent amount */
165
166typedef uint32_t mask_t;
167#define MASK_BITS (sizeof(mask_t) * CHAR_BIT)
168
169struct node {
170 struct node *parent;
171 struct node *left;
172 struct node *right;
173 sparsebit_idx_t idx; /* index of least-significant bit in mask */
174 sparsebit_num_t num_after; /* num contiguously set after mask */
175 mask_t mask;
176};
177
178struct sparsebit {
179 /*
180 * Points to root node of the binary search
181 * tree. Equal to NULL when no bits are set in
182 * the entire sparsebit array.
183 */
184 struct node *root;
185
186 /*
187 * A redundant count of the total number of bits set. Used for
188 * diagnostic purposes and to change the time complexity of
189 * sparsebit_num_set() from O(n) to O(1).
190 * Note: Due to overflow, a value of 0 means none or all set.
191 */
192 sparsebit_num_t num_set;
193};
194
195/* Returns the number of set bits described by the settings
196 * of the node pointed to by nodep.
197 */
198static sparsebit_num_t node_num_set(struct node *nodep)
199{
200 return nodep->num_after + __builtin_popcount(nodep->mask);
201}
202
203/* Returns a pointer to the node that describes the
204 * lowest bit index.
205 */
206static struct node *node_first(struct sparsebit *s)
207{
208 struct node *nodep;
209
210 for (nodep = s->root; nodep && nodep->left; nodep = nodep->left)
211 ;
212
213 return nodep;
214}
215
216/* Returns a pointer to the node that describes the
217 * lowest bit index > the index of the node pointed to by np.
218 * Returns NULL if no node with a higher index exists.
219 */
220static struct node *node_next(struct sparsebit *s, struct node *np)
221{
222 struct node *nodep = np;
223
224 /*
225 * If current node has a right child, next node is the left-most
226 * of the right child.
227 */
228 if (nodep->right) {
229 for (nodep = nodep->right; nodep->left; nodep = nodep->left)
230 ;
231 return nodep;
232 }
233
234 /*
235 * No right child. Go up until node is left child of a parent.
236 * That parent is then the next node.
237 */
238 while (nodep->parent && nodep == nodep->parent->right)
239 nodep = nodep->parent;
240
241 return nodep->parent;
242}
243
244/* Searches for and returns a pointer to the node that describes the
245 * highest index < the index of the node pointed to by np.
246 * Returns NULL if no node with a lower index exists.
247 */
248static struct node *node_prev(struct sparsebit *s, struct node *np)
249{
250 struct node *nodep = np;
251
252 /*
253 * If current node has a left child, next node is the right-most
254 * of the left child.
255 */
256 if (nodep->left) {
257 for (nodep = nodep->left; nodep->right; nodep = nodep->right)
258 ;
259 return (struct node *) nodep;
260 }
261
262 /*
263 * No left child. Go up until node is right child of a parent.
264 * That parent is then the next node.
265 */
266 while (nodep->parent && nodep == nodep->parent->left)
267 nodep = nodep->parent;
268
269 return (struct node *) nodep->parent;
270}
271
272
273/* Allocates space to hold a copy of the node sub-tree pointed to by
274 * subtree and duplicates the bit settings to the newly allocated nodes.
275 * Returns the newly allocated copy of subtree.
276 */
277static struct node *node_copy_subtree(struct node *subtree)
278{
279 struct node *root;
280
281 /* Duplicate the node at the root of the subtree */
282 root = calloc(1, sizeof(*root));
283 if (!root) {
284 perror("calloc");
285 abort();
286 }
287
288 root->idx = subtree->idx;
289 root->mask = subtree->mask;
290 root->num_after = subtree->num_after;
291
292 /* As needed, recursively duplicate the left and right subtrees */
293 if (subtree->left) {
294 root->left = node_copy_subtree(subtree->left);
295 root->left->parent = root;
296 }
297
298 if (subtree->right) {
299 root->right = node_copy_subtree(subtree->right);
300 root->right->parent = root;
301 }
302
303 return root;
304}
305
306/* Searches for and returns a pointer to the node that describes the setting
307 * of the bit given by idx. A node describes the setting of a bit if its
308 * index is within the bits described by the mask bits or the number of
309 * contiguous bits set after the mask. Returns NULL if there is no such node.
310 */
311static struct node *node_find(struct sparsebit *s, sparsebit_idx_t idx)
312{
313 struct node *nodep;
314
315 /* Find the node that describes the setting of the bit at idx */
316 for (nodep = s->root; nodep;
317 nodep = nodep->idx > idx ? nodep->left : nodep->right) {
318 if (idx >= nodep->idx &&
319 idx <= nodep->idx + MASK_BITS + nodep->num_after - 1)
320 break;
321 }
322
323 return nodep;
324}
325
326/* Entry Requirements:
327 * + A node that describes the setting of idx is not already present.
328 *
329 * Adds a new node to describe the setting of the bit at the index given
330 * by idx. Returns a pointer to the newly added node.
331 *
332 * TODO(lhuemill): Degenerate cases causes the tree to get unbalanced.
333 */
334static struct node *node_add(struct sparsebit *s, sparsebit_idx_t idx)
335{
336 struct node *nodep, *parentp, *prev;
337
338 /* Allocate and initialize the new node. */
339 nodep = calloc(1, sizeof(*nodep));
340 if (!nodep) {
341 perror("calloc");
342 abort();
343 }
344
345 nodep->idx = idx & -MASK_BITS;
346
347 /* If no nodes, set it up as the root node. */
348 if (!s->root) {
349 s->root = nodep;
350 return nodep;
351 }
352
353 /*
354 * Find the parent where the new node should be attached
355 * and add the node there.
356 */
357 parentp = s->root;
358 while (true) {
359 if (idx < parentp->idx) {
360 if (!parentp->left) {
361 parentp->left = nodep;
362 nodep->parent = parentp;
363 break;
364 }
365 parentp = parentp->left;
366 } else {
367 assert(idx > parentp->idx + MASK_BITS + parentp->num_after - 1);
368 if (!parentp->right) {
369 parentp->right = nodep;
370 nodep->parent = parentp;
371 break;
372 }
373 parentp = parentp->right;
374 }
375 }
376
377 /*
378 * Does num_after bits of previous node overlap with the mask
379 * of the new node? If so set the bits in the new nodes mask
380 * and reduce the previous nodes num_after.
381 */
382 prev = node_prev(s, nodep);
383 while (prev && prev->idx + MASK_BITS + prev->num_after - 1 >= nodep->idx) {
384 unsigned int n1 = (prev->idx + MASK_BITS + prev->num_after - 1)
385 - nodep->idx;
386 assert(prev->num_after > 0);
387 assert(n1 < MASK_BITS);
388 assert(!(nodep->mask & (1 << n1)));
389 nodep->mask |= (1 << n1);
390 prev->num_after--;
391 }
392
393 return nodep;
394}
395
396/* Returns whether all the bits in the sparsebit array are set. */
397bool sparsebit_all_set(struct sparsebit *s)
398{
399 /*
400 * If any nodes there must be at least one bit set. Only case
401 * where a bit is set and total num set is 0, is when all bits
402 * are set.
403 */
404 return s->root && s->num_set == 0;
405}
406
407/* Clears all bits described by the node pointed to by nodep, then
408 * removes the node.
409 */
410static void node_rm(struct sparsebit *s, struct node *nodep)
411{
412 struct node *tmp;
413 sparsebit_num_t num_set;
414
415 num_set = node_num_set(nodep);
416 assert(s->num_set >= num_set || sparsebit_all_set(s));
417 s->num_set -= node_num_set(nodep);
418
419 /* Have both left and right child */
420 if (nodep->left && nodep->right) {
421 /*
422 * Move left children to the leftmost leaf node
423 * of the right child.
424 */
425 for (tmp = nodep->right; tmp->left; tmp = tmp->left)
426 ;
427 tmp->left = nodep->left;
428 nodep->left = NULL;
429 tmp->left->parent = tmp;
430 }
431
432 /* Left only child */
433 if (nodep->left) {
434 if (!nodep->parent) {
435 s->root = nodep->left;
436 nodep->left->parent = NULL;
437 } else {
438 nodep->left->parent = nodep->parent;
439 if (nodep == nodep->parent->left)
440 nodep->parent->left = nodep->left;
441 else {
442 assert(nodep == nodep->parent->right);
443 nodep->parent->right = nodep->left;
444 }
445 }
446
447 nodep->parent = nodep->left = nodep->right = NULL;
448 free(nodep);
449
450 return;
451 }
452
453
454 /* Right only child */
455 if (nodep->right) {
456 if (!nodep->parent) {
457 s->root = nodep->right;
458 nodep->right->parent = NULL;
459 } else {
460 nodep->right->parent = nodep->parent;
461 if (nodep == nodep->parent->left)
462 nodep->parent->left = nodep->right;
463 else {
464 assert(nodep == nodep->parent->right);
465 nodep->parent->right = nodep->right;
466 }
467 }
468
469 nodep->parent = nodep->left = nodep->right = NULL;
470 free(nodep);
471
472 return;
473 }
474
475 /* Leaf Node */
476 if (!nodep->parent) {
477 s->root = NULL;
478 } else {
479 if (nodep->parent->left == nodep)
480 nodep->parent->left = NULL;
481 else {
482 assert(nodep == nodep->parent->right);
483 nodep->parent->right = NULL;
484 }
485 }
486
487 nodep->parent = nodep->left = nodep->right = NULL;
488 free(nodep);
489
490 return;
491}
492
493/* Splits the node containing the bit at idx so that there is a node
494 * that starts at the specified index. If no such node exists, a new
495 * node at the specified index is created. Returns the new node.
496 *
497 * idx must start of a mask boundary.
498 */
499static struct node *node_split(struct sparsebit *s, sparsebit_idx_t idx)
500{
501 struct node *nodep1, *nodep2;
502 sparsebit_idx_t offset;
503 sparsebit_num_t orig_num_after;
504
505 assert(!(idx % MASK_BITS));
506
507 /*
508 * Is there a node that describes the setting of idx?
509 * If not, add it.
510 */
511 nodep1 = node_find(s, idx);
512 if (!nodep1)
513 return node_add(s, idx);
514
515 /*
516 * All done if the starting index of the node is where the
517 * split should occur.
518 */
519 if (nodep1->idx == idx)
520 return nodep1;
521
522 /*
523 * Split point not at start of mask, so it must be part of
524 * bits described by num_after.
525 */
526
527 /*
528 * Calculate offset within num_after for where the split is
529 * to occur.
530 */
531 offset = idx - (nodep1->idx + MASK_BITS);
532 orig_num_after = nodep1->num_after;
533
534 /*
535 * Add a new node to describe the bits starting at
536 * the split point.
537 */
538 nodep1->num_after = offset;
539 nodep2 = node_add(s, idx);
540
541 /* Move bits after the split point into the new node */
542 nodep2->num_after = orig_num_after - offset;
543 if (nodep2->num_after >= MASK_BITS) {
544 nodep2->mask = ~(mask_t) 0;
545 nodep2->num_after -= MASK_BITS;
546 } else {
547 nodep2->mask = (1 << nodep2->num_after) - 1;
548 nodep2->num_after = 0;
549 }
550
551 return nodep2;
552}
553
554/* Iteratively reduces the node pointed to by nodep and its adjacent
555 * nodes into a more compact form. For example, a node with a mask with
556 * all bits set adjacent to a previous node, will get combined into a
557 * single node with an increased num_after setting.
558 *
559 * After each reduction, a further check is made to see if additional
560 * reductions are possible with the new previous and next nodes. Note,
561 * a search for a reduction is only done across the nodes nearest nodep
562 * and those that became part of a reduction. Reductions beyond nodep
563 * and the adjacent nodes that are reduced are not discovered. It is the
564 * responsibility of the caller to pass a nodep that is within one node
565 * of each possible reduction.
566 *
567 * This function does not fix the temporary violation of all invariants.
568 * For example it does not fix the case where the bit settings described
569 * by two or more nodes overlap. Such a violation introduces the potential
570 * complication of a bit setting for a specific index having different settings
571 * in different nodes. This would then introduce the further complication
572 * of which node has the correct setting of the bit and thus such conditions
573 * are not allowed.
574 *
575 * This function is designed to fix invariant violations that are introduced
576 * by node_split() and by changes to the nodes mask or num_after members.
577 * For example, when setting a bit within a nodes mask, the function that
578 * sets the bit doesn't have to worry about whether the setting of that
579 * bit caused the mask to have leading only or trailing only bits set.
580 * Instead, the function can call node_reduce(), with nodep equal to the
581 * node address that it set a mask bit in, and node_reduce() will notice
582 * the cases of leading or trailing only bits and that there is an
583 * adjacent node that the bit settings could be merged into.
584 *
585 * This implementation specifically detects and corrects violation of the
586 * following invariants:
587 *
588 * + Node are only used to represent bits that are set.
589 * Nodes with a mask of 0 and num_after of 0 are not allowed.
590 *
591 * + The setting of at least one bit is always described in a nodes
592 * mask (mask >= 1).
593 *
594 * + A node with all mask bits set only occurs when the last bit
595 * described by the previous node is not equal to this nodes
596 * starting index - 1. All such occurences of this condition are
597 * avoided by moving the setting of the nodes mask bits into
598 * the previous nodes num_after setting.
599 */
600static void node_reduce(struct sparsebit *s, struct node *nodep)
601{
602 bool reduction_performed;
603
604 do {
605 reduction_performed = false;
606 struct node *prev, *next, *tmp;
607
608 /* 1) Potential reductions within the current node. */
609
610 /* Nodes with all bits cleared may be removed. */
611 if (nodep->mask == 0 && nodep->num_after == 0) {
612 /*
613 * About to remove the node pointed to by
614 * nodep, which normally would cause a problem
615 * for the next pass through the reduction loop,
616 * because the node at the starting point no longer
617 * exists. This potential problem is handled
618 * by first remembering the location of the next
619 * or previous nodes. Doesn't matter which, because
620 * once the node at nodep is removed, there will be
621 * no other nodes between prev and next.
622 *
623 * Note, the checks performed on nodep against both
624 * both prev and next both check for an adjacent
625 * node that can be reduced into a single node. As
626 * such, after removing the node at nodep, doesn't
627 * matter whether the nodep for the next pass
628 * through the loop is equal to the previous pass
629 * prev or next node. Either way, on the next pass
630 * the one not selected will become either the
631 * prev or next node.
632 */
633 tmp = node_next(s, nodep);
634 if (!tmp)
635 tmp = node_prev(s, nodep);
636
637 node_rm(s, nodep);
638 nodep = NULL;
639
640 nodep = tmp;
641 reduction_performed = true;
642 continue;
643 }
644
645 /*
646 * When the mask is 0, can reduce the amount of num_after
647 * bits by moving the initial num_after bits into the mask.
648 */
649 if (nodep->mask == 0) {
650 assert(nodep->num_after != 0);
651 assert(nodep->idx + MASK_BITS > nodep->idx);
652
653 nodep->idx += MASK_BITS;
654
655 if (nodep->num_after >= MASK_BITS) {
656 nodep->mask = ~0;
657 nodep->num_after -= MASK_BITS;
658 } else {
659 nodep->mask = (1u << nodep->num_after) - 1;
660 nodep->num_after = 0;
661 }
662
663 reduction_performed = true;
664 continue;
665 }
666
667 /*
668 * 2) Potential reductions between the current and
669 * previous nodes.
670 */
671 prev = node_prev(s, nodep);
672 if (prev) {
673 sparsebit_idx_t prev_highest_bit;
674
675 /* Nodes with no bits set can be removed. */
676 if (prev->mask == 0 && prev->num_after == 0) {
677 node_rm(s, prev);
678
679 reduction_performed = true;
680 continue;
681 }
682
683 /*
684 * All mask bits set and previous node has
685 * adjacent index.
686 */
687 if (nodep->mask + 1 == 0 &&
688 prev->idx + MASK_BITS == nodep->idx) {
689 prev->num_after += MASK_BITS + nodep->num_after;
690 nodep->mask = 0;
691 nodep->num_after = 0;
692
693 reduction_performed = true;
694 continue;
695 }
696
697 /*
698 * Is node adjacent to previous node and the node
699 * contains a single contiguous range of bits
700 * starting from the beginning of the mask?
701 */
702 prev_highest_bit = prev->idx + MASK_BITS - 1 + prev->num_after;
703 if (prev_highest_bit + 1 == nodep->idx &&
704 (nodep->mask | (nodep->mask >> 1)) == nodep->mask) {
705 /*
706 * How many contiguous bits are there?
707 * Is equal to the total number of set
708 * bits, due to an earlier check that
709 * there is a single contiguous range of
710 * set bits.
711 */
712 unsigned int num_contiguous
713 = __builtin_popcount(nodep->mask);
714 assert((num_contiguous > 0) &&
715 ((1ULL << num_contiguous) - 1) == nodep->mask);
716
717 prev->num_after += num_contiguous;
718 nodep->mask = 0;
719
720 /*
721 * For predictable performance, handle special
722 * case where all mask bits are set and there
723 * is a non-zero num_after setting. This code
724 * is functionally correct without the following
725 * conditionalized statements, but without them
726 * the value of num_after is only reduced by
727 * the number of mask bits per pass. There are
728 * cases where num_after can be close to 2^64.
729 * Without this code it could take nearly
730 * (2^64) / 32 passes to perform the full
731 * reduction.
732 */
733 if (num_contiguous == MASK_BITS) {
734 prev->num_after += nodep->num_after;
735 nodep->num_after = 0;
736 }
737
738 reduction_performed = true;
739 continue;
740 }
741 }
742
743 /*
744 * 3) Potential reductions between the current and
745 * next nodes.
746 */
747 next = node_next(s, nodep);
748 if (next) {
749 /* Nodes with no bits set can be removed. */
750 if (next->mask == 0 && next->num_after == 0) {
751 node_rm(s, next);
752 reduction_performed = true;
753 continue;
754 }
755
756 /*
757 * Is next node index adjacent to current node
758 * and has a mask with all bits set?
759 */
760 if (next->idx == nodep->idx + MASK_BITS + nodep->num_after &&
761 next->mask == ~(mask_t) 0) {
762 nodep->num_after += MASK_BITS;
763 next->mask = 0;
764 nodep->num_after += next->num_after;
765 next->num_after = 0;
766
767 node_rm(s, next);
768 next = NULL;
769
770 reduction_performed = true;
771 continue;
772 }
773 }
774 } while (nodep && reduction_performed);
775}
776
777/* Returns whether the bit at the index given by idx, within the
778 * sparsebit array is set or not.
779 */
780bool sparsebit_is_set(struct sparsebit *s, sparsebit_idx_t idx)
781{
782 struct node *nodep;
783
784 /* Find the node that describes the setting of the bit at idx */
785 for (nodep = s->root; nodep;
786 nodep = nodep->idx > idx ? nodep->left : nodep->right)
787 if (idx >= nodep->idx &&
788 idx <= nodep->idx + MASK_BITS + nodep->num_after - 1)
789 goto have_node;
790
791 return false;
792
793have_node:
794 /* Bit is set if it is any of the bits described by num_after */
795 if (nodep->num_after && idx >= nodep->idx + MASK_BITS)
796 return true;
797
798 /* Is the corresponding mask bit set */
799 assert(idx >= nodep->idx && idx - nodep->idx < MASK_BITS);
800 return !!(nodep->mask & (1 << (idx - nodep->idx)));
801}
802
803/* Within the sparsebit array pointed to by s, sets the bit
804 * at the index given by idx.
805 */
806static void bit_set(struct sparsebit *s, sparsebit_idx_t idx)
807{
808 struct node *nodep;
809
810 /* Skip bits that are already set */
811 if (sparsebit_is_set(s, idx))
812 return;
813
814 /*
815 * Get a node where the bit at idx is described by the mask.
816 * The node_split will also create a node, if there isn't
817 * already a node that describes the setting of bit.
818 */
819 nodep = node_split(s, idx & -MASK_BITS);
820
821 /* Set the bit within the nodes mask */
822 assert(idx >= nodep->idx && idx <= nodep->idx + MASK_BITS - 1);
823 assert(!(nodep->mask & (1 << (idx - nodep->idx))));
824 nodep->mask |= 1 << (idx - nodep->idx);
825 s->num_set++;
826
827 node_reduce(s, nodep);
828}
829
830/* Within the sparsebit array pointed to by s, clears the bit
831 * at the index given by idx.
832 */
833static void bit_clear(struct sparsebit *s, sparsebit_idx_t idx)
834{
835 struct node *nodep;
836
837 /* Skip bits that are already cleared */
838 if (!sparsebit_is_set(s, idx))
839 return;
840
841 /* Is there a node that describes the setting of this bit? */
842 nodep = node_find(s, idx);
843 if (!nodep)
844 return;
845
846 /*
847 * If a num_after bit, split the node, so that the bit is
848 * part of a node mask.
849 */
850 if (idx >= nodep->idx + MASK_BITS)
851 nodep = node_split(s, idx & -MASK_BITS);
852
853 /*
854 * After node_split above, bit at idx should be within the mask.
855 * Clear that bit.
856 */
857 assert(idx >= nodep->idx && idx <= nodep->idx + MASK_BITS - 1);
858 assert(nodep->mask & (1 << (idx - nodep->idx)));
859 nodep->mask &= ~(1 << (idx - nodep->idx));
860 assert(s->num_set > 0 || sparsebit_all_set(s));
861 s->num_set--;
862
863 node_reduce(s, nodep);
864}
865
866/* Recursively dumps to the FILE stream given by stream the contents
867 * of the sub-tree of nodes pointed to by nodep. Each line of output
868 * is prefixed by the number of spaces given by indent. On each
869 * recursion, the indent amount is increased by 2. This causes nodes
870 * at each level deeper into the binary search tree to be displayed
871 * with a greater indent.
872 */
873static void dump_nodes(FILE *stream, struct node *nodep,
874 unsigned int indent)
875{
876 char *node_type;
877
878 /* Dump contents of node */
879 if (!nodep->parent)
880 node_type = "root";
881 else if (nodep == nodep->parent->left)
882 node_type = "left";
883 else {
884 assert(nodep == nodep->parent->right);
885 node_type = "right";
886 }
887 fprintf(stream, "%*s---- %s nodep: %p\n", indent, "", node_type, nodep);
888 fprintf(stream, "%*s parent: %p left: %p right: %p\n", indent, "",
889 nodep->parent, nodep->left, nodep->right);
890 fprintf(stream, "%*s idx: 0x%lx mask: 0x%x num_after: 0x%lx\n",
891 indent, "", nodep->idx, nodep->mask, nodep->num_after);
892
893 /* If present, dump contents of left child nodes */
894 if (nodep->left)
895 dump_nodes(stream, nodep->left, indent + 2);
896
897 /* If present, dump contents of right child nodes */
898 if (nodep->right)
899 dump_nodes(stream, nodep->right, indent + 2);
900}
901
902static inline sparsebit_idx_t node_first_set(struct node *nodep, int start)
903{
904 mask_t leading = (mask_t)1 << start;
905 int n1 = __builtin_ctz(nodep->mask & -leading);
906
907 return nodep->idx + n1;
908}
909
910static inline sparsebit_idx_t node_first_clear(struct node *nodep, int start)
911{
912 mask_t leading = (mask_t)1 << start;
913 int n1 = __builtin_ctz(~nodep->mask & -leading);
914
915 return nodep->idx + n1;
916}
917
918/* Dumps to the FILE stream specified by stream, the implementation dependent
919 * internal state of s. Each line of output is prefixed with the number
920 * of spaces given by indent. The output is completely implementation
921 * dependent and subject to change. Output from this function should only
922 * be used for diagnostic purposes. For example, this function can be
923 * used by test cases after they detect an unexpected condition, as a means
924 * to capture diagnostic information.
925 */
926static void sparsebit_dump_internal(FILE *stream, struct sparsebit *s,
927 unsigned int indent)
928{
929 /* Dump the contents of s */
930 fprintf(stream, "%*sroot: %p\n", indent, "", s->root);
931 fprintf(stream, "%*snum_set: 0x%lx\n", indent, "", s->num_set);
932
933 if (s->root)
934 dump_nodes(stream, s->root, indent);
935}
936
937/* Allocates and returns a new sparsebit array. The initial state
938 * of the newly allocated sparsebit array has all bits cleared.
939 */
940struct sparsebit *sparsebit_alloc(void)
941{
942 struct sparsebit *s;
943
944 /* Allocate top level structure. */
945 s = calloc(1, sizeof(*s));
946 if (!s) {
947 perror("calloc");
948 abort();
949 }
950
951 return s;
952}
953
954/* Frees the implementation dependent data for the sparsebit array
955 * pointed to by s and poisons the pointer to that data.
956 */
957void sparsebit_free(struct sparsebit **sbitp)
958{
959 struct sparsebit *s = *sbitp;
960
961 if (!s)
962 return;
963
964 sparsebit_clear_all(s);
965 free(s);
966 *sbitp = NULL;
967}
968
969/* Makes a copy of the sparsebit array given by s, to the sparsebit
970 * array given by d. Note, d must have already been allocated via
971 * sparsebit_alloc(). It can though already have bits set, which
972 * if different from src will be cleared.
973 */
974void sparsebit_copy(struct sparsebit *d, struct sparsebit *s)
975{
976 /* First clear any bits already set in the destination */
977 sparsebit_clear_all(d);
978
979 if (s->root) {
980 d->root = node_copy_subtree(s->root);
981 d->num_set = s->num_set;
982 }
983}
984
985/* Returns whether num consecutive bits starting at idx are all set. */
986bool sparsebit_is_set_num(struct sparsebit *s,
987 sparsebit_idx_t idx, sparsebit_num_t num)
988{
989 sparsebit_idx_t next_cleared;
990
991 assert(num > 0);
992 assert(idx + num - 1 >= idx);
993
994 /* With num > 0, the first bit must be set. */
995 if (!sparsebit_is_set(s, idx))
996 return false;
997
998 /* Find the next cleared bit */
999 next_cleared = sparsebit_next_clear(s, idx);
1000
1001 /*
1002 * If no cleared bits beyond idx, then there are at least num
1003 * set bits. idx + num doesn't wrap. Otherwise check if
1004 * there are enough set bits between idx and the next cleared bit.
1005 */
1006 return next_cleared == 0 || next_cleared - idx >= num;
1007}
1008
1009/* Returns whether the bit at the index given by idx. */
1010bool sparsebit_is_clear(struct sparsebit *s,
1011 sparsebit_idx_t idx)
1012{
1013 return !sparsebit_is_set(s, idx);
1014}
1015
1016/* Returns whether num consecutive bits starting at idx are all cleared. */
1017bool sparsebit_is_clear_num(struct sparsebit *s,
1018 sparsebit_idx_t idx, sparsebit_num_t num)
1019{
1020 sparsebit_idx_t next_set;
1021
1022 assert(num > 0);
1023 assert(idx + num - 1 >= idx);
1024
1025 /* With num > 0, the first bit must be cleared. */
1026 if (!sparsebit_is_clear(s, idx))
1027 return false;
1028
1029 /* Find the next set bit */
1030 next_set = sparsebit_next_set(s, idx);
1031
1032 /*
1033 * If no set bits beyond idx, then there are at least num
1034 * cleared bits. idx + num doesn't wrap. Otherwise check if
1035 * there are enough cleared bits between idx and the next set bit.
1036 */
1037 return next_set == 0 || next_set - idx >= num;
1038}
1039
1040/* Returns the total number of bits set. Note: 0 is also returned for
1041 * the case of all bits set. This is because with all bits set, there
1042 * is 1 additional bit set beyond what can be represented in the return
1043 * value. Use sparsebit_any_set(), instead of sparsebit_num_set() > 0,
1044 * to determine if the sparsebit array has any bits set.
1045 */
1046sparsebit_num_t sparsebit_num_set(struct sparsebit *s)
1047{
1048 return s->num_set;
1049}
1050
1051/* Returns whether any bit is set in the sparsebit array. */
1052bool sparsebit_any_set(struct sparsebit *s)
1053{
1054 /*
1055 * Nodes only describe set bits. If any nodes then there
1056 * is at least 1 bit set.
1057 */
1058 if (!s->root)
1059 return false;
1060
1061 /*
1062 * Every node should have a non-zero mask. For now will
1063 * just assure that the root node has a non-zero mask,
1064 * which is a quick check that at least 1 bit is set.
1065 */
1066 assert(s->root->mask != 0);
1067 assert(s->num_set > 0 ||
1068 (s->root->num_after == ((sparsebit_num_t) 0) - MASK_BITS &&
1069 s->root->mask == ~(mask_t) 0));
1070
1071 return true;
1072}
1073
1074/* Returns whether all the bits in the sparsebit array are cleared. */
1075bool sparsebit_all_clear(struct sparsebit *s)
1076{
1077 return !sparsebit_any_set(s);
1078}
1079
1080/* Returns whether all the bits in the sparsebit array are set. */
1081bool sparsebit_any_clear(struct sparsebit *s)
1082{
1083 return !sparsebit_all_set(s);
1084}
1085
1086/* Returns the index of the first set bit. Abort if no bits are set.
1087 */
1088sparsebit_idx_t sparsebit_first_set(struct sparsebit *s)
1089{
1090 struct node *nodep;
1091
1092 /* Validate at least 1 bit is set */
1093 assert(sparsebit_any_set(s));
1094
1095 nodep = node_first(s);
1096 return node_first_set(nodep, 0);
1097}
1098
1099/* Returns the index of the first cleared bit. Abort if
1100 * no bits are cleared.
1101 */
1102sparsebit_idx_t sparsebit_first_clear(struct sparsebit *s)
1103{
1104 struct node *nodep1, *nodep2;
1105
1106 /* Validate at least 1 bit is cleared. */
1107 assert(sparsebit_any_clear(s));
1108
1109 /* If no nodes or first node index > 0 then lowest cleared is 0 */
1110 nodep1 = node_first(s);
1111 if (!nodep1 || nodep1->idx > 0)
1112 return 0;
1113
1114 /* Does the mask in the first node contain any cleared bits. */
1115 if (nodep1->mask != ~(mask_t) 0)
1116 return node_first_clear(nodep1, 0);
1117
1118 /*
1119 * All mask bits set in first node. If there isn't a second node
1120 * then the first cleared bit is the first bit after the bits
1121 * described by the first node.
1122 */
1123 nodep2 = node_next(s, nodep1);
1124 if (!nodep2) {
1125 /*
1126 * No second node. First cleared bit is first bit beyond
1127 * bits described by first node.
1128 */
1129 assert(nodep1->mask == ~(mask_t) 0);
1130 assert(nodep1->idx + MASK_BITS + nodep1->num_after != (sparsebit_idx_t) 0);
1131 return nodep1->idx + MASK_BITS + nodep1->num_after;
1132 }
1133
1134 /*
1135 * There is a second node.
1136 * If it is not adjacent to the first node, then there is a gap
1137 * of cleared bits between the nodes, and the first cleared bit
1138 * is the first bit within the gap.
1139 */
1140 if (nodep1->idx + MASK_BITS + nodep1->num_after != nodep2->idx)
1141 return nodep1->idx + MASK_BITS + nodep1->num_after;
1142
1143 /*
1144 * Second node is adjacent to the first node.
1145 * Because it is adjacent, its mask should be non-zero. If all
1146 * its mask bits are set, then with it being adjacent, it should
1147 * have had the mask bits moved into the num_after setting of the
1148 * previous node.
1149 */
1150 return node_first_clear(nodep2, 0);
1151}
1152
1153/* Returns index of next bit set within s after the index given by prev.
1154 * Returns 0 if there are no bits after prev that are set.
1155 */
1156sparsebit_idx_t sparsebit_next_set(struct sparsebit *s,
1157 sparsebit_idx_t prev)
1158{
1159 sparsebit_idx_t lowest_possible = prev + 1;
1160 sparsebit_idx_t start;
1161 struct node *nodep;
1162
1163 /* A bit after the highest index can't be set. */
1164 if (lowest_possible == 0)
1165 return 0;
1166
1167 /*
1168 * Find the leftmost 'candidate' overlapping or to the right
1169 * of lowest_possible.
1170 */
1171 struct node *candidate = NULL;
1172
1173 /* True iff lowest_possible is within candidate */
1174 bool contains = false;
1175
1176 /*
1177 * Find node that describes setting of bit at lowest_possible.
1178 * If such a node doesn't exist, find the node with the lowest
1179 * starting index that is > lowest_possible.
1180 */
1181 for (nodep = s->root; nodep;) {
1182 if ((nodep->idx + MASK_BITS + nodep->num_after - 1)
1183 >= lowest_possible) {
1184 candidate = nodep;
1185 if (candidate->idx <= lowest_possible) {
1186 contains = true;
1187 break;
1188 }
1189 nodep = nodep->left;
1190 } else {
1191 nodep = nodep->right;
1192 }
1193 }
1194 if (!candidate)
1195 return 0;
1196
1197 assert(candidate->mask != 0);
1198
1199 /* Does the candidate node describe the setting of lowest_possible? */
1200 if (!contains) {
1201 /*
1202 * Candidate doesn't describe setting of bit at lowest_possible.
1203 * Candidate points to the first node with a starting index
1204 * > lowest_possible.
1205 */
1206 assert(candidate->idx > lowest_possible);
1207
1208 return node_first_set(candidate, 0);
1209 }
1210
1211 /*
1212 * Candidate describes setting of bit at lowest_possible.
1213 * Note: although the node describes the setting of the bit
1214 * at lowest_possible, its possible that its setting and the
1215 * setting of all latter bits described by this node are 0.
1216 * For now, just handle the cases where this node describes
1217 * a bit at or after an index of lowest_possible that is set.
1218 */
1219 start = lowest_possible - candidate->idx;
1220
1221 if (start < MASK_BITS && candidate->mask >= (1 << start))
1222 return node_first_set(candidate, start);
1223
1224 if (candidate->num_after) {
1225 sparsebit_idx_t first_num_after_idx = candidate->idx + MASK_BITS;
1226
1227 return lowest_possible < first_num_after_idx
1228 ? first_num_after_idx : lowest_possible;
1229 }
1230
1231 /*
1232 * Although candidate node describes setting of bit at
1233 * the index of lowest_possible, all bits at that index and
1234 * latter that are described by candidate are cleared. With
1235 * this, the next bit is the first bit in the next node, if
1236 * such a node exists. If a next node doesn't exist, then
1237 * there is no next set bit.
1238 */
1239 candidate = node_next(s, candidate);
1240 if (!candidate)
1241 return 0;
1242
1243 return node_first_set(candidate, 0);
1244}
1245
1246/* Returns index of next bit cleared within s after the index given by prev.
1247 * Returns 0 if there are no bits after prev that are cleared.
1248 */
1249sparsebit_idx_t sparsebit_next_clear(struct sparsebit *s,
1250 sparsebit_idx_t prev)
1251{
1252 sparsebit_idx_t lowest_possible = prev + 1;
1253 sparsebit_idx_t idx;
1254 struct node *nodep1, *nodep2;
1255
1256 /* A bit after the highest index can't be set. */
1257 if (lowest_possible == 0)
1258 return 0;
1259
1260 /*
1261 * Does a node describing the setting of lowest_possible exist?
1262 * If not, the bit at lowest_possible is cleared.
1263 */
1264 nodep1 = node_find(s, lowest_possible);
1265 if (!nodep1)
1266 return lowest_possible;
1267
1268 /* Does a mask bit in node 1 describe the next cleared bit. */
1269 for (idx = lowest_possible - nodep1->idx; idx < MASK_BITS; idx++)
1270 if (!(nodep1->mask & (1 << idx)))
1271 return nodep1->idx + idx;
1272
1273 /*
1274 * Next cleared bit is not described by node 1. If there
1275 * isn't a next node, then next cleared bit is described
1276 * by bit after the bits described by the first node.
1277 */
1278 nodep2 = node_next(s, nodep1);
1279 if (!nodep2)
1280 return nodep1->idx + MASK_BITS + nodep1->num_after;
1281
1282 /*
1283 * There is a second node.
1284 * If it is not adjacent to the first node, then there is a gap
1285 * of cleared bits between the nodes, and the next cleared bit
1286 * is the first bit within the gap.
1287 */
1288 if (nodep1->idx + MASK_BITS + nodep1->num_after != nodep2->idx)
1289 return nodep1->idx + MASK_BITS + nodep1->num_after;
1290
1291 /*
1292 * Second node is adjacent to the first node.
1293 * Because it is adjacent, its mask should be non-zero. If all
1294 * its mask bits are set, then with it being adjacent, it should
1295 * have had the mask bits moved into the num_after setting of the
1296 * previous node.
1297 */
1298 return node_first_clear(nodep2, 0);
1299}
1300
1301/* Starting with the index 1 greater than the index given by start, finds
1302 * and returns the index of the first sequence of num consecutively set
1303 * bits. Returns a value of 0 of no such sequence exists.
1304 */
1305sparsebit_idx_t sparsebit_next_set_num(struct sparsebit *s,
1306 sparsebit_idx_t start, sparsebit_num_t num)
1307{
1308 sparsebit_idx_t idx;
1309
1310 assert(num >= 1);
1311
1312 for (idx = sparsebit_next_set(s, start);
1313 idx != 0 && idx + num - 1 >= idx;
1314 idx = sparsebit_next_set(s, idx)) {
1315 assert(sparsebit_is_set(s, idx));
1316
1317 /*
1318 * Does the sequence of bits starting at idx consist of
1319 * num set bits?
1320 */
1321 if (sparsebit_is_set_num(s, idx, num))
1322 return idx;
1323
1324 /*
1325 * Sequence of set bits at idx isn't large enough.
1326 * Skip this entire sequence of set bits.
1327 */
1328 idx = sparsebit_next_clear(s, idx);
1329 if (idx == 0)
1330 return 0;
1331 }
1332
1333 return 0;
1334}
1335
1336/* Starting with the index 1 greater than the index given by start, finds
1337 * and returns the index of the first sequence of num consecutively cleared
1338 * bits. Returns a value of 0 of no such sequence exists.
1339 */
1340sparsebit_idx_t sparsebit_next_clear_num(struct sparsebit *s,
1341 sparsebit_idx_t start, sparsebit_num_t num)
1342{
1343 sparsebit_idx_t idx;
1344
1345 assert(num >= 1);
1346
1347 for (idx = sparsebit_next_clear(s, start);
1348 idx != 0 && idx + num - 1 >= idx;
1349 idx = sparsebit_next_clear(s, idx)) {
1350 assert(sparsebit_is_clear(s, idx));
1351
1352 /*
1353 * Does the sequence of bits starting at idx consist of
1354 * num cleared bits?
1355 */
1356 if (sparsebit_is_clear_num(s, idx, num))
1357 return idx;
1358
1359 /*
1360 * Sequence of cleared bits at idx isn't large enough.
1361 * Skip this entire sequence of cleared bits.
1362 */
1363 idx = sparsebit_next_set(s, idx);
1364 if (idx == 0)
1365 return 0;
1366 }
1367
1368 return 0;
1369}
1370
1371/* Sets the bits * in the inclusive range idx through idx + num - 1. */
1372void sparsebit_set_num(struct sparsebit *s,
1373 sparsebit_idx_t start, sparsebit_num_t num)
1374{
1375 struct node *nodep, *next;
1376 unsigned int n1;
1377 sparsebit_idx_t idx;
1378 sparsebit_num_t n;
1379 sparsebit_idx_t middle_start, middle_end;
1380
1381 assert(num > 0);
1382 assert(start + num - 1 >= start);
1383
1384 /*
1385 * Leading - bits before first mask boundary.
1386 *
1387 * TODO(lhuemill): With some effort it may be possible to
1388 * replace the following loop with a sequential sequence
1389 * of statements. High level sequence would be:
1390 *
1391 * 1. Use node_split() to force node that describes setting
1392 * of idx to be within the mask portion of a node.
1393 * 2. Form mask of bits to be set.
1394 * 3. Determine number of mask bits already set in the node
1395 * and store in a local variable named num_already_set.
1396 * 4. Set the appropriate mask bits within the node.
1397 * 5. Increment struct sparsebit_pvt num_set member
1398 * by the number of bits that were actually set.
1399 * Exclude from the counts bits that were already set.
1400 * 6. Before returning to the caller, use node_reduce() to
1401 * handle the multiple corner cases that this method
1402 * introduces.
1403 */
1404 for (idx = start, n = num; n > 0 && idx % MASK_BITS != 0; idx++, n--)
1405 bit_set(s, idx);
1406
1407 /* Middle - bits spanning one or more entire mask */
1408 middle_start = idx;
1409 middle_end = middle_start + (n & -MASK_BITS) - 1;
1410 if (n >= MASK_BITS) {
1411 nodep = node_split(s, middle_start);
1412
1413 /*
1414 * As needed, split just after end of middle bits.
1415 * No split needed if end of middle bits is at highest
1416 * supported bit index.
1417 */
1418 if (middle_end + 1 > middle_end)
1419 (void) node_split(s, middle_end + 1);
1420
1421 /* Delete nodes that only describe bits within the middle. */
1422 for (next = node_next(s, nodep);
1423 next && (next->idx < middle_end);
1424 next = node_next(s, nodep)) {
1425 assert(next->idx + MASK_BITS + next->num_after - 1 <= middle_end);
1426 node_rm(s, next);
1427 next = NULL;
1428 }
1429
1430 /* As needed set each of the mask bits */
1431 for (n1 = 0; n1 < MASK_BITS; n1++) {
1432 if (!(nodep->mask & (1 << n1))) {
1433 nodep->mask |= 1 << n1;
1434 s->num_set++;
1435 }
1436 }
1437
1438 s->num_set -= nodep->num_after;
1439 nodep->num_after = middle_end - middle_start + 1 - MASK_BITS;
1440 s->num_set += nodep->num_after;
1441
1442 node_reduce(s, nodep);
1443 }
1444 idx = middle_end + 1;
1445 n -= middle_end - middle_start + 1;
1446
1447 /* Trailing - bits at and beyond last mask boundary */
1448 assert(n < MASK_BITS);
1449 for (; n > 0; idx++, n--)
1450 bit_set(s, idx);
1451}
1452
1453/* Clears the bits * in the inclusive range idx through idx + num - 1. */
1454void sparsebit_clear_num(struct sparsebit *s,
1455 sparsebit_idx_t start, sparsebit_num_t num)
1456{
1457 struct node *nodep, *next;
1458 unsigned int n1;
1459 sparsebit_idx_t idx;
1460 sparsebit_num_t n;
1461 sparsebit_idx_t middle_start, middle_end;
1462
1463 assert(num > 0);
1464 assert(start + num - 1 >= start);
1465
1466 /* Leading - bits before first mask boundary */
1467 for (idx = start, n = num; n > 0 && idx % MASK_BITS != 0; idx++, n--)
1468 bit_clear(s, idx);
1469
1470 /* Middle - bits spanning one or more entire mask */
1471 middle_start = idx;
1472 middle_end = middle_start + (n & -MASK_BITS) - 1;
1473 if (n >= MASK_BITS) {
1474 nodep = node_split(s, middle_start);
1475
1476 /*
1477 * As needed, split just after end of middle bits.
1478 * No split needed if end of middle bits is at highest
1479 * supported bit index.
1480 */
1481 if (middle_end + 1 > middle_end)
1482 (void) node_split(s, middle_end + 1);
1483
1484 /* Delete nodes that only describe bits within the middle. */
1485 for (next = node_next(s, nodep);
1486 next && (next->idx < middle_end);
1487 next = node_next(s, nodep)) {
1488 assert(next->idx + MASK_BITS + next->num_after - 1 <= middle_end);
1489 node_rm(s, next);
1490 next = NULL;
1491 }
1492
1493 /* As needed clear each of the mask bits */
1494 for (n1 = 0; n1 < MASK_BITS; n1++) {
1495 if (nodep->mask & (1 << n1)) {
1496 nodep->mask &= ~(1 << n1);
1497 s->num_set--;
1498 }
1499 }
1500
1501 /* Clear any bits described by num_after */
1502 s->num_set -= nodep->num_after;
1503 nodep->num_after = 0;
1504
1505 /*
1506 * Delete the node that describes the beginning of
1507 * the middle bits and perform any allowed reductions
1508 * with the nodes prev or next of nodep.
1509 */
1510 node_reduce(s, nodep);
1511 nodep = NULL;
1512 }
1513 idx = middle_end + 1;
1514 n -= middle_end - middle_start + 1;
1515
1516 /* Trailing - bits at and beyond last mask boundary */
1517 assert(n < MASK_BITS);
1518 for (; n > 0; idx++, n--)
1519 bit_clear(s, idx);
1520}
1521
1522/* Sets the bit at the index given by idx. */
1523void sparsebit_set(struct sparsebit *s, sparsebit_idx_t idx)
1524{
1525 sparsebit_set_num(s, idx, 1);
1526}
1527
1528/* Clears the bit at the index given by idx. */
1529void sparsebit_clear(struct sparsebit *s, sparsebit_idx_t idx)
1530{
1531 sparsebit_clear_num(s, idx, 1);
1532}
1533
1534/* Sets the bits in the entire addressable range of the sparsebit array. */
1535void sparsebit_set_all(struct sparsebit *s)
1536{
1537 sparsebit_set(s, 0);
1538 sparsebit_set_num(s, 1, ~(sparsebit_idx_t) 0);
1539 assert(sparsebit_all_set(s));
1540}
1541
1542/* Clears the bits in the entire addressable range of the sparsebit array. */
1543void sparsebit_clear_all(struct sparsebit *s)
1544{
1545 sparsebit_clear(s, 0);
1546 sparsebit_clear_num(s, 1, ~(sparsebit_idx_t) 0);
1547 assert(!sparsebit_any_set(s));
1548}
1549
1550static size_t display_range(FILE *stream, sparsebit_idx_t low,
1551 sparsebit_idx_t high, bool prepend_comma_space)
1552{
1553 char *fmt_str;
1554 size_t sz;
1555
1556 /* Determine the printf format string */
1557 if (low == high)
1558 fmt_str = prepend_comma_space ? ", 0x%lx" : "0x%lx";
1559 else
1560 fmt_str = prepend_comma_space ? ", 0x%lx:0x%lx" : "0x%lx:0x%lx";
1561
1562 /*
1563 * When stream is NULL, just determine the size of what would
1564 * have been printed, else print the range.
1565 */
1566 if (!stream)
1567 sz = snprintf(NULL, 0, fmt_str, low, high);
1568 else
1569 sz = fprintf(stream, fmt_str, low, high);
1570
1571 return sz;
1572}
1573
1574
1575/* Dumps to the FILE stream given by stream, the bit settings
1576 * of s. Each line of output is prefixed with the number of
1577 * spaces given by indent. The length of each line is implementation
1578 * dependent and does not depend on the indent amount. The following
1579 * is an example output of a sparsebit array that has bits:
1580 *
1581 * 0x5, 0x8, 0xa:0xe, 0x12
1582 *
1583 * This corresponds to a sparsebit whose bits 5, 8, 10, 11, 12, 13, 14, 18
1584 * are set. Note that a ':', instead of a '-' is used to specify a range of
1585 * contiguous bits. This is done because '-' is used to specify command-line
1586 * options, and sometimes ranges are specified as command-line arguments.
1587 */
1588void sparsebit_dump(FILE *stream, struct sparsebit *s,
1589 unsigned int indent)
1590{
1591 size_t current_line_len = 0;
1592 size_t sz;
1593 struct node *nodep;
1594
1595 if (!sparsebit_any_set(s))
1596 return;
1597
1598 /* Display initial indent */
1599 fprintf(stream, "%*s", indent, "");
1600
1601 /* For each node */
1602 for (nodep = node_first(s); nodep; nodep = node_next(s, nodep)) {
1603 unsigned int n1;
1604 sparsebit_idx_t low, high;
1605
1606 /* For each group of bits in the mask */
1607 for (n1 = 0; n1 < MASK_BITS; n1++) {
1608 if (nodep->mask & (1 << n1)) {
1609 low = high = nodep->idx + n1;
1610
1611 for (; n1 < MASK_BITS; n1++) {
1612 if (nodep->mask & (1 << n1))
1613 high = nodep->idx + n1;
1614 else
1615 break;
1616 }
1617
1618 if ((n1 == MASK_BITS) && nodep->num_after)
1619 high += nodep->num_after;
1620
1621 /*
1622 * How much room will it take to display
1623 * this range.
1624 */
1625 sz = display_range(NULL, low, high,
1626 current_line_len != 0);
1627
1628 /*
1629 * If there is not enough room, display
1630 * a newline plus the indent of the next
1631 * line.
1632 */
1633 if (current_line_len + sz > DUMP_LINE_MAX) {
1634 fputs("\n", stream);
1635 fprintf(stream, "%*s", indent, "");
1636 current_line_len = 0;
1637 }
1638
1639 /* Display the range */
1640 sz = display_range(stream, low, high,
1641 current_line_len != 0);
1642 current_line_len += sz;
1643 }
1644 }
1645
1646 /*
1647 * If num_after and most significant-bit of mask is not
1648 * set, then still need to display a range for the bits
1649 * described by num_after.
1650 */
1651 if (!(nodep->mask & (1 << (MASK_BITS - 1))) && nodep->num_after) {
1652 low = nodep->idx + MASK_BITS;
1653 high = nodep->idx + MASK_BITS + nodep->num_after - 1;
1654
1655 /*
1656 * How much room will it take to display
1657 * this range.
1658 */
1659 sz = display_range(NULL, low, high,
1660 current_line_len != 0);
1661
1662 /*
1663 * If there is not enough room, display
1664 * a newline plus the indent of the next
1665 * line.
1666 */
1667 if (current_line_len + sz > DUMP_LINE_MAX) {
1668 fputs("\n", stream);
1669 fprintf(stream, "%*s", indent, "");
1670 current_line_len = 0;
1671 }
1672
1673 /* Display the range */
1674 sz = display_range(stream, low, high,
1675 current_line_len != 0);
1676 current_line_len += sz;
1677 }
1678 }
1679 fputs("\n", stream);
1680}
1681
1682/* Validates the internal state of the sparsebit array given by
1683 * s. On error, diagnostic information is printed to stderr and
1684 * abort is called.
1685 */
1686void sparsebit_validate_internal(struct sparsebit *s)
1687{
1688 bool error_detected = false;
1689 struct node *nodep, *prev = NULL;
1690 sparsebit_num_t total_bits_set = 0;
1691 unsigned int n1;
1692
1693 /* For each node */
1694 for (nodep = node_first(s); nodep;
1695 prev = nodep, nodep = node_next(s, nodep)) {
1696
1697 /*
1698 * Increase total bits set by the number of bits set
1699 * in this node.
1700 */
1701 for (n1 = 0; n1 < MASK_BITS; n1++)
1702 if (nodep->mask & (1 << n1))
1703 total_bits_set++;
1704
1705 total_bits_set += nodep->num_after;
1706
1707 /*
1708 * Arbitrary choice as to whether a mask of 0 is allowed
1709 * or not. For diagnostic purposes it is beneficial to
1710 * have only one valid means to represent a set of bits.
1711 * To support this an arbitrary choice has been made
1712 * to not allow a mask of zero.
1713 */
1714 if (nodep->mask == 0) {
1715 fprintf(stderr, "Node mask of zero, "
1716 "nodep: %p nodep->mask: 0x%x",
1717 nodep, nodep->mask);
1718 error_detected = true;
1719 break;
1720 }
1721
1722 /*
1723 * Validate num_after is not greater than the max index
1724 * - the number of mask bits. The num_after member
1725 * uses 0-based indexing and thus has no value that
1726 * represents all bits set. This limitation is handled
1727 * by requiring a non-zero mask. With a non-zero mask,
1728 * MASK_BITS worth of bits are described by the mask,
1729 * which makes the largest needed num_after equal to:
1730 *
1731 * (~(sparsebit_num_t) 0) - MASK_BITS + 1
1732 */
1733 if (nodep->num_after
1734 > (~(sparsebit_num_t) 0) - MASK_BITS + 1) {
1735 fprintf(stderr, "num_after too large, "
1736 "nodep: %p nodep->num_after: 0x%lx",
1737 nodep, nodep->num_after);
1738 error_detected = true;
1739 break;
1740 }
1741
1742 /* Validate node index is divisible by the mask size */
1743 if (nodep->idx % MASK_BITS) {
1744 fprintf(stderr, "Node index not divisible by "
1745 "mask size,\n"
1746 " nodep: %p nodep->idx: 0x%lx "
1747 "MASK_BITS: %lu\n",
1748 nodep, nodep->idx, MASK_BITS);
1749 error_detected = true;
1750 break;
1751 }
1752
1753 /*
1754 * Validate bits described by node don't wrap beyond the
1755 * highest supported index.
1756 */
1757 if ((nodep->idx + MASK_BITS + nodep->num_after - 1) < nodep->idx) {
1758 fprintf(stderr, "Bits described by node wrap "
1759 "beyond highest supported index,\n"
1760 " nodep: %p nodep->idx: 0x%lx\n"
1761 " MASK_BITS: %lu nodep->num_after: 0x%lx",
1762 nodep, nodep->idx, MASK_BITS, nodep->num_after);
1763 error_detected = true;
1764 break;
1765 }
1766
1767 /* Check parent pointers. */
1768 if (nodep->left) {
1769 if (nodep->left->parent != nodep) {
1770 fprintf(stderr, "Left child parent pointer "
1771 "doesn't point to this node,\n"
1772 " nodep: %p nodep->left: %p "
1773 "nodep->left->parent: %p",
1774 nodep, nodep->left,
1775 nodep->left->parent);
1776 error_detected = true;
1777 break;
1778 }
1779 }
1780
1781 if (nodep->right) {
1782 if (nodep->right->parent != nodep) {
1783 fprintf(stderr, "Right child parent pointer "
1784 "doesn't point to this node,\n"
1785 " nodep: %p nodep->right: %p "
1786 "nodep->right->parent: %p",
1787 nodep, nodep->right,
1788 nodep->right->parent);
1789 error_detected = true;
1790 break;
1791 }
1792 }
1793
1794 if (!nodep->parent) {
1795 if (s->root != nodep) {
1796 fprintf(stderr, "Unexpected root node, "
1797 "s->root: %p nodep: %p",
1798 s->root, nodep);
1799 error_detected = true;
1800 break;
1801 }
1802 }
1803
1804 if (prev) {
1805 /*
1806 * Is index of previous node before index of
1807 * current node?
1808 */
1809 if (prev->idx >= nodep->idx) {
1810 fprintf(stderr, "Previous node index "
1811 ">= current node index,\n"
1812 " prev: %p prev->idx: 0x%lx\n"
1813 " nodep: %p nodep->idx: 0x%lx",
1814 prev, prev->idx, nodep, nodep->idx);
1815 error_detected = true;
1816 break;
1817 }
1818
1819 /*
1820 * Nodes occur in asscending order, based on each
1821 * nodes starting index.
1822 */
1823 if ((prev->idx + MASK_BITS + prev->num_after - 1)
1824 >= nodep->idx) {
1825 fprintf(stderr, "Previous node bit range "
1826 "overlap with current node bit range,\n"
1827 " prev: %p prev->idx: 0x%lx "
1828 "prev->num_after: 0x%lx\n"
1829 " nodep: %p nodep->idx: 0x%lx "
1830 "nodep->num_after: 0x%lx\n"
1831 " MASK_BITS: %lu",
1832 prev, prev->idx, prev->num_after,
1833 nodep, nodep->idx, nodep->num_after,
1834 MASK_BITS);
1835 error_detected = true;
1836 break;
1837 }
1838
1839 /*
1840 * When the node has all mask bits set, it shouldn't
1841 * be adjacent to the last bit described by the
1842 * previous node.
1843 */
1844 if (nodep->mask == ~(mask_t) 0 &&
1845 prev->idx + MASK_BITS + prev->num_after == nodep->idx) {
1846 fprintf(stderr, "Current node has mask with "
1847 "all bits set and is adjacent to the "
1848 "previous node,\n"
1849 " prev: %p prev->idx: 0x%lx "
1850 "prev->num_after: 0x%lx\n"
1851 " nodep: %p nodep->idx: 0x%lx "
1852 "nodep->num_after: 0x%lx\n"
1853 " MASK_BITS: %lu",
1854 prev, prev->idx, prev->num_after,
1855 nodep, nodep->idx, nodep->num_after,
1856 MASK_BITS);
1857
1858 error_detected = true;
1859 break;
1860 }
1861 }
1862 }
1863
1864 if (!error_detected) {
1865 /*
1866 * Is sum of bits set in each node equal to the count
1867 * of total bits set.
1868 */
1869 if (s->num_set != total_bits_set) {
1870 fprintf(stderr, "Number of bits set missmatch,\n"
1871 " s->num_set: 0x%lx total_bits_set: 0x%lx",
1872 s->num_set, total_bits_set);
1873
1874 error_detected = true;
1875 }
1876 }
1877
1878 if (error_detected) {
1879 fputs(" dump_internal:\n", stderr);
1880 sparsebit_dump_internal(stderr, s, 4);
1881 abort();
1882 }
1883}
1884
1885
1886#ifdef FUZZ
1887/* A simple but effective fuzzing driver. Look for bugs with the help
1888 * of some invariants and of a trivial representation of sparsebit.
1889 * Just use 512 bytes of /dev/zero and /dev/urandom as inputs, and let
1890 * afl-fuzz do the magic. :)
1891 */
1892
1893#include <stdlib.h>
1894#include <assert.h>
1895
1896struct range {
1897 sparsebit_idx_t first, last;
1898 bool set;
1899};
1900
1901struct sparsebit *s;
1902struct range ranges[1000];
1903int num_ranges;
1904
1905static bool get_value(sparsebit_idx_t idx)
1906{
1907 int i;
1908
1909 for (i = num_ranges; --i >= 0; )
1910 if (ranges[i].first <= idx && idx <= ranges[i].last)
1911 return ranges[i].set;
1912
1913 return false;
1914}
1915
1916static void operate(int code, sparsebit_idx_t first, sparsebit_idx_t last)
1917{
1918 sparsebit_num_t num;
1919 sparsebit_idx_t next;
1920
1921 if (first < last) {
1922 num = last - first + 1;
1923 } else {
1924 num = first - last + 1;
1925 first = last;
1926 last = first + num - 1;
1927 }
1928
1929 switch (code) {
1930 case 0:
1931 sparsebit_set(s, first);
1932 assert(sparsebit_is_set(s, first));
1933 assert(!sparsebit_is_clear(s, first));
1934 assert(sparsebit_any_set(s));
1935 assert(!sparsebit_all_clear(s));
1936 if (get_value(first))
1937 return;
1938 if (num_ranges == 1000)
1939 exit(0);
1940 ranges[num_ranges++] = (struct range)
1941 { .first = first, .last = first, .set = true };
1942 break;
1943 case 1:
1944 sparsebit_clear(s, first);
1945 assert(!sparsebit_is_set(s, first));
1946 assert(sparsebit_is_clear(s, first));
1947 assert(sparsebit_any_clear(s));
1948 assert(!sparsebit_all_set(s));
1949 if (!get_value(first))
1950 return;
1951 if (num_ranges == 1000)
1952 exit(0);
1953 ranges[num_ranges++] = (struct range)
1954 { .first = first, .last = first, .set = false };
1955 break;
1956 case 2:
1957 assert(sparsebit_is_set(s, first) == get_value(first));
1958 assert(sparsebit_is_clear(s, first) == !get_value(first));
1959 break;
1960 case 3:
1961 if (sparsebit_any_set(s))
1962 assert(get_value(sparsebit_first_set(s)));
1963 if (sparsebit_any_clear(s))
1964 assert(!get_value(sparsebit_first_clear(s)));
1965 sparsebit_set_all(s);
1966 assert(!sparsebit_any_clear(s));
1967 assert(sparsebit_all_set(s));
1968 num_ranges = 0;
1969 ranges[num_ranges++] = (struct range)
1970 { .first = 0, .last = ~(sparsebit_idx_t)0, .set = true };
1971 break;
1972 case 4:
1973 if (sparsebit_any_set(s))
1974 assert(get_value(sparsebit_first_set(s)));
1975 if (sparsebit_any_clear(s))
1976 assert(!get_value(sparsebit_first_clear(s)));
1977 sparsebit_clear_all(s);
1978 assert(!sparsebit_any_set(s));
1979 assert(sparsebit_all_clear(s));
1980 num_ranges = 0;
1981 break;
1982 case 5:
1983 next = sparsebit_next_set(s, first);
1984 assert(next == 0 || next > first);
1985 assert(next == 0 || get_value(next));
1986 break;
1987 case 6:
1988 next = sparsebit_next_clear(s, first);
1989 assert(next == 0 || next > first);
1990 assert(next == 0 || !get_value(next));
1991 break;
1992 case 7:
1993 next = sparsebit_next_clear(s, first);
1994 if (sparsebit_is_set_num(s, first, num)) {
1995 assert(next == 0 || next > last);
1996 if (first)
1997 next = sparsebit_next_set(s, first - 1);
1998 else if (sparsebit_any_set(s))
1999 next = sparsebit_first_set(s);
2000 else
2001 return;
2002 assert(next == first);
2003 } else {
2004 assert(sparsebit_is_clear(s, first) || next <= last);
2005 }
2006 break;
2007 case 8:
2008 next = sparsebit_next_set(s, first);
2009 if (sparsebit_is_clear_num(s, first, num)) {
2010 assert(next == 0 || next > last);
2011 if (first)
2012 next = sparsebit_next_clear(s, first - 1);
2013 else if (sparsebit_any_clear(s))
2014 next = sparsebit_first_clear(s);
2015 else
2016 return;
2017 assert(next == first);
2018 } else {
2019 assert(sparsebit_is_set(s, first) || next <= last);
2020 }
2021 break;
2022 case 9:
2023 sparsebit_set_num(s, first, num);
2024 assert(sparsebit_is_set_num(s, first, num));
2025 assert(!sparsebit_is_clear_num(s, first, num));
2026 assert(sparsebit_any_set(s));
2027 assert(!sparsebit_all_clear(s));
2028 if (num_ranges == 1000)
2029 exit(0);
2030 ranges[num_ranges++] = (struct range)
2031 { .first = first, .last = last, .set = true };
2032 break;
2033 case 10:
2034 sparsebit_clear_num(s, first, num);
2035 assert(!sparsebit_is_set_num(s, first, num));
2036 assert(sparsebit_is_clear_num(s, first, num));
2037 assert(sparsebit_any_clear(s));
2038 assert(!sparsebit_all_set(s));
2039 if (num_ranges == 1000)
2040 exit(0);
2041 ranges[num_ranges++] = (struct range)
2042 { .first = first, .last = last, .set = false };
2043 break;
2044 case 11:
2045 sparsebit_validate_internal(s);
2046 break;
2047 default:
2048 break;
2049 }
2050}
2051
2052unsigned char get8(void)
2053{
2054 int ch;
2055
2056 ch = getchar();
2057 if (ch == EOF)
2058 exit(0);
2059 return ch;
2060}
2061
2062uint64_t get64(void)
2063{
2064 uint64_t x;
2065
2066 x = get8();
2067 x = (x << 8) | get8();
2068 x = (x << 8) | get8();
2069 x = (x << 8) | get8();
2070 x = (x << 8) | get8();
2071 x = (x << 8) | get8();
2072 x = (x << 8) | get8();
2073 return (x << 8) | get8();
2074}
2075
2076int main(void)
2077{
2078 s = sparsebit_alloc();
2079 for (;;) {
2080 uint8_t op = get8() & 0xf;
2081 uint64_t first = get64();
2082 uint64_t last = get64();
2083
2084 operate(op, first, last);
2085 }
2086}
2087#endif
diff --git a/tools/testing/selftests/kvm/lib/vmx.c b/tools/testing/selftests/kvm/lib/vmx.c
new file mode 100644
index 000000000000..0231bc0aae7b
--- /dev/null
+++ b/tools/testing/selftests/kvm/lib/vmx.c
@@ -0,0 +1,243 @@
1/*
2 * tools/testing/selftests/kvm/lib/x86.c
3 *
4 * Copyright (C) 2018, Google LLC.
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2.
7 */
8
9#define _GNU_SOURCE /* for program_invocation_name */
10
11#include "test_util.h"
12#include "kvm_util.h"
13#include "x86.h"
14#include "vmx.h"
15
16/* Create a default VM for VMX tests.
17 *
18 * Input Args:
19 * vcpuid - The id of the single VCPU to add to the VM.
20 * guest_code - The vCPU's entry point
21 *
22 * Output Args: None
23 *
24 * Return:
25 * Pointer to opaque structure that describes the created VM.
26 */
27struct kvm_vm *
28vm_create_default_vmx(uint32_t vcpuid, vmx_guest_code_t guest_code)
29{
30 struct kvm_cpuid2 *cpuid;
31 struct kvm_vm *vm;
32 vm_vaddr_t vmxon_vaddr;
33 vm_paddr_t vmxon_paddr;
34 vm_vaddr_t vmcs_vaddr;
35 vm_paddr_t vmcs_paddr;
36
37 vm = vm_create_default(vcpuid, (void *) guest_code);
38
39 /* Enable nesting in CPUID */
40 vcpu_set_cpuid(vm, vcpuid, kvm_get_supported_cpuid());
41
42 /* Setup of a region of guest memory for the vmxon region. */
43 vmxon_vaddr = vm_vaddr_alloc(vm, getpagesize(), 0, 0, 0);
44 vmxon_paddr = addr_gva2gpa(vm, vmxon_vaddr);
45
46 /* Setup of a region of guest memory for a vmcs. */
47 vmcs_vaddr = vm_vaddr_alloc(vm, getpagesize(), 0, 0, 0);
48 vmcs_paddr = addr_gva2gpa(vm, vmcs_vaddr);
49
50 vcpu_args_set(vm, vcpuid, 4, vmxon_vaddr, vmxon_paddr, vmcs_vaddr,
51 vmcs_paddr);
52
53 return vm;
54}
55
56void prepare_for_vmx_operation(void)
57{
58 uint64_t feature_control;
59 uint64_t required;
60 unsigned long cr0;
61 unsigned long cr4;
62
63 /*
64 * Ensure bits in CR0 and CR4 are valid in VMX operation:
65 * - Bit X is 1 in _FIXED0: bit X is fixed to 1 in CRx.
66 * - Bit X is 0 in _FIXED1: bit X is fixed to 0 in CRx.
67 */
68 __asm__ __volatile__("mov %%cr0, %0" : "=r"(cr0) : : "memory");
69 cr0 &= rdmsr(MSR_IA32_VMX_CR0_FIXED1);
70 cr0 |= rdmsr(MSR_IA32_VMX_CR0_FIXED0);
71 __asm__ __volatile__("mov %0, %%cr0" : : "r"(cr0) : "memory");
72
73 __asm__ __volatile__("mov %%cr4, %0" : "=r"(cr4) : : "memory");
74 cr4 &= rdmsr(MSR_IA32_VMX_CR4_FIXED1);
75 cr4 |= rdmsr(MSR_IA32_VMX_CR4_FIXED0);
76 /* Enable VMX operation */
77 cr4 |= X86_CR4_VMXE;
78 __asm__ __volatile__("mov %0, %%cr4" : : "r"(cr4) : "memory");
79
80 /*
81 * Configure IA32_FEATURE_CONTROL MSR to allow VMXON:
82 * Bit 0: Lock bit. If clear, VMXON causes a #GP.
83 * Bit 2: Enables VMXON outside of SMX operation. If clear, VMXON
84 * outside of SMX causes a #GP.
85 */
86 required = FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX;
87 required |= FEATURE_CONTROL_LOCKED;
88 feature_control = rdmsr(MSR_IA32_FEATURE_CONTROL);
89 if ((feature_control & required) != required)
90 wrmsr(MSR_IA32_FEATURE_CONTROL, feature_control | required);
91}
92
93/*
94 * Initialize the control fields to the most basic settings possible.
95 */
96static inline void init_vmcs_control_fields(void)
97{
98 vmwrite(VIRTUAL_PROCESSOR_ID, 0);
99 vmwrite(POSTED_INTR_NV, 0);
100
101 vmwrite(PIN_BASED_VM_EXEC_CONTROL, rdmsr(MSR_IA32_VMX_PINBASED_CTLS));
102 vmwrite(CPU_BASED_VM_EXEC_CONTROL, rdmsr(MSR_IA32_VMX_PROCBASED_CTLS));
103 vmwrite(EXCEPTION_BITMAP, 0);
104 vmwrite(PAGE_FAULT_ERROR_CODE_MASK, 0);
105 vmwrite(PAGE_FAULT_ERROR_CODE_MATCH, -1); /* Never match */
106 vmwrite(CR3_TARGET_COUNT, 0);
107 vmwrite(VM_EXIT_CONTROLS, rdmsr(MSR_IA32_VMX_EXIT_CTLS) |
108 VM_EXIT_HOST_ADDR_SPACE_SIZE); /* 64-bit host */
109 vmwrite(VM_EXIT_MSR_STORE_COUNT, 0);
110 vmwrite(VM_EXIT_MSR_LOAD_COUNT, 0);
111 vmwrite(VM_ENTRY_CONTROLS, rdmsr(MSR_IA32_VMX_ENTRY_CTLS) |
112 VM_ENTRY_IA32E_MODE); /* 64-bit guest */
113 vmwrite(VM_ENTRY_MSR_LOAD_COUNT, 0);
114 vmwrite(VM_ENTRY_INTR_INFO_FIELD, 0);
115 vmwrite(TPR_THRESHOLD, 0);
116 vmwrite(SECONDARY_VM_EXEC_CONTROL, 0);
117
118 vmwrite(CR0_GUEST_HOST_MASK, 0);
119 vmwrite(CR4_GUEST_HOST_MASK, 0);
120 vmwrite(CR0_READ_SHADOW, get_cr0());
121 vmwrite(CR4_READ_SHADOW, get_cr4());
122}
123
124/*
125 * Initialize the host state fields based on the current host state, with
126 * the exception of HOST_RSP and HOST_RIP, which should be set by vmlaunch
127 * or vmresume.
128 */
129static inline void init_vmcs_host_state(void)
130{
131 uint32_t exit_controls = vmreadz(VM_EXIT_CONTROLS);
132
133 vmwrite(HOST_ES_SELECTOR, get_es());
134 vmwrite(HOST_CS_SELECTOR, get_cs());
135 vmwrite(HOST_SS_SELECTOR, get_ss());
136 vmwrite(HOST_DS_SELECTOR, get_ds());
137 vmwrite(HOST_FS_SELECTOR, get_fs());
138 vmwrite(HOST_GS_SELECTOR, get_gs());
139 vmwrite(HOST_TR_SELECTOR, get_tr());
140
141 if (exit_controls & VM_EXIT_LOAD_IA32_PAT)
142 vmwrite(HOST_IA32_PAT, rdmsr(MSR_IA32_CR_PAT));
143 if (exit_controls & VM_EXIT_LOAD_IA32_EFER)
144 vmwrite(HOST_IA32_EFER, rdmsr(MSR_EFER));
145 if (exit_controls & VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL)
146 vmwrite(HOST_IA32_PERF_GLOBAL_CTRL,
147 rdmsr(MSR_CORE_PERF_GLOBAL_CTRL));
148
149 vmwrite(HOST_IA32_SYSENTER_CS, rdmsr(MSR_IA32_SYSENTER_CS));
150
151 vmwrite(HOST_CR0, get_cr0());
152 vmwrite(HOST_CR3, get_cr3());
153 vmwrite(HOST_CR4, get_cr4());
154 vmwrite(HOST_FS_BASE, rdmsr(MSR_FS_BASE));
155 vmwrite(HOST_GS_BASE, rdmsr(MSR_GS_BASE));
156 vmwrite(HOST_TR_BASE,
157 get_desc64_base((struct desc64 *)(get_gdt_base() + get_tr())));
158 vmwrite(HOST_GDTR_BASE, get_gdt_base());
159 vmwrite(HOST_IDTR_BASE, get_idt_base());
160 vmwrite(HOST_IA32_SYSENTER_ESP, rdmsr(MSR_IA32_SYSENTER_ESP));
161 vmwrite(HOST_IA32_SYSENTER_EIP, rdmsr(MSR_IA32_SYSENTER_EIP));
162}
163
164/*
165 * Initialize the guest state fields essentially as a clone of
166 * the host state fields. Some host state fields have fixed
167 * values, and we set the corresponding guest state fields accordingly.
168 */
169static inline void init_vmcs_guest_state(void *rip, void *rsp)
170{
171 vmwrite(GUEST_ES_SELECTOR, vmreadz(HOST_ES_SELECTOR));
172 vmwrite(GUEST_CS_SELECTOR, vmreadz(HOST_CS_SELECTOR));
173 vmwrite(GUEST_SS_SELECTOR, vmreadz(HOST_SS_SELECTOR));
174 vmwrite(GUEST_DS_SELECTOR, vmreadz(HOST_DS_SELECTOR));
175 vmwrite(GUEST_FS_SELECTOR, vmreadz(HOST_FS_SELECTOR));
176 vmwrite(GUEST_GS_SELECTOR, vmreadz(HOST_GS_SELECTOR));
177 vmwrite(GUEST_LDTR_SELECTOR, 0);
178 vmwrite(GUEST_TR_SELECTOR, vmreadz(HOST_TR_SELECTOR));
179 vmwrite(GUEST_INTR_STATUS, 0);
180 vmwrite(GUEST_PML_INDEX, 0);
181
182 vmwrite(VMCS_LINK_POINTER, -1ll);
183 vmwrite(GUEST_IA32_DEBUGCTL, 0);
184 vmwrite(GUEST_IA32_PAT, vmreadz(HOST_IA32_PAT));
185 vmwrite(GUEST_IA32_EFER, vmreadz(HOST_IA32_EFER));
186 vmwrite(GUEST_IA32_PERF_GLOBAL_CTRL,
187 vmreadz(HOST_IA32_PERF_GLOBAL_CTRL));
188
189 vmwrite(GUEST_ES_LIMIT, -1);
190 vmwrite(GUEST_CS_LIMIT, -1);
191 vmwrite(GUEST_SS_LIMIT, -1);
192 vmwrite(GUEST_DS_LIMIT, -1);
193 vmwrite(GUEST_FS_LIMIT, -1);
194 vmwrite(GUEST_GS_LIMIT, -1);
195 vmwrite(GUEST_LDTR_LIMIT, -1);
196 vmwrite(GUEST_TR_LIMIT, 0x67);
197 vmwrite(GUEST_GDTR_LIMIT, 0xffff);
198 vmwrite(GUEST_IDTR_LIMIT, 0xffff);
199 vmwrite(GUEST_ES_AR_BYTES,
200 vmreadz(GUEST_ES_SELECTOR) == 0 ? 0x10000 : 0xc093);
201 vmwrite(GUEST_CS_AR_BYTES, 0xa09b);
202 vmwrite(GUEST_SS_AR_BYTES, 0xc093);
203 vmwrite(GUEST_DS_AR_BYTES,
204 vmreadz(GUEST_DS_SELECTOR) == 0 ? 0x10000 : 0xc093);
205 vmwrite(GUEST_FS_AR_BYTES,
206 vmreadz(GUEST_FS_SELECTOR) == 0 ? 0x10000 : 0xc093);
207 vmwrite(GUEST_GS_AR_BYTES,
208 vmreadz(GUEST_GS_SELECTOR) == 0 ? 0x10000 : 0xc093);
209 vmwrite(GUEST_LDTR_AR_BYTES, 0x10000);
210 vmwrite(GUEST_TR_AR_BYTES, 0x8b);
211 vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
212 vmwrite(GUEST_ACTIVITY_STATE, 0);
213 vmwrite(GUEST_SYSENTER_CS, vmreadz(HOST_IA32_SYSENTER_CS));
214 vmwrite(VMX_PREEMPTION_TIMER_VALUE, 0);
215
216 vmwrite(GUEST_CR0, vmreadz(HOST_CR0));
217 vmwrite(GUEST_CR3, vmreadz(HOST_CR3));
218 vmwrite(GUEST_CR4, vmreadz(HOST_CR4));
219 vmwrite(GUEST_ES_BASE, 0);
220 vmwrite(GUEST_CS_BASE, 0);
221 vmwrite(GUEST_SS_BASE, 0);
222 vmwrite(GUEST_DS_BASE, 0);
223 vmwrite(GUEST_FS_BASE, vmreadz(HOST_FS_BASE));
224 vmwrite(GUEST_GS_BASE, vmreadz(HOST_GS_BASE));
225 vmwrite(GUEST_LDTR_BASE, 0);
226 vmwrite(GUEST_TR_BASE, vmreadz(HOST_TR_BASE));
227 vmwrite(GUEST_GDTR_BASE, vmreadz(HOST_GDTR_BASE));
228 vmwrite(GUEST_IDTR_BASE, vmreadz(HOST_IDTR_BASE));
229 vmwrite(GUEST_DR7, 0x400);
230 vmwrite(GUEST_RSP, (uint64_t)rsp);
231 vmwrite(GUEST_RIP, (uint64_t)rip);
232 vmwrite(GUEST_RFLAGS, 2);
233 vmwrite(GUEST_PENDING_DBG_EXCEPTIONS, 0);
234 vmwrite(GUEST_SYSENTER_ESP, vmreadz(HOST_IA32_SYSENTER_ESP));
235 vmwrite(GUEST_SYSENTER_EIP, vmreadz(HOST_IA32_SYSENTER_EIP));
236}
237
238void prepare_vmcs(void *guest_rip, void *guest_rsp)
239{
240 init_vmcs_control_fields();
241 init_vmcs_host_state();
242 init_vmcs_guest_state(guest_rip, guest_rsp);
243}
diff --git a/tools/testing/selftests/kvm/lib/x86.c b/tools/testing/selftests/kvm/lib/x86.c
new file mode 100644
index 000000000000..2f17675f4275
--- /dev/null
+++ b/tools/testing/selftests/kvm/lib/x86.c
@@ -0,0 +1,700 @@
1/*
2 * tools/testing/selftests/kvm/lib/x86.c
3 *
4 * Copyright (C) 2018, Google LLC.
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2.
7 */
8
9#define _GNU_SOURCE /* for program_invocation_name */
10
11#include "test_util.h"
12#include "kvm_util.h"
13#include "kvm_util_internal.h"
14#include "x86.h"
15
16/* Minimum physical address used for virtual translation tables. */
17#define KVM_GUEST_PAGE_TABLE_MIN_PADDR 0x180000
18
19/* Virtual translation table structure declarations */
20struct pageMapL4Entry {
21 uint64_t present:1;
22 uint64_t writable:1;
23 uint64_t user:1;
24 uint64_t write_through:1;
25 uint64_t cache_disable:1;
26 uint64_t accessed:1;
27 uint64_t ignored_06:1;
28 uint64_t page_size:1;
29 uint64_t ignored_11_08:4;
30 uint64_t address:40;
31 uint64_t ignored_62_52:11;
32 uint64_t execute_disable:1;
33};
34
35struct pageDirectoryPointerEntry {
36 uint64_t present:1;
37 uint64_t writable:1;
38 uint64_t user:1;
39 uint64_t write_through:1;
40 uint64_t cache_disable:1;
41 uint64_t accessed:1;
42 uint64_t ignored_06:1;
43 uint64_t page_size:1;
44 uint64_t ignored_11_08:4;
45 uint64_t address:40;
46 uint64_t ignored_62_52:11;
47 uint64_t execute_disable:1;
48};
49
50struct pageDirectoryEntry {
51 uint64_t present:1;
52 uint64_t writable:1;
53 uint64_t user:1;
54 uint64_t write_through:1;
55 uint64_t cache_disable:1;
56 uint64_t accessed:1;
57 uint64_t ignored_06:1;
58 uint64_t page_size:1;
59 uint64_t ignored_11_08:4;
60 uint64_t address:40;
61 uint64_t ignored_62_52:11;
62 uint64_t execute_disable:1;
63};
64
65struct pageTableEntry {
66 uint64_t present:1;
67 uint64_t writable:1;
68 uint64_t user:1;
69 uint64_t write_through:1;
70 uint64_t cache_disable:1;
71 uint64_t accessed:1;
72 uint64_t dirty:1;
73 uint64_t reserved_07:1;
74 uint64_t global:1;
75 uint64_t ignored_11_09:3;
76 uint64_t address:40;
77 uint64_t ignored_62_52:11;
78 uint64_t execute_disable:1;
79};
80
81/* Register Dump
82 *
83 * Input Args:
84 * indent - Left margin indent amount
85 * regs - register
86 *
87 * Output Args:
88 * stream - Output FILE stream
89 *
90 * Return: None
91 *
92 * Dumps the state of the registers given by regs, to the FILE stream
93 * given by steam.
94 */
95void regs_dump(FILE *stream, struct kvm_regs *regs,
96 uint8_t indent)
97{
98 fprintf(stream, "%*srax: 0x%.16llx rbx: 0x%.16llx "
99 "rcx: 0x%.16llx rdx: 0x%.16llx\n",
100 indent, "",
101 regs->rax, regs->rbx, regs->rcx, regs->rdx);
102 fprintf(stream, "%*srsi: 0x%.16llx rdi: 0x%.16llx "
103 "rsp: 0x%.16llx rbp: 0x%.16llx\n",
104 indent, "",
105 regs->rsi, regs->rdi, regs->rsp, regs->rbp);
106 fprintf(stream, "%*sr8: 0x%.16llx r9: 0x%.16llx "
107 "r10: 0x%.16llx r11: 0x%.16llx\n",
108 indent, "",
109 regs->r8, regs->r9, regs->r10, regs->r11);
110 fprintf(stream, "%*sr12: 0x%.16llx r13: 0x%.16llx "
111 "r14: 0x%.16llx r15: 0x%.16llx\n",
112 indent, "",
113 regs->r12, regs->r13, regs->r14, regs->r15);
114 fprintf(stream, "%*srip: 0x%.16llx rfl: 0x%.16llx\n",
115 indent, "",
116 regs->rip, regs->rflags);
117}
118
119/* Segment Dump
120 *
121 * Input Args:
122 * indent - Left margin indent amount
123 * segment - KVM segment
124 *
125 * Output Args:
126 * stream - Output FILE stream
127 *
128 * Return: None
129 *
130 * Dumps the state of the KVM segment given by segment, to the FILE stream
131 * given by steam.
132 */
133static void segment_dump(FILE *stream, struct kvm_segment *segment,
134 uint8_t indent)
135{
136 fprintf(stream, "%*sbase: 0x%.16llx limit: 0x%.8x "
137 "selector: 0x%.4x type: 0x%.2x\n",
138 indent, "", segment->base, segment->limit,
139 segment->selector, segment->type);
140 fprintf(stream, "%*spresent: 0x%.2x dpl: 0x%.2x "
141 "db: 0x%.2x s: 0x%.2x l: 0x%.2x\n",
142 indent, "", segment->present, segment->dpl,
143 segment->db, segment->s, segment->l);
144 fprintf(stream, "%*sg: 0x%.2x avl: 0x%.2x "
145 "unusable: 0x%.2x padding: 0x%.2x\n",
146 indent, "", segment->g, segment->avl,
147 segment->unusable, segment->padding);
148}
149
150/* dtable Dump
151 *
152 * Input Args:
153 * indent - Left margin indent amount
154 * dtable - KVM dtable
155 *
156 * Output Args:
157 * stream - Output FILE stream
158 *
159 * Return: None
160 *
161 * Dumps the state of the KVM dtable given by dtable, to the FILE stream
162 * given by steam.
163 */
164static void dtable_dump(FILE *stream, struct kvm_dtable *dtable,
165 uint8_t indent)
166{
167 fprintf(stream, "%*sbase: 0x%.16llx limit: 0x%.4x "
168 "padding: 0x%.4x 0x%.4x 0x%.4x\n",
169 indent, "", dtable->base, dtable->limit,
170 dtable->padding[0], dtable->padding[1], dtable->padding[2]);
171}
172
173/* System Register Dump
174 *
175 * Input Args:
176 * indent - Left margin indent amount
177 * sregs - System registers
178 *
179 * Output Args:
180 * stream - Output FILE stream
181 *
182 * Return: None
183 *
184 * Dumps the state of the system registers given by sregs, to the FILE stream
185 * given by steam.
186 */
187void sregs_dump(FILE *stream, struct kvm_sregs *sregs,
188 uint8_t indent)
189{
190 unsigned int i;
191
192 fprintf(stream, "%*scs:\n", indent, "");
193 segment_dump(stream, &sregs->cs, indent + 2);
194 fprintf(stream, "%*sds:\n", indent, "");
195 segment_dump(stream, &sregs->ds, indent + 2);
196 fprintf(stream, "%*ses:\n", indent, "");
197 segment_dump(stream, &sregs->es, indent + 2);
198 fprintf(stream, "%*sfs:\n", indent, "");
199 segment_dump(stream, &sregs->fs, indent + 2);
200 fprintf(stream, "%*sgs:\n", indent, "");
201 segment_dump(stream, &sregs->gs, indent + 2);
202 fprintf(stream, "%*sss:\n", indent, "");
203 segment_dump(stream, &sregs->ss, indent + 2);
204 fprintf(stream, "%*str:\n", indent, "");
205 segment_dump(stream, &sregs->tr, indent + 2);
206 fprintf(stream, "%*sldt:\n", indent, "");
207 segment_dump(stream, &sregs->ldt, indent + 2);
208
209 fprintf(stream, "%*sgdt:\n", indent, "");
210 dtable_dump(stream, &sregs->gdt, indent + 2);
211 fprintf(stream, "%*sidt:\n", indent, "");
212 dtable_dump(stream, &sregs->idt, indent + 2);
213
214 fprintf(stream, "%*scr0: 0x%.16llx cr2: 0x%.16llx "
215 "cr3: 0x%.16llx cr4: 0x%.16llx\n",
216 indent, "",
217 sregs->cr0, sregs->cr2, sregs->cr3, sregs->cr4);
218 fprintf(stream, "%*scr8: 0x%.16llx efer: 0x%.16llx "
219 "apic_base: 0x%.16llx\n",
220 indent, "",
221 sregs->cr8, sregs->efer, sregs->apic_base);
222
223 fprintf(stream, "%*sinterrupt_bitmap:\n", indent, "");
224 for (i = 0; i < (KVM_NR_INTERRUPTS + 63) / 64; i++) {
225 fprintf(stream, "%*s%.16llx\n", indent + 2, "",
226 sregs->interrupt_bitmap[i]);
227 }
228}
229
230void virt_pgd_alloc(struct kvm_vm *vm, uint32_t pgd_memslot)
231{
232 int rc;
233
234 TEST_ASSERT(vm->mode == VM_MODE_FLAT48PG, "Attempt to use "
235 "unknown or unsupported guest mode, mode: 0x%x", vm->mode);
236
237 /* If needed, create page map l4 table. */
238 if (!vm->pgd_created) {
239 vm_paddr_t paddr = vm_phy_page_alloc(vm,
240 KVM_GUEST_PAGE_TABLE_MIN_PADDR, pgd_memslot);
241 vm->pgd = paddr;
242
243 /* Set pointer to pgd tables in all the VCPUs that
244 * have already been created. Future VCPUs will have
245 * the value set as each one is created.
246 */
247 for (struct vcpu *vcpu = vm->vcpu_head; vcpu;
248 vcpu = vcpu->next) {
249 struct kvm_sregs sregs;
250
251 /* Obtain the current system register settings */
252 vcpu_sregs_get(vm, vcpu->id, &sregs);
253
254 /* Set and store the pointer to the start of the
255 * pgd tables.
256 */
257 sregs.cr3 = vm->pgd;
258 vcpu_sregs_set(vm, vcpu->id, &sregs);
259 }
260
261 vm->pgd_created = true;
262 }
263}
264
265/* VM Virtual Page Map
266 *
267 * Input Args:
268 * vm - Virtual Machine
269 * vaddr - VM Virtual Address
270 * paddr - VM Physical Address
271 * pgd_memslot - Memory region slot for new virtual translation tables
272 *
273 * Output Args: None
274 *
275 * Return: None
276 *
277 * Within the VM given by vm, creates a virtual translation for the page
278 * starting at vaddr to the page starting at paddr.
279 */
280void virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr,
281 uint32_t pgd_memslot)
282{
283 uint16_t index[4];
284 struct pageMapL4Entry *pml4e;
285
286 TEST_ASSERT(vm->mode == VM_MODE_FLAT48PG, "Attempt to use "
287 "unknown or unsupported guest mode, mode: 0x%x", vm->mode);
288
289 TEST_ASSERT((vaddr % vm->page_size) == 0,
290 "Virtual address not on page boundary,\n"
291 " vaddr: 0x%lx vm->page_size: 0x%x",
292 vaddr, vm->page_size);
293 TEST_ASSERT(sparsebit_is_set(vm->vpages_valid,
294 (vaddr >> vm->page_shift)),
295 "Invalid virtual address, vaddr: 0x%lx",
296 vaddr);
297 TEST_ASSERT((paddr % vm->page_size) == 0,
298 "Physical address not on page boundary,\n"
299 " paddr: 0x%lx vm->page_size: 0x%x",
300 paddr, vm->page_size);
301 TEST_ASSERT((paddr >> vm->page_shift) <= vm->max_gfn,
302 "Physical address beyond beyond maximum supported,\n"
303 " paddr: 0x%lx vm->max_gfn: 0x%lx vm->page_size: 0x%x",
304 paddr, vm->max_gfn, vm->page_size);
305
306 index[0] = (vaddr >> 12) & 0x1ffu;
307 index[1] = (vaddr >> 21) & 0x1ffu;
308 index[2] = (vaddr >> 30) & 0x1ffu;
309 index[3] = (vaddr >> 39) & 0x1ffu;
310
311 /* Allocate page directory pointer table if not present. */
312 pml4e = addr_gpa2hva(vm, vm->pgd);
313 if (!pml4e[index[3]].present) {
314 pml4e[index[3]].address = vm_phy_page_alloc(vm,
315 KVM_GUEST_PAGE_TABLE_MIN_PADDR, pgd_memslot)
316 >> vm->page_shift;
317 pml4e[index[3]].writable = true;
318 pml4e[index[3]].present = true;
319 }
320
321 /* Allocate page directory table if not present. */
322 struct pageDirectoryPointerEntry *pdpe;
323 pdpe = addr_gpa2hva(vm, pml4e[index[3]].address * vm->page_size);
324 if (!pdpe[index[2]].present) {
325 pdpe[index[2]].address = vm_phy_page_alloc(vm,
326 KVM_GUEST_PAGE_TABLE_MIN_PADDR, pgd_memslot)
327 >> vm->page_shift;
328 pdpe[index[2]].writable = true;
329 pdpe[index[2]].present = true;
330 }
331
332 /* Allocate page table if not present. */
333 struct pageDirectoryEntry *pde;
334 pde = addr_gpa2hva(vm, pdpe[index[2]].address * vm->page_size);
335 if (!pde[index[1]].present) {
336 pde[index[1]].address = vm_phy_page_alloc(vm,
337 KVM_GUEST_PAGE_TABLE_MIN_PADDR, pgd_memslot)
338 >> vm->page_shift;
339 pde[index[1]].writable = true;
340 pde[index[1]].present = true;
341 }
342
343 /* Fill in page table entry. */
344 struct pageTableEntry *pte;
345 pte = addr_gpa2hva(vm, pde[index[1]].address * vm->page_size);
346 pte[index[0]].address = paddr >> vm->page_shift;
347 pte[index[0]].writable = true;
348 pte[index[0]].present = 1;
349}
350
351/* Virtual Translation Tables Dump
352 *
353 * Input Args:
354 * vm - Virtual Machine
355 * indent - Left margin indent amount
356 *
357 * Output Args:
358 * stream - Output FILE stream
359 *
360 * Return: None
361 *
362 * Dumps to the FILE stream given by stream, the contents of all the
363 * virtual translation tables for the VM given by vm.
364 */
365void virt_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent)
366{
367 struct pageMapL4Entry *pml4e, *pml4e_start;
368 struct pageDirectoryPointerEntry *pdpe, *pdpe_start;
369 struct pageDirectoryEntry *pde, *pde_start;
370 struct pageTableEntry *pte, *pte_start;
371
372 if (!vm->pgd_created)
373 return;
374
375 fprintf(stream, "%*s "
376 " no\n", indent, "");
377 fprintf(stream, "%*s index hvaddr gpaddr "
378 "addr w exec dirty\n",
379 indent, "");
380 pml4e_start = (struct pageMapL4Entry *) addr_gpa2hva(vm,
381 vm->pgd);
382 for (uint16_t n1 = 0; n1 <= 0x1ffu; n1++) {
383 pml4e = &pml4e_start[n1];
384 if (!pml4e->present)
385 continue;
386 fprintf(stream, "%*spml4e 0x%-3zx %p 0x%-12lx 0x%-10lx %u "
387 " %u\n",
388 indent, "",
389 pml4e - pml4e_start, pml4e,
390 addr_hva2gpa(vm, pml4e), (uint64_t) pml4e->address,
391 pml4e->writable, pml4e->execute_disable);
392
393 pdpe_start = addr_gpa2hva(vm, pml4e->address
394 * vm->page_size);
395 for (uint16_t n2 = 0; n2 <= 0x1ffu; n2++) {
396 pdpe = &pdpe_start[n2];
397 if (!pdpe->present)
398 continue;
399 fprintf(stream, "%*spdpe 0x%-3zx %p 0x%-12lx 0x%-10lx "
400 "%u %u\n",
401 indent, "",
402 pdpe - pdpe_start, pdpe,
403 addr_hva2gpa(vm, pdpe),
404 (uint64_t) pdpe->address, pdpe->writable,
405 pdpe->execute_disable);
406
407 pde_start = addr_gpa2hva(vm,
408 pdpe->address * vm->page_size);
409 for (uint16_t n3 = 0; n3 <= 0x1ffu; n3++) {
410 pde = &pde_start[n3];
411 if (!pde->present)
412 continue;
413 fprintf(stream, "%*spde 0x%-3zx %p "
414 "0x%-12lx 0x%-10lx %u %u\n",
415 indent, "", pde - pde_start, pde,
416 addr_hva2gpa(vm, pde),
417 (uint64_t) pde->address, pde->writable,
418 pde->execute_disable);
419
420 pte_start = addr_gpa2hva(vm,
421 pde->address * vm->page_size);
422 for (uint16_t n4 = 0; n4 <= 0x1ffu; n4++) {
423 pte = &pte_start[n4];
424 if (!pte->present)
425 continue;
426 fprintf(stream, "%*spte 0x%-3zx %p "
427 "0x%-12lx 0x%-10lx %u %u "
428 " %u 0x%-10lx\n",
429 indent, "",
430 pte - pte_start, pte,
431 addr_hva2gpa(vm, pte),
432 (uint64_t) pte->address,
433 pte->writable,
434 pte->execute_disable,
435 pte->dirty,
436 ((uint64_t) n1 << 27)
437 | ((uint64_t) n2 << 18)
438 | ((uint64_t) n3 << 9)
439 | ((uint64_t) n4));
440 }
441 }
442 }
443 }
444}
445
446/* Set Unusable Segment
447 *
448 * Input Args: None
449 *
450 * Output Args:
451 * segp - Pointer to segment register
452 *
453 * Return: None
454 *
455 * Sets the segment register pointed to by segp to an unusable state.
456 */
457static void kvm_seg_set_unusable(struct kvm_segment *segp)
458{
459 memset(segp, 0, sizeof(*segp));
460 segp->unusable = true;
461}
462
463/* Set Long Mode Flat Kernel Code Segment
464 *
465 * Input Args:
466 * selector - selector value
467 *
468 * Output Args:
469 * segp - Pointer to KVM segment
470 *
471 * Return: None
472 *
473 * Sets up the KVM segment pointed to by segp, to be a code segment
474 * with the selector value given by selector.
475 */
476static void kvm_seg_set_kernel_code_64bit(uint16_t selector,
477 struct kvm_segment *segp)
478{
479 memset(segp, 0, sizeof(*segp));
480 segp->selector = selector;
481 segp->limit = 0xFFFFFFFFu;
482 segp->s = 0x1; /* kTypeCodeData */
483 segp->type = 0x08 | 0x01 | 0x02; /* kFlagCode | kFlagCodeAccessed
484 * | kFlagCodeReadable
485 */
486 segp->g = true;
487 segp->l = true;
488 segp->present = 1;
489}
490
491/* Set Long Mode Flat Kernel Data Segment
492 *
493 * Input Args:
494 * selector - selector value
495 *
496 * Output Args:
497 * segp - Pointer to KVM segment
498 *
499 * Return: None
500 *
501 * Sets up the KVM segment pointed to by segp, to be a data segment
502 * with the selector value given by selector.
503 */
504static void kvm_seg_set_kernel_data_64bit(uint16_t selector,
505 struct kvm_segment *segp)
506{
507 memset(segp, 0, sizeof(*segp));
508 segp->selector = selector;
509 segp->limit = 0xFFFFFFFFu;
510 segp->s = 0x1; /* kTypeCodeData */
511 segp->type = 0x00 | 0x01 | 0x02; /* kFlagData | kFlagDataAccessed
512 * | kFlagDataWritable
513 */
514 segp->g = true;
515 segp->present = true;
516}
517
518/* Address Guest Virtual to Guest Physical
519 *
520 * Input Args:
521 * vm - Virtual Machine
522 * gpa - VM virtual address
523 *
524 * Output Args: None
525 *
526 * Return:
527 * Equivalent VM physical address
528 *
529 * Translates the VM virtual address given by gva to a VM physical
530 * address and then locates the memory region containing the VM
531 * physical address, within the VM given by vm. When found, the host
532 * virtual address providing the memory to the vm physical address is returned.
533 * A TEST_ASSERT failure occurs if no region containing translated
534 * VM virtual address exists.
535 */
536vm_paddr_t addr_gva2gpa(struct kvm_vm *vm, vm_vaddr_t gva)
537{
538 uint16_t index[4];
539 struct pageMapL4Entry *pml4e;
540 struct pageDirectoryPointerEntry *pdpe;
541 struct pageDirectoryEntry *pde;
542 struct pageTableEntry *pte;
543 void *hva;
544
545 TEST_ASSERT(vm->mode == VM_MODE_FLAT48PG, "Attempt to use "
546 "unknown or unsupported guest mode, mode: 0x%x", vm->mode);
547
548 index[0] = (gva >> 12) & 0x1ffu;
549 index[1] = (gva >> 21) & 0x1ffu;
550 index[2] = (gva >> 30) & 0x1ffu;
551 index[3] = (gva >> 39) & 0x1ffu;
552
553 if (!vm->pgd_created)
554 goto unmapped_gva;
555 pml4e = addr_gpa2hva(vm, vm->pgd);
556 if (!pml4e[index[3]].present)
557 goto unmapped_gva;
558
559 pdpe = addr_gpa2hva(vm, pml4e[index[3]].address * vm->page_size);
560 if (!pdpe[index[2]].present)
561 goto unmapped_gva;
562
563 pde = addr_gpa2hva(vm, pdpe[index[2]].address * vm->page_size);
564 if (!pde[index[1]].present)
565 goto unmapped_gva;
566
567 pte = addr_gpa2hva(vm, pde[index[1]].address * vm->page_size);
568 if (!pte[index[0]].present)
569 goto unmapped_gva;
570
571 return (pte[index[0]].address * vm->page_size) + (gva & 0xfffu);
572
573unmapped_gva:
574 TEST_ASSERT(false, "No mapping for vm virtual address, "
575 "gva: 0x%lx", gva);
576}
577
578void vcpu_setup(struct kvm_vm *vm, int vcpuid)
579{
580 struct kvm_sregs sregs;
581
582 /* Set mode specific system register values. */
583 vcpu_sregs_get(vm, vcpuid, &sregs);
584
585 switch (vm->mode) {
586 case VM_MODE_FLAT48PG:
587 sregs.cr0 = X86_CR0_PE | X86_CR0_NE | X86_CR0_PG;
588 sregs.cr4 |= X86_CR4_PAE;
589 sregs.efer |= (EFER_LME | EFER_LMA | EFER_NX);
590
591 kvm_seg_set_unusable(&sregs.ldt);
592 kvm_seg_set_kernel_code_64bit(0x8, &sregs.cs);
593 kvm_seg_set_kernel_data_64bit(0x10, &sregs.ds);
594 kvm_seg_set_kernel_data_64bit(0x10, &sregs.es);
595 break;
596
597 default:
598 TEST_ASSERT(false, "Unknown guest mode, mode: 0x%x", vm->mode);
599 }
600 vcpu_sregs_set(vm, vcpuid, &sregs);
601
602 /* If virtual translation table have been setup, set system register
603 * to point to the tables. It's okay if they haven't been setup yet,
604 * in that the code that sets up the virtual translation tables, will
605 * go back through any VCPUs that have already been created and set
606 * their values.
607 */
608 if (vm->pgd_created) {
609 struct kvm_sregs sregs;
610
611 vcpu_sregs_get(vm, vcpuid, &sregs);
612
613 sregs.cr3 = vm->pgd;
614 vcpu_sregs_set(vm, vcpuid, &sregs);
615 }
616}
617/* Adds a vCPU with reasonable defaults (i.e., a stack)
618 *
619 * Input Args:
620 * vcpuid - The id of the VCPU to add to the VM.
621 * guest_code - The vCPU's entry point
622 */
623void vm_vcpu_add_default(struct kvm_vm *vm, uint32_t vcpuid, void *guest_code)
624{
625 struct kvm_mp_state mp_state;
626 struct kvm_regs regs;
627 vm_vaddr_t stack_vaddr;
628 stack_vaddr = vm_vaddr_alloc(vm, DEFAULT_STACK_PGS * getpagesize(),
629 DEFAULT_GUEST_STACK_VADDR_MIN, 0, 0);
630
631 /* Create VCPU */
632 vm_vcpu_add(vm, vcpuid);
633
634 /* Setup guest general purpose registers */
635 vcpu_regs_get(vm, vcpuid, &regs);
636 regs.rflags = regs.rflags | 0x2;
637 regs.rsp = stack_vaddr + (DEFAULT_STACK_PGS * getpagesize());
638 regs.rip = (unsigned long) guest_code;
639 vcpu_regs_set(vm, vcpuid, &regs);
640
641 /* Setup the MP state */
642 mp_state.mp_state = 0;
643 vcpu_set_mp_state(vm, vcpuid, &mp_state);
644}
645
646/* VM VCPU CPUID Set
647 *
648 * Input Args:
649 * vm - Virtual Machine
650 * vcpuid - VCPU id
651 * cpuid - The CPUID values to set.
652 *
653 * Output Args: None
654 *
655 * Return: void
656 *
657 * Set the VCPU's CPUID.
658 */
659void vcpu_set_cpuid(struct kvm_vm *vm,
660 uint32_t vcpuid, struct kvm_cpuid2 *cpuid)
661{
662 struct vcpu *vcpu = vcpu_find(vm, vcpuid);
663 int rc;
664
665 TEST_ASSERT(vcpu != NULL, "vcpu not found, vcpuid: %u", vcpuid);
666
667 rc = ioctl(vcpu->fd, KVM_SET_CPUID2, cpuid);
668 TEST_ASSERT(rc == 0, "KVM_SET_CPUID2 failed, rc: %i errno: %i",
669 rc, errno);
670
671}
672/* Create a VM with reasonable defaults
673 *
674 * Input Args:
675 * vcpuid - The id of the single VCPU to add to the VM.
676 * guest_code - The vCPU's entry point
677 *
678 * Output Args: None
679 *
680 * Return:
681 * Pointer to opaque structure that describes the created VM.
682 */
683struct kvm_vm *vm_create_default(uint32_t vcpuid, void *guest_code)
684{
685 struct kvm_vm *vm;
686
687 /* Create VM */
688 vm = vm_create(VM_MODE_FLAT48PG, DEFAULT_GUEST_PHY_PAGES, O_RDWR);
689
690 /* Setup guest code */
691 kvm_vm_elf_load(vm, program_invocation_name, 0, 0);
692
693 /* Setup IRQ Chip */
694 vm_create_irqchip(vm);
695
696 /* Add the first vCPU. */
697 vm_vcpu_add_default(vm, vcpuid, guest_code);
698
699 return vm;
700}
diff --git a/tools/testing/selftests/kvm/set_sregs_test.c b/tools/testing/selftests/kvm/set_sregs_test.c
new file mode 100644
index 000000000000..090fd3f19352
--- /dev/null
+++ b/tools/testing/selftests/kvm/set_sregs_test.c
@@ -0,0 +1,54 @@
1/*
2 * KVM_SET_SREGS tests
3 *
4 * Copyright (C) 2018, Google LLC.
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2.
7 *
8 * This is a regression test for the bug fixed by the following commit:
9 * d3802286fa0f ("kvm: x86: Disallow illegal IA32_APIC_BASE MSR values")
10 *
11 * That bug allowed a user-mode program that called the KVM_SET_SREGS
12 * ioctl to put a VCPU's local APIC into an invalid state.
13 *
14 */
15#define _GNU_SOURCE /* for program_invocation_short_name */
16#include <fcntl.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <sys/ioctl.h>
21
22#include "test_util.h"
23
24#include "kvm_util.h"
25#include "x86.h"
26
27#define VCPU_ID 5
28
29int main(int argc, char *argv[])
30{
31 struct kvm_sregs sregs;
32 struct kvm_vm *vm;
33 int rc;
34
35 /* Tell stdout not to buffer its content */
36 setbuf(stdout, NULL);
37
38 /* Create VM */
39 vm = vm_create_default(VCPU_ID, NULL);
40
41 vcpu_sregs_get(vm, VCPU_ID, &sregs);
42 sregs.apic_base = 1 << 10;
43 rc = _vcpu_sregs_set(vm, VCPU_ID, &sregs);
44 TEST_ASSERT(rc, "Set IA32_APIC_BASE to %llx (invalid)",
45 sregs.apic_base);
46 sregs.apic_base = 1 << 11;
47 rc = _vcpu_sregs_set(vm, VCPU_ID, &sregs);
48 TEST_ASSERT(!rc, "Couldn't set IA32_APIC_BASE to %llx (valid)",
49 sregs.apic_base);
50
51 kvm_vm_free(vm);
52
53 return 0;
54}
diff --git a/tools/testing/selftests/kvm/sync_regs_test.c b/tools/testing/selftests/kvm/sync_regs_test.c
new file mode 100644
index 000000000000..428e9473f5e2
--- /dev/null
+++ b/tools/testing/selftests/kvm/sync_regs_test.c
@@ -0,0 +1,232 @@
1/*
2 * Test for x86 KVM_CAP_SYNC_REGS
3 *
4 * Copyright (C) 2018, Google LLC.
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2.
7 *
8 * Verifies expected behavior of x86 KVM_CAP_SYNC_REGS functionality,
9 * including requesting an invalid register set, updates to/from values
10 * in kvm_run.s.regs when kvm_valid_regs and kvm_dirty_regs are toggled.
11 */
12
13#define _GNU_SOURCE /* for program_invocation_short_name */
14#include <fcntl.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18#include <sys/ioctl.h>
19
20#include "test_util.h"
21#include "kvm_util.h"
22#include "x86.h"
23
24#define VCPU_ID 5
25#define PORT_HOST_SYNC 0x1000
26
27static void __exit_to_l0(uint16_t port, uint64_t arg0, uint64_t arg1)
28{
29 __asm__ __volatile__("in %[port], %%al"
30 :
31 : [port]"d"(port), "D"(arg0), "S"(arg1)
32 : "rax");
33}
34
35#define exit_to_l0(_port, _arg0, _arg1) \
36 __exit_to_l0(_port, (uint64_t) (_arg0), (uint64_t) (_arg1))
37
38#define GUEST_ASSERT(_condition) do { \
39 if (!(_condition)) \
40 exit_to_l0(PORT_ABORT, "Failed guest assert: " #_condition, 0);\
41} while (0)
42
43void guest_code(void)
44{
45 for (;;) {
46 exit_to_l0(PORT_HOST_SYNC, "hello", 0);
47 asm volatile ("inc %r11");
48 }
49}
50
51static void compare_regs(struct kvm_regs *left, struct kvm_regs *right)
52{
53#define REG_COMPARE(reg) \
54 TEST_ASSERT(left->reg == right->reg, \
55 "Register " #reg \
56 " values did not match: 0x%llx, 0x%llx\n", \
57 left->reg, right->reg)
58 REG_COMPARE(rax);
59 REG_COMPARE(rbx);
60 REG_COMPARE(rcx);
61 REG_COMPARE(rdx);
62 REG_COMPARE(rsi);
63 REG_COMPARE(rdi);
64 REG_COMPARE(rsp);
65 REG_COMPARE(rbp);
66 REG_COMPARE(r8);
67 REG_COMPARE(r9);
68 REG_COMPARE(r10);
69 REG_COMPARE(r11);
70 REG_COMPARE(r12);
71 REG_COMPARE(r13);
72 REG_COMPARE(r14);
73 REG_COMPARE(r15);
74 REG_COMPARE(rip);
75 REG_COMPARE(rflags);
76#undef REG_COMPARE
77}
78
79static void compare_sregs(struct kvm_sregs *left, struct kvm_sregs *right)
80{
81}
82
83static void compare_vcpu_events(struct kvm_vcpu_events *left,
84 struct kvm_vcpu_events *right)
85{
86}
87
88int main(int argc, char *argv[])
89{
90 struct kvm_vm *vm;
91 struct kvm_run *run;
92 struct kvm_regs regs;
93 struct kvm_sregs sregs;
94 struct kvm_vcpu_events events;
95 int rv, cap;
96
97 /* Tell stdout not to buffer its content */
98 setbuf(stdout, NULL);
99
100 cap = kvm_check_cap(KVM_CAP_SYNC_REGS);
101 TEST_ASSERT((unsigned long)cap == KVM_SYNC_X86_VALID_FIELDS,
102 "KVM_CAP_SYNC_REGS (0x%x) != KVM_SYNC_X86_VALID_FIELDS (0x%lx)\n",
103 cap, KVM_SYNC_X86_VALID_FIELDS);
104
105 /* Create VM */
106 vm = vm_create_default(VCPU_ID, guest_code);
107
108 run = vcpu_state(vm, VCPU_ID);
109
110 /* Request reading invalid register set from VCPU. */
111 run->kvm_valid_regs = KVM_SYNC_X86_VALID_FIELDS << 1;
112 rv = _vcpu_run(vm, VCPU_ID);
113 TEST_ASSERT(rv < 0 && errno == EINVAL,
114 "Invalid kvm_valid_regs did not cause expected KVM_RUN error: %d\n",
115 rv);
116 vcpu_state(vm, VCPU_ID)->kvm_valid_regs = 0;
117
118 /* Request setting invalid register set into VCPU. */
119 run->kvm_dirty_regs = KVM_SYNC_X86_VALID_FIELDS << 1;
120 rv = _vcpu_run(vm, VCPU_ID);
121 TEST_ASSERT(rv < 0 && errno == EINVAL,
122 "Invalid kvm_dirty_regs did not cause expected KVM_RUN error: %d\n",
123 rv);
124 vcpu_state(vm, VCPU_ID)->kvm_dirty_regs = 0;
125
126 /* Request and verify all valid register sets. */
127 /* TODO: BUILD TIME CHECK: TEST_ASSERT(KVM_SYNC_X86_NUM_FIELDS != 3); */
128 run->kvm_valid_regs = KVM_SYNC_X86_VALID_FIELDS;
129 rv = _vcpu_run(vm, VCPU_ID);
130 TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
131 "Unexpected exit reason: %u (%s),\n",
132 run->exit_reason,
133 exit_reason_str(run->exit_reason));
134
135 vcpu_regs_get(vm, VCPU_ID, &regs);
136 compare_regs(&regs, &run->s.regs.regs);
137
138 vcpu_sregs_get(vm, VCPU_ID, &sregs);
139 compare_sregs(&sregs, &run->s.regs.sregs);
140
141 vcpu_events_get(vm, VCPU_ID, &events);
142 compare_vcpu_events(&events, &run->s.regs.events);
143
144 /* Set and verify various register values. */
145 run->s.regs.regs.r11 = 0xBAD1DEA;
146 run->s.regs.sregs.apic_base = 1 << 11;
147 /* TODO run->s.regs.events.XYZ = ABC; */
148
149 run->kvm_valid_regs = KVM_SYNC_X86_VALID_FIELDS;
150 run->kvm_dirty_regs = KVM_SYNC_X86_REGS | KVM_SYNC_X86_SREGS;
151 rv = _vcpu_run(vm, VCPU_ID);
152 TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
153 "Unexpected exit reason: %u (%s),\n",
154 run->exit_reason,
155 exit_reason_str(run->exit_reason));
156 TEST_ASSERT(run->s.regs.regs.r11 == 0xBAD1DEA + 1,
157 "r11 sync regs value incorrect 0x%llx.",
158 run->s.regs.regs.r11);
159 TEST_ASSERT(run->s.regs.sregs.apic_base == 1 << 11,
160 "apic_base sync regs value incorrect 0x%llx.",
161 run->s.regs.sregs.apic_base);
162
163 vcpu_regs_get(vm, VCPU_ID, &regs);
164 compare_regs(&regs, &run->s.regs.regs);
165
166 vcpu_sregs_get(vm, VCPU_ID, &sregs);
167 compare_sregs(&sregs, &run->s.regs.sregs);
168
169 vcpu_events_get(vm, VCPU_ID, &events);
170 compare_vcpu_events(&events, &run->s.regs.events);
171
172 /* Clear kvm_dirty_regs bits, verify new s.regs values are
173 * overwritten with existing guest values.
174 */
175 run->kvm_valid_regs = KVM_SYNC_X86_VALID_FIELDS;
176 run->kvm_dirty_regs = 0;
177 run->s.regs.regs.r11 = 0xDEADBEEF;
178 rv = _vcpu_run(vm, VCPU_ID);
179 TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
180 "Unexpected exit reason: %u (%s),\n",
181 run->exit_reason,
182 exit_reason_str(run->exit_reason));
183 TEST_ASSERT(run->s.regs.regs.r11 != 0xDEADBEEF,
184 "r11 sync regs value incorrect 0x%llx.",
185 run->s.regs.regs.r11);
186
187 /* Clear kvm_valid_regs bits and kvm_dirty_bits.
188 * Verify s.regs values are not overwritten with existing guest values
189 * and that guest values are not overwritten with kvm_sync_regs values.
190 */
191 run->kvm_valid_regs = 0;
192 run->kvm_dirty_regs = 0;
193 run->s.regs.regs.r11 = 0xAAAA;
194 regs.r11 = 0xBAC0;
195 vcpu_regs_set(vm, VCPU_ID, &regs);
196 rv = _vcpu_run(vm, VCPU_ID);
197 TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
198 "Unexpected exit reason: %u (%s),\n",
199 run->exit_reason,
200 exit_reason_str(run->exit_reason));
201 TEST_ASSERT(run->s.regs.regs.r11 == 0xAAAA,
202 "r11 sync regs value incorrect 0x%llx.",
203 run->s.regs.regs.r11);
204 vcpu_regs_get(vm, VCPU_ID, &regs);
205 TEST_ASSERT(regs.r11 == 0xBAC0 + 1,
206 "r11 guest value incorrect 0x%llx.",
207 regs.r11);
208
209 /* Clear kvm_valid_regs bits. Verify s.regs values are not overwritten
210 * with existing guest values but that guest values are overwritten
211 * with kvm_sync_regs values.
212 */
213 run->kvm_valid_regs = 0;
214 run->kvm_dirty_regs = KVM_SYNC_X86_VALID_FIELDS;
215 run->s.regs.regs.r11 = 0xBBBB;
216 rv = _vcpu_run(vm, VCPU_ID);
217 TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
218 "Unexpected exit reason: %u (%s),\n",
219 run->exit_reason,
220 exit_reason_str(run->exit_reason));
221 TEST_ASSERT(run->s.regs.regs.r11 == 0xBBBB,
222 "r11 sync regs value incorrect 0x%llx.",
223 run->s.regs.regs.r11);
224 vcpu_regs_get(vm, VCPU_ID, &regs);
225 TEST_ASSERT(regs.r11 == 0xBBBB + 1,
226 "r11 guest value incorrect 0x%llx.",
227 regs.r11);
228
229 kvm_vm_free(vm);
230
231 return 0;
232}
diff --git a/tools/testing/selftests/kvm/vmx_tsc_adjust_test.c b/tools/testing/selftests/kvm/vmx_tsc_adjust_test.c
new file mode 100644
index 000000000000..8f7f62093add
--- /dev/null
+++ b/tools/testing/selftests/kvm/vmx_tsc_adjust_test.c
@@ -0,0 +1,231 @@
1/*
2 * gtests/tests/vmx_tsc_adjust_test.c
3 *
4 * Copyright (C) 2018, Google LLC.
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2.
7 *
8 *
9 * IA32_TSC_ADJUST test
10 *
11 * According to the SDM, "if an execution of WRMSR to the
12 * IA32_TIME_STAMP_COUNTER MSR adds (or subtracts) value X from the TSC,
13 * the logical processor also adds (or subtracts) value X from the
14 * IA32_TSC_ADJUST MSR.
15 *
16 * Note that when L1 doesn't intercept writes to IA32_TSC, a
17 * WRMSR(IA32_TSC) from L2 sets L1's TSC value, not L2's perceived TSC
18 * value.
19 *
20 * This test verifies that this unusual case is handled correctly.
21 */
22
23#include "test_util.h"
24#include "kvm_util.h"
25#include "x86.h"
26#include "vmx.h"
27
28#include <string.h>
29#include <sys/ioctl.h>
30
31#ifndef MSR_IA32_TSC_ADJUST
32#define MSR_IA32_TSC_ADJUST 0x3b
33#endif
34
35#define PAGE_SIZE 4096
36#define VCPU_ID 5
37
38#define TSC_ADJUST_VALUE (1ll << 32)
39#define TSC_OFFSET_VALUE -(1ll << 48)
40
41enum {
42 PORT_ABORT = 0x1000,
43 PORT_REPORT,
44 PORT_DONE,
45};
46
47struct vmx_page {
48 vm_vaddr_t virt;
49 vm_paddr_t phys;
50};
51
52enum {
53 VMXON_PAGE = 0,
54 VMCS_PAGE,
55 MSR_BITMAP_PAGE,
56
57 NUM_VMX_PAGES,
58};
59
60struct kvm_single_msr {
61 struct kvm_msrs header;
62 struct kvm_msr_entry entry;
63} __attribute__((packed));
64
65/* The virtual machine object. */
66static struct kvm_vm *vm;
67
68/* Array of vmx_page descriptors that is shared with the guest. */
69struct vmx_page *vmx_pages;
70
71#define exit_to_l0(_port, _arg) do_exit_to_l0(_port, (unsigned long) (_arg))
72static void do_exit_to_l0(uint16_t port, unsigned long arg)
73{
74 __asm__ __volatile__("in %[port], %%al"
75 :
76 : [port]"d"(port), "D"(arg)
77 : "rax");
78}
79
80
81#define GUEST_ASSERT(_condition) do { \
82 if (!(_condition)) \
83 exit_to_l0(PORT_ABORT, "Failed guest assert: " #_condition); \
84} while (0)
85
86static void check_ia32_tsc_adjust(int64_t max)
87{
88 int64_t adjust;
89
90 adjust = rdmsr(MSR_IA32_TSC_ADJUST);
91 exit_to_l0(PORT_REPORT, adjust);
92 GUEST_ASSERT(adjust <= max);
93}
94
95static void l2_guest_code(void)
96{
97 uint64_t l1_tsc = rdtsc() - TSC_OFFSET_VALUE;
98
99 wrmsr(MSR_IA32_TSC, l1_tsc - TSC_ADJUST_VALUE);
100 check_ia32_tsc_adjust(-2 * TSC_ADJUST_VALUE);
101
102 /* Exit to L1 */
103 __asm__ __volatile__("vmcall");
104}
105
106static void l1_guest_code(struct vmx_page *vmx_pages)
107{
108#define L2_GUEST_STACK_SIZE 64
109 unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
110 uint32_t control;
111 uintptr_t save_cr3;
112
113 GUEST_ASSERT(rdtsc() < TSC_ADJUST_VALUE);
114 wrmsr(MSR_IA32_TSC, rdtsc() - TSC_ADJUST_VALUE);
115 check_ia32_tsc_adjust(-1 * TSC_ADJUST_VALUE);
116
117 prepare_for_vmx_operation();
118
119 /* Enter VMX root operation. */
120 *(uint32_t *)vmx_pages[VMXON_PAGE].virt = vmcs_revision();
121 GUEST_ASSERT(!vmxon(vmx_pages[VMXON_PAGE].phys));
122
123 /* Load a VMCS. */
124 *(uint32_t *)vmx_pages[VMCS_PAGE].virt = vmcs_revision();
125 GUEST_ASSERT(!vmclear(vmx_pages[VMCS_PAGE].phys));
126 GUEST_ASSERT(!vmptrld(vmx_pages[VMCS_PAGE].phys));
127
128 /* Prepare the VMCS for L2 execution. */
129 prepare_vmcs(l2_guest_code, &l2_guest_stack[L2_GUEST_STACK_SIZE]);
130 control = vmreadz(CPU_BASED_VM_EXEC_CONTROL);
131 control |= CPU_BASED_USE_MSR_BITMAPS | CPU_BASED_USE_TSC_OFFSETING;
132 vmwrite(CPU_BASED_VM_EXEC_CONTROL, control);
133 vmwrite(MSR_BITMAP, vmx_pages[MSR_BITMAP_PAGE].phys);
134 vmwrite(TSC_OFFSET, TSC_OFFSET_VALUE);
135
136 /* Jump into L2. First, test failure to load guest CR3. */
137 save_cr3 = vmreadz(GUEST_CR3);
138 vmwrite(GUEST_CR3, -1ull);
139 GUEST_ASSERT(!vmlaunch());
140 GUEST_ASSERT(vmreadz(VM_EXIT_REASON) ==
141 (EXIT_REASON_FAILED_VMENTRY | EXIT_REASON_INVALID_STATE));
142 check_ia32_tsc_adjust(-1 * TSC_ADJUST_VALUE);
143 vmwrite(GUEST_CR3, save_cr3);
144
145 GUEST_ASSERT(!vmlaunch());
146 GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
147
148 check_ia32_tsc_adjust(-2 * TSC_ADJUST_VALUE);
149
150 exit_to_l0(PORT_DONE, 0);
151}
152
153static void allocate_vmx_page(struct vmx_page *page)
154{
155 vm_vaddr_t virt;
156
157 virt = vm_vaddr_alloc(vm, PAGE_SIZE, 0, 0, 0);
158 memset(addr_gva2hva(vm, virt), 0, PAGE_SIZE);
159
160 page->virt = virt;
161 page->phys = addr_gva2gpa(vm, virt);
162}
163
164static vm_vaddr_t allocate_vmx_pages(void)
165{
166 vm_vaddr_t vmx_pages_vaddr;
167 int i;
168
169 vmx_pages_vaddr = vm_vaddr_alloc(
170 vm, sizeof(struct vmx_page) * NUM_VMX_PAGES, 0, 0, 0);
171
172 vmx_pages = (void *) addr_gva2hva(vm, vmx_pages_vaddr);
173
174 for (i = 0; i < NUM_VMX_PAGES; i++)
175 allocate_vmx_page(&vmx_pages[i]);
176
177 return vmx_pages_vaddr;
178}
179
180void report(int64_t val)
181{
182 printf("IA32_TSC_ADJUST is %ld (%lld * TSC_ADJUST_VALUE + %lld).\n",
183 val, val / TSC_ADJUST_VALUE, val % TSC_ADJUST_VALUE);
184}
185
186int main(int argc, char *argv[])
187{
188 vm_vaddr_t vmx_pages_vaddr;
189 struct kvm_cpuid_entry2 *entry = kvm_get_supported_cpuid_entry(1);
190
191 if (!(entry->ecx & CPUID_VMX)) {
192 printf("nested VMX not enabled, skipping test");
193 return 0;
194 }
195
196 vm = vm_create_default_vmx(VCPU_ID, (void *) l1_guest_code);
197
198 /* Allocate VMX pages and shared descriptors (vmx_pages). */
199 vmx_pages_vaddr = allocate_vmx_pages();
200 vcpu_args_set(vm, VCPU_ID, 1, vmx_pages_vaddr);
201
202 for (;;) {
203 volatile struct kvm_run *run = vcpu_state(vm, VCPU_ID);
204 struct kvm_regs regs;
205
206 vcpu_run(vm, VCPU_ID);
207 TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
208 "Got exit_reason other than KVM_EXIT_IO: %u (%s),\n",
209 run->exit_reason,
210 exit_reason_str(run->exit_reason));
211
212 vcpu_regs_get(vm, VCPU_ID, &regs);
213
214 switch (run->io.port) {
215 case PORT_ABORT:
216 TEST_ASSERT(false, "%s", (const char *) regs.rdi);
217 /* NOT REACHED */
218 case PORT_REPORT:
219 report(regs.rdi);
220 break;
221 case PORT_DONE:
222 goto done;
223 default:
224 TEST_ASSERT(false, "Unknown port 0x%x.", run->io.port);
225 }
226 }
227
228 kvm_vm_free(vm);
229done:
230 return 0;
231}
diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk
index 7de482a0519d..195e9d4739a9 100644
--- a/tools/testing/selftests/lib.mk
+++ b/tools/testing/selftests/lib.mk
@@ -20,6 +20,7 @@ all: $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES)
20 20
21.ONESHELL: 21.ONESHELL:
22define RUN_TESTS 22define RUN_TESTS
23 @export KSFT_TAP_LEVEL=`echo 1`;
23 @test_num=`echo 0`; 24 @test_num=`echo 0`;
24 @echo "TAP version 13"; 25 @echo "TAP version 13";
25 @for TEST in $(1); do \ 26 @for TEST in $(1); do \
diff --git a/tools/testing/selftests/powerpc/benchmarks/.gitignore b/tools/testing/selftests/powerpc/benchmarks/.gitignore
index 04dc1e6ef2ce..9161679b1e1a 100644
--- a/tools/testing/selftests/powerpc/benchmarks/.gitignore
+++ b/tools/testing/selftests/powerpc/benchmarks/.gitignore
@@ -1,5 +1,7 @@
1gettimeofday 1gettimeofday
2context_switch 2context_switch
3fork
4exec_target
3mmap_bench 5mmap_bench
4futex_bench 6futex_bench
5null_syscall 7null_syscall
diff --git a/tools/testing/selftests/powerpc/benchmarks/Makefile b/tools/testing/selftests/powerpc/benchmarks/Makefile
index a35058e3766c..b4d7432a0ecd 100644
--- a/tools/testing/selftests/powerpc/benchmarks/Makefile
+++ b/tools/testing/selftests/powerpc/benchmarks/Makefile
@@ -1,5 +1,6 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2TEST_GEN_PROGS := gettimeofday context_switch mmap_bench futex_bench null_syscall 2TEST_GEN_PROGS := gettimeofday context_switch fork mmap_bench futex_bench null_syscall
3TEST_GEN_FILES := exec_target
3 4
4CFLAGS += -O2 5CFLAGS += -O2
5 6
@@ -10,3 +11,7 @@ $(TEST_GEN_PROGS): ../harness.c
10$(OUTPUT)/context_switch: ../utils.c 11$(OUTPUT)/context_switch: ../utils.c
11$(OUTPUT)/context_switch: CFLAGS += -maltivec -mvsx -mabi=altivec 12$(OUTPUT)/context_switch: CFLAGS += -maltivec -mvsx -mabi=altivec
12$(OUTPUT)/context_switch: LDLIBS += -lpthread 13$(OUTPUT)/context_switch: LDLIBS += -lpthread
14
15$(OUTPUT)/fork: LDLIBS += -lpthread
16
17$(OUTPUT)/exec_target: CFLAGS += -static -nostartfiles
diff --git a/tools/testing/selftests/powerpc/benchmarks/exec_target.c b/tools/testing/selftests/powerpc/benchmarks/exec_target.c
new file mode 100644
index 000000000000..3c9c144192be
--- /dev/null
+++ b/tools/testing/selftests/powerpc/benchmarks/exec_target.c
@@ -0,0 +1,13 @@
1// SPDX-License-Identifier: GPL-2.0+
2
3/*
4 * Part of fork context switch microbenchmark.
5 *
6 * Copyright 2018, Anton Blanchard, IBM Corp.
7 */
8
9void _exit(int);
10void _start(void)
11{
12 _exit(0);
13}
diff --git a/tools/testing/selftests/powerpc/benchmarks/fork.c b/tools/testing/selftests/powerpc/benchmarks/fork.c
new file mode 100644
index 000000000000..d312e638cb37
--- /dev/null
+++ b/tools/testing/selftests/powerpc/benchmarks/fork.c
@@ -0,0 +1,325 @@
1// SPDX-License-Identifier: GPL-2.0+
2
3/*
4 * Context switch microbenchmark.
5 *
6 * Copyright 2018, Anton Blanchard, IBM Corp.
7 */
8
9#define _GNU_SOURCE
10#include <assert.h>
11#include <errno.h>
12#include <getopt.h>
13#include <limits.h>
14#include <linux/futex.h>
15#include <pthread.h>
16#include <sched.h>
17#include <signal.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include <sys/shm.h>
22#include <sys/syscall.h>
23#include <sys/time.h>
24#include <sys/types.h>
25#include <sys/wait.h>
26#include <unistd.h>
27
28static unsigned int timeout = 30;
29
30static void set_cpu(int cpu)
31{
32 cpu_set_t cpuset;
33
34 if (cpu == -1)
35 return;
36
37 CPU_ZERO(&cpuset);
38 CPU_SET(cpu, &cpuset);
39
40 if (sched_setaffinity(0, sizeof(cpuset), &cpuset)) {
41 perror("sched_setaffinity");
42 exit(1);
43 }
44}
45
46static void start_process_on(void *(*fn)(void *), void *arg, int cpu)
47{
48 int pid;
49
50 pid = fork();
51 if (pid == -1) {
52 perror("fork");
53 exit(1);
54 }
55
56 if (pid)
57 return;
58
59 set_cpu(cpu);
60
61 fn(arg);
62
63 exit(0);
64}
65
66static int cpu;
67static int do_fork = 0;
68static int do_vfork = 0;
69static int do_exec = 0;
70static char *exec_file;
71static int exec_target = 0;
72static unsigned long iterations;
73static unsigned long iterations_prev;
74
75static void run_exec(void)
76{
77 char *const argv[] = { "./exec_target", NULL };
78
79 if (execve("./exec_target", argv, NULL) == -1) {
80 perror("execve");
81 exit(1);
82 }
83}
84
85static void bench_fork(void)
86{
87 while (1) {
88 pid_t pid = fork();
89 if (pid == -1) {
90 perror("fork");
91 exit(1);
92 }
93 if (pid == 0) {
94 if (do_exec)
95 run_exec();
96 _exit(0);
97 }
98 pid = waitpid(pid, NULL, 0);
99 if (pid == -1) {
100 perror("waitpid");
101 exit(1);
102 }
103 iterations++;
104 }
105}
106
107static void bench_vfork(void)
108{
109 while (1) {
110 pid_t pid = vfork();
111 if (pid == -1) {
112 perror("fork");
113 exit(1);
114 }
115 if (pid == 0) {
116 if (do_exec)
117 run_exec();
118 _exit(0);
119 }
120 pid = waitpid(pid, NULL, 0);
121 if (pid == -1) {
122 perror("waitpid");
123 exit(1);
124 }
125 iterations++;
126 }
127}
128
129static void *null_fn(void *arg)
130{
131 pthread_exit(NULL);
132}
133
134static void bench_thread(void)
135{
136 pthread_t tid;
137 cpu_set_t cpuset;
138 pthread_attr_t attr;
139 int rc;
140
141 rc = pthread_attr_init(&attr);
142 if (rc) {
143 errno = rc;
144 perror("pthread_attr_init");
145 exit(1);
146 }
147
148 if (cpu != -1) {
149 CPU_ZERO(&cpuset);
150 CPU_SET(cpu, &cpuset);
151
152 rc = pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpuset);
153 if (rc) {
154 errno = rc;
155 perror("pthread_attr_setaffinity_np");
156 exit(1);
157 }
158 }
159
160 while (1) {
161 rc = pthread_create(&tid, &attr, null_fn, NULL);
162 if (rc) {
163 errno = rc;
164 perror("pthread_create");
165 exit(1);
166 }
167 rc = pthread_join(tid, NULL);
168 if (rc) {
169 errno = rc;
170 perror("pthread_join");
171 exit(1);
172 }
173 iterations++;
174 }
175}
176
177static void sigalrm_handler(int junk)
178{
179 unsigned long i = iterations;
180
181 printf("%ld\n", i - iterations_prev);
182 iterations_prev = i;
183
184 if (--timeout == 0)
185 kill(0, SIGUSR1);
186
187 alarm(1);
188}
189
190static void sigusr1_handler(int junk)
191{
192 exit(0);
193}
194
195static void *bench_proc(void *arg)
196{
197 signal(SIGALRM, sigalrm_handler);
198 alarm(1);
199
200 if (do_fork)
201 bench_fork();
202 else if (do_vfork)
203 bench_vfork();
204 else
205 bench_thread();
206
207 return NULL;
208}
209
210static struct option options[] = {
211 { "fork", no_argument, &do_fork, 1 },
212 { "vfork", no_argument, &do_vfork, 1 },
213 { "exec", no_argument, &do_exec, 1 },
214 { "timeout", required_argument, 0, 's' },
215 { "exec-target", no_argument, &exec_target, 1 },
216 { NULL },
217};
218
219static void usage(void)
220{
221 fprintf(stderr, "Usage: fork <options> CPU\n\n");
222 fprintf(stderr, "\t\t--fork\tUse fork() (default threads)\n");
223 fprintf(stderr, "\t\t--vfork\tUse vfork() (default threads)\n");
224 fprintf(stderr, "\t\t--exec\tAlso exec() (default no exec)\n");
225 fprintf(stderr, "\t\t--timeout=X\tDuration in seconds to run (default 30)\n");
226 fprintf(stderr, "\t\t--exec-target\tInternal option for exec workload\n");
227}
228
229int main(int argc, char *argv[])
230{
231 signed char c;
232
233 while (1) {
234 int option_index = 0;
235
236 c = getopt_long(argc, argv, "", options, &option_index);
237
238 if (c == -1)
239 break;
240
241 switch (c) {
242 case 0:
243 if (options[option_index].flag != 0)
244 break;
245
246 usage();
247 exit(1);
248 break;
249
250 case 's':
251 timeout = atoi(optarg);
252 break;
253
254 default:
255 usage();
256 exit(1);
257 }
258 }
259
260 if (do_fork && do_vfork) {
261 usage();
262 exit(1);
263 }
264 if (do_exec && !do_fork && !do_vfork) {
265 usage();
266 exit(1);
267 }
268
269 if (do_exec) {
270 char *dirname = strdup(argv[0]);
271 int i;
272 i = strlen(dirname) - 1;
273 while (i) {
274 if (dirname[i] == '/') {
275 dirname[i] = '\0';
276 if (chdir(dirname) == -1) {
277 perror("chdir");
278 exit(1);
279 }
280 break;
281 }
282 i--;
283 }
284 }
285
286 if (exec_target) {
287 exit(0);
288 }
289
290 if (((argc - optind) != 1)) {
291 cpu = -1;
292 } else {
293 cpu = atoi(argv[optind++]);
294 }
295
296 if (do_exec)
297 exec_file = argv[0];
298
299 set_cpu(cpu);
300
301 printf("Using ");
302 if (do_fork)
303 printf("fork");
304 else if (do_vfork)
305 printf("vfork");
306 else
307 printf("clone");
308
309 if (do_exec)
310 printf(" + exec");
311
312 printf(" on cpu %d\n", cpu);
313
314 /* Create a new process group so we can signal everyone for exit */
315 setpgid(getpid(), getpid());
316
317 signal(SIGUSR1, sigusr1_handler);
318
319 start_process_on(bench_proc, NULL, cpu);
320
321 while (1)
322 sleep(3600);
323
324 return 0;
325}
diff --git a/tools/testing/selftests/powerpc/copyloops/Makefile b/tools/testing/selftests/powerpc/copyloops/Makefile
index ac4a52e19e59..eedce3366f64 100644
--- a/tools/testing/selftests/powerpc/copyloops/Makefile
+++ b/tools/testing/selftests/powerpc/copyloops/Makefile
@@ -5,8 +5,8 @@ CFLAGS += -I$(CURDIR)
5CFLAGS += -D SELFTEST 5CFLAGS += -D SELFTEST
6CFLAGS += -maltivec 6CFLAGS += -maltivec
7 7
8# Use our CFLAGS for the implicit .S rule 8# Use our CFLAGS for the implicit .S rule & set the asm machine type
9ASFLAGS = $(CFLAGS) 9ASFLAGS = $(CFLAGS) -Wa,-mpower4
10 10
11TEST_GEN_PROGS := copyuser_64 copyuser_power7 memcpy_64 memcpy_power7 11TEST_GEN_PROGS := copyuser_64 copyuser_power7 memcpy_64 memcpy_power7
12EXTRA_SOURCES := validate.c ../harness.c 12EXTRA_SOURCES := validate.c ../harness.c
diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile
index 5c72ff978f27..c0e45d2dde25 100644
--- a/tools/testing/selftests/powerpc/tm/Makefile
+++ b/tools/testing/selftests/powerpc/tm/Makefile
@@ -4,7 +4,7 @@ SIGNAL_CONTEXT_CHK_TESTS := tm-signal-context-chk-gpr tm-signal-context-chk-fpu
4 4
5TEST_GEN_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack \ 5TEST_GEN_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack \
6 tm-vmxcopy tm-fork tm-tar tm-tmspr tm-vmx-unavail tm-unavailable tm-trap \ 6 tm-vmxcopy tm-fork tm-tar tm-tmspr tm-vmx-unavail tm-unavailable tm-trap \
7 $(SIGNAL_CONTEXT_CHK_TESTS) 7 $(SIGNAL_CONTEXT_CHK_TESTS) tm-sigreturn
8 8
9include ../../lib.mk 9include ../../lib.mk
10 10
diff --git a/tools/testing/selftests/powerpc/tm/tm-sigreturn.c b/tools/testing/selftests/powerpc/tm/tm-sigreturn.c
new file mode 100644
index 000000000000..85d63449243b
--- /dev/null
+++ b/tools/testing/selftests/powerpc/tm/tm-sigreturn.c
@@ -0,0 +1,92 @@
1// SPDX-License-Identifier: GPL-2.0
2
3/*
4 * Copyright 2015, Laurent Dufour, IBM Corp.
5 *
6 * Test the kernel's signal returning code to check reclaim is done if the
7 * sigreturn() is called while in a transaction (suspended since active is
8 * already dropped trough the system call path).
9 *
10 * The kernel must discard the transaction when entering sigreturn, since
11 * restoring the potential TM SPRS from the signal frame is requiring to not be
12 * in a transaction.
13 */
14
15#include <signal.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19#include <sys/types.h>
20#include <sys/wait.h>
21#include <unistd.h>
22
23#include "tm.h"
24#include "utils.h"
25
26
27void handler(int sig)
28{
29 uint64_t ret;
30
31 asm __volatile__(
32 "li 3,1 ;"
33 "tbegin. ;"
34 "beq 1f ;"
35 "li 3,0 ;"
36 "tsuspend. ;"
37 "1: ;"
38 "std%X[ret] 3, %[ret] ;"
39 : [ret] "=m"(ret)
40 :
41 : "memory", "3", "cr0");
42
43 if (ret)
44 exit(1);
45
46 /*
47 * We return from the signal handle while in a suspended transaction
48 */
49}
50
51
52int tm_sigreturn(void)
53{
54 struct sigaction sa;
55 uint64_t ret = 0;
56
57 SKIP_IF(!have_htm());
58
59 memset(&sa, 0, sizeof(sa));
60 sa.sa_handler = handler;
61 sigemptyset(&sa.sa_mask);
62
63 if (sigaction(SIGSEGV, &sa, NULL))
64 exit(1);
65
66 asm __volatile__(
67 "tbegin. ;"
68 "beq 1f ;"
69 "li 3,0 ;"
70 "std 3,0(3) ;" /* trigger SEGV */
71 "li 3,1 ;"
72 "std%X[ret] 3,%[ret] ;"
73 "tend. ;"
74 "b 2f ;"
75 "1: ;"
76 "li 3,2 ;"
77 "std%X[ret] 3,%[ret] ;"
78 "2: ;"
79 : [ret] "=m"(ret)
80 :
81 : "memory", "3", "cr0");
82
83 if (ret != 2)
84 exit(1);
85
86 exit(0);
87}
88
89int main(void)
90{
91 return test_harness(tm_sigreturn, "tm_sigreturn");
92}
diff --git a/tools/testing/selftests/powerpc/tm/tm-unavailable.c b/tools/testing/selftests/powerpc/tm/tm-unavailable.c
index e6a0fad2bfd0..156c8e750259 100644
--- a/tools/testing/selftests/powerpc/tm/tm-unavailable.c
+++ b/tools/testing/selftests/powerpc/tm/tm-unavailable.c
@@ -80,7 +80,7 @@ bool is_failure(uint64_t condition_reg)
80 return ((condition_reg >> 28) & 0xa) == 0xa; 80 return ((condition_reg >> 28) & 0xa) == 0xa;
81} 81}
82 82
83void *ping(void *input) 83void *tm_una_ping(void *input)
84{ 84{
85 85
86 /* 86 /*
@@ -280,7 +280,7 @@ void *ping(void *input)
280} 280}
281 281
282/* Thread to force context switch */ 282/* Thread to force context switch */
283void *pong(void *not_used) 283void *tm_una_pong(void *not_used)
284{ 284{
285 /* Wait thread get its name "pong". */ 285 /* Wait thread get its name "pong". */
286 if (DEBUG) 286 if (DEBUG)
@@ -311,11 +311,11 @@ void test_fp_vec(int fp, int vec, pthread_attr_t *attr)
311 do { 311 do {
312 int rc; 312 int rc;
313 313
314 /* Bind 'ping' to CPU 0, as specified in 'attr'. */ 314 /* Bind to CPU 0, as specified in 'attr'. */
315 rc = pthread_create(&t0, attr, ping, (void *) &flags); 315 rc = pthread_create(&t0, attr, tm_una_ping, (void *) &flags);
316 if (rc) 316 if (rc)
317 pr_err(rc, "pthread_create()"); 317 pr_err(rc, "pthread_create()");
318 rc = pthread_setname_np(t0, "ping"); 318 rc = pthread_setname_np(t0, "tm_una_ping");
319 if (rc) 319 if (rc)
320 pr_warn(rc, "pthread_setname_np"); 320 pr_warn(rc, "pthread_setname_np");
321 rc = pthread_join(t0, &ret_value); 321 rc = pthread_join(t0, &ret_value);
@@ -333,13 +333,15 @@ void test_fp_vec(int fp, int vec, pthread_attr_t *attr)
333 } 333 }
334} 334}
335 335
336int main(int argc, char **argv) 336int tm_unavailable_test(void)
337{ 337{
338 int rc, exception; /* FP = 0, VEC = 1, VSX = 2 */ 338 int rc, exception; /* FP = 0, VEC = 1, VSX = 2 */
339 pthread_t t1; 339 pthread_t t1;
340 pthread_attr_t attr; 340 pthread_attr_t attr;
341 cpu_set_t cpuset; 341 cpu_set_t cpuset;
342 342
343 SKIP_IF(!have_htm());
344
343 /* Set only CPU 0 in the mask. Both threads will be bound to CPU 0. */ 345 /* Set only CPU 0 in the mask. Both threads will be bound to CPU 0. */
344 CPU_ZERO(&cpuset); 346 CPU_ZERO(&cpuset);
345 CPU_SET(0, &cpuset); 347 CPU_SET(0, &cpuset);
@@ -354,12 +356,12 @@ int main(int argc, char **argv)
354 if (rc) 356 if (rc)
355 pr_err(rc, "pthread_attr_setaffinity_np()"); 357 pr_err(rc, "pthread_attr_setaffinity_np()");
356 358
357 rc = pthread_create(&t1, &attr /* Bind 'pong' to CPU 0 */, pong, NULL); 359 rc = pthread_create(&t1, &attr /* Bind to CPU 0 */, tm_una_pong, NULL);
358 if (rc) 360 if (rc)
359 pr_err(rc, "pthread_create()"); 361 pr_err(rc, "pthread_create()");
360 362
361 /* Name it for systemtap convenience */ 363 /* Name it for systemtap convenience */
362 rc = pthread_setname_np(t1, "pong"); 364 rc = pthread_setname_np(t1, "tm_una_pong");
363 if (rc) 365 if (rc)
364 pr_warn(rc, "pthread_create()"); 366 pr_warn(rc, "pthread_create()");
365 367
@@ -394,3 +396,9 @@ int main(int argc, char **argv)
394 exit(0); 396 exit(0);
395 } 397 }
396} 398}
399
400int main(int argc, char **argv)
401{
402 test_harness_set_timeout(220);
403 return test_harness(tm_unavailable_test, "tm_unavailable_test");
404}
diff --git a/tools/testing/selftests/proc/.gitignore b/tools/testing/selftests/proc/.gitignore
new file mode 100644
index 000000000000..6c16f77c722c
--- /dev/null
+++ b/tools/testing/selftests/proc/.gitignore
@@ -0,0 +1,8 @@
1/proc-loadavg-001
2/proc-self-map-files-001
3/proc-self-map-files-002
4/proc-self-syscall
5/proc-self-wchan
6/proc-uptime-001
7/proc-uptime-002
8/read
diff --git a/tools/testing/selftests/proc/Makefile b/tools/testing/selftests/proc/Makefile
new file mode 100644
index 000000000000..dbb87e56264c
--- /dev/null
+++ b/tools/testing/selftests/proc/Makefile
@@ -0,0 +1,13 @@
1CFLAGS += -Wall -O2
2
3TEST_GEN_PROGS :=
4TEST_GEN_PROGS += proc-loadavg-001
5TEST_GEN_PROGS += proc-self-map-files-001
6TEST_GEN_PROGS += proc-self-map-files-002
7TEST_GEN_PROGS += proc-self-syscall
8TEST_GEN_PROGS += proc-self-wchan
9TEST_GEN_PROGS += proc-uptime-001
10TEST_GEN_PROGS += proc-uptime-002
11TEST_GEN_PROGS += read
12
13include ../lib.mk
diff --git a/tools/testing/selftests/proc/config b/tools/testing/selftests/proc/config
new file mode 100644
index 000000000000..68fbd2b35884
--- /dev/null
+++ b/tools/testing/selftests/proc/config
@@ -0,0 +1 @@
CONFIG_PROC_FS=y
diff --git a/tools/testing/selftests/proc/proc-loadavg-001.c b/tools/testing/selftests/proc/proc-loadavg-001.c
new file mode 100644
index 000000000000..fcff7047000d
--- /dev/null
+++ b/tools/testing/selftests/proc/proc-loadavg-001.c
@@ -0,0 +1,83 @@
1/*
2 * Copyright © 2018 Alexey Dobriyan <adobriyan@gmail.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16/* Test that /proc/loadavg correctly reports last pid in pid namespace. */
17#define _GNU_SOURCE
18#include <errno.h>
19#include <sched.h>
20#include <sys/types.h>
21#include <sys/stat.h>
22#include <fcntl.h>
23#include <unistd.h>
24#include <sys/wait.h>
25
26int main(void)
27{
28 pid_t pid;
29 int wstatus;
30
31 if (unshare(CLONE_NEWPID) == -1) {
32 if (errno == ENOSYS || errno == EPERM)
33 return 2;
34 return 1;
35 }
36
37 pid = fork();
38 if (pid == -1)
39 return 1;
40 if (pid == 0) {
41 char buf[128], *p;
42 int fd;
43 ssize_t rv;
44
45 fd = open("/proc/loadavg" , O_RDONLY);
46 if (fd == -1)
47 return 1;
48 rv = read(fd, buf, sizeof(buf));
49 if (rv < 3)
50 return 1;
51 p = buf + rv;
52
53 /* pid 1 */
54 if (!(p[-3] == ' ' && p[-2] == '1' && p[-1] == '\n'))
55 return 1;
56
57 pid = fork();
58 if (pid == -1)
59 return 1;
60 if (pid == 0)
61 return 0;
62 if (waitpid(pid, NULL, 0) == -1)
63 return 1;
64
65 lseek(fd, 0, SEEK_SET);
66 rv = read(fd, buf, sizeof(buf));
67 if (rv < 3)
68 return 1;
69 p = buf + rv;
70
71 /* pid 2 */
72 if (!(p[-3] == ' ' && p[-2] == '2' && p[-1] == '\n'))
73 return 1;
74
75 return 0;
76 }
77
78 if (waitpid(pid, &wstatus, 0) == -1)
79 return 1;
80 if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == 0)
81 return 0;
82 return 1;
83}
diff --git a/tools/testing/selftests/proc/proc-self-map-files-001.c b/tools/testing/selftests/proc/proc-self-map-files-001.c
new file mode 100644
index 000000000000..4209c64283d6
--- /dev/null
+++ b/tools/testing/selftests/proc/proc-self-map-files-001.c
@@ -0,0 +1,82 @@
1/*
2 * Copyright © 2018 Alexey Dobriyan <adobriyan@gmail.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16/* Test readlink /proc/self/map_files/... */
17#include <errno.h>
18#include <sys/types.h>
19#include <sys/stat.h>
20#include <fcntl.h>
21#include <stdio.h>
22#include <unistd.h>
23#include <sys/mman.h>
24#include <stdlib.h>
25
26static void pass(const char *fmt, unsigned long a, unsigned long b)
27{
28 char name[64];
29 char buf[64];
30
31 snprintf(name, sizeof(name), fmt, a, b);
32 if (readlink(name, buf, sizeof(buf)) == -1)
33 exit(1);
34}
35
36static void fail(const char *fmt, unsigned long a, unsigned long b)
37{
38 char name[64];
39 char buf[64];
40
41 snprintf(name, sizeof(name), fmt, a, b);
42 if (readlink(name, buf, sizeof(buf)) == -1 && errno == ENOENT)
43 return;
44 exit(1);
45}
46
47int main(void)
48{
49 const unsigned int PAGE_SIZE = sysconf(_SC_PAGESIZE);
50 void *p;
51 int fd;
52 unsigned long a, b;
53
54 fd = open("/dev/zero", O_RDONLY);
55 if (fd == -1)
56 return 1;
57
58 p = mmap(NULL, PAGE_SIZE, PROT_NONE, MAP_PRIVATE|MAP_FILE, fd, 0);
59 if (p == MAP_FAILED)
60 return 1;
61
62 a = (unsigned long)p;
63 b = (unsigned long)p + PAGE_SIZE;
64
65 pass("/proc/self/map_files/%lx-%lx", a, b);
66 fail("/proc/self/map_files/ %lx-%lx", a, b);
67 fail("/proc/self/map_files/%lx -%lx", a, b);
68 fail("/proc/self/map_files/%lx- %lx", a, b);
69 fail("/proc/self/map_files/%lx-%lx ", a, b);
70 fail("/proc/self/map_files/0%lx-%lx", a, b);
71 fail("/proc/self/map_files/%lx-0%lx", a, b);
72 if (sizeof(long) == 4) {
73 fail("/proc/self/map_files/100000000%lx-%lx", a, b);
74 fail("/proc/self/map_files/%lx-100000000%lx", a, b);
75 } else if (sizeof(long) == 8) {
76 fail("/proc/self/map_files/10000000000000000%lx-%lx", a, b);
77 fail("/proc/self/map_files/%lx-10000000000000000%lx", a, b);
78 } else
79 return 1;
80
81 return 0;
82}
diff --git a/tools/testing/selftests/proc/proc-self-map-files-002.c b/tools/testing/selftests/proc/proc-self-map-files-002.c
new file mode 100644
index 000000000000..6f1f4a6e1ecb
--- /dev/null
+++ b/tools/testing/selftests/proc/proc-self-map-files-002.c
@@ -0,0 +1,85 @@
1/*
2 * Copyright © 2018 Alexey Dobriyan <adobriyan@gmail.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16/* Test readlink /proc/self/map_files/... with address 0. */
17#include <errno.h>
18#include <sys/types.h>
19#include <sys/stat.h>
20#include <fcntl.h>
21#include <stdio.h>
22#include <unistd.h>
23#include <sys/mman.h>
24#include <stdlib.h>
25
26static void pass(const char *fmt, unsigned long a, unsigned long b)
27{
28 char name[64];
29 char buf[64];
30
31 snprintf(name, sizeof(name), fmt, a, b);
32 if (readlink(name, buf, sizeof(buf)) == -1)
33 exit(1);
34}
35
36static void fail(const char *fmt, unsigned long a, unsigned long b)
37{
38 char name[64];
39 char buf[64];
40
41 snprintf(name, sizeof(name), fmt, a, b);
42 if (readlink(name, buf, sizeof(buf)) == -1 && errno == ENOENT)
43 return;
44 exit(1);
45}
46
47int main(void)
48{
49 const unsigned int PAGE_SIZE = sysconf(_SC_PAGESIZE);
50 void *p;
51 int fd;
52 unsigned long a, b;
53
54 fd = open("/dev/zero", O_RDONLY);
55 if (fd == -1)
56 return 1;
57
58 p = mmap(NULL, PAGE_SIZE, PROT_NONE, MAP_PRIVATE|MAP_FILE|MAP_FIXED, fd, 0);
59 if (p == MAP_FAILED) {
60 if (errno == EPERM)
61 return 2;
62 return 1;
63 }
64
65 a = (unsigned long)p;
66 b = (unsigned long)p + PAGE_SIZE;
67
68 pass("/proc/self/map_files/%lx-%lx", a, b);
69 fail("/proc/self/map_files/ %lx-%lx", a, b);
70 fail("/proc/self/map_files/%lx -%lx", a, b);
71 fail("/proc/self/map_files/%lx- %lx", a, b);
72 fail("/proc/self/map_files/%lx-%lx ", a, b);
73 fail("/proc/self/map_files/0%lx-%lx", a, b);
74 fail("/proc/self/map_files/%lx-0%lx", a, b);
75 if (sizeof(long) == 4) {
76 fail("/proc/self/map_files/100000000%lx-%lx", a, b);
77 fail("/proc/self/map_files/%lx-100000000%lx", a, b);
78 } else if (sizeof(long) == 8) {
79 fail("/proc/self/map_files/10000000000000000%lx-%lx", a, b);
80 fail("/proc/self/map_files/%lx-10000000000000000%lx", a, b);
81 } else
82 return 1;
83
84 return 0;
85}
diff --git a/tools/testing/selftests/proc/proc-self-syscall.c b/tools/testing/selftests/proc/proc-self-syscall.c
new file mode 100644
index 000000000000..5ab5f4810e43
--- /dev/null
+++ b/tools/testing/selftests/proc/proc-self-syscall.c
@@ -0,0 +1,60 @@
1/*
2 * Copyright © 2018 Alexey Dobriyan <adobriyan@gmail.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#define _GNU_SOURCE
17#include <unistd.h>
18#include <sys/syscall.h>
19#include <sys/types.h>
20#include <sys/stat.h>
21#include <fcntl.h>
22#include <errno.h>
23#include <unistd.h>
24#include <string.h>
25#include <stdio.h>
26
27static inline ssize_t sys_read(int fd, void *buf, size_t len)
28{
29 return syscall(SYS_read, fd, buf, len);
30}
31
32int main(void)
33{
34 char buf1[64];
35 char buf2[64];
36 int fd;
37 ssize_t rv;
38
39 fd = open("/proc/self/syscall", O_RDONLY);
40 if (fd == -1) {
41 if (errno == ENOENT)
42 return 2;
43 return 1;
44 }
45
46 /* Do direct system call as libc can wrap anything. */
47 snprintf(buf1, sizeof(buf1), "%ld 0x%lx 0x%lx 0x%lx",
48 (long)SYS_read, (long)fd, (long)buf2, (long)sizeof(buf2));
49
50 memset(buf2, 0, sizeof(buf2));
51 rv = sys_read(fd, buf2, sizeof(buf2));
52 if (rv < 0)
53 return 1;
54 if (rv < strlen(buf1))
55 return 1;
56 if (strncmp(buf1, buf2, strlen(buf1)) != 0)
57 return 1;
58
59 return 0;
60}
diff --git a/tools/testing/selftests/proc/proc-self-wchan.c b/tools/testing/selftests/proc/proc-self-wchan.c
new file mode 100644
index 000000000000..a38b2fbaa7ad
--- /dev/null
+++ b/tools/testing/selftests/proc/proc-self-wchan.c
@@ -0,0 +1,40 @@
1/*
2 * Copyright © 2018 Alexey Dobriyan <adobriyan@gmail.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#include <sys/types.h>
17#include <sys/stat.h>
18#include <fcntl.h>
19#include <errno.h>
20#include <unistd.h>
21
22int main(void)
23{
24 char buf[64];
25 int fd;
26
27 fd = open("/proc/self/wchan", O_RDONLY);
28 if (fd == -1) {
29 if (errno == ENOENT)
30 return 2;
31 return 1;
32 }
33
34 buf[0] = '\0';
35 if (read(fd, buf, sizeof(buf)) != 1)
36 return 1;
37 if (buf[0] != '0')
38 return 1;
39 return 0;
40}
diff --git a/tools/testing/selftests/proc/proc-uptime-001.c b/tools/testing/selftests/proc/proc-uptime-001.c
new file mode 100644
index 000000000000..781f7a50fc3f
--- /dev/null
+++ b/tools/testing/selftests/proc/proc-uptime-001.c
@@ -0,0 +1,45 @@
1/*
2 * Copyright © 2018 Alexey Dobriyan <adobriyan@gmail.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16// Test that values in /proc/uptime increment monotonically.
17#undef NDEBUG
18#include <assert.h>
19#include <stdint.h>
20#include <sys/types.h>
21#include <sys/stat.h>
22#include <fcntl.h>
23
24#include "proc-uptime.h"
25
26int main(void)
27{
28 uint64_t start, u0, u1, i0, i1;
29 int fd;
30
31 fd = open("/proc/uptime", O_RDONLY);
32 assert(fd >= 0);
33
34 proc_uptime(fd, &u0, &i0);
35 start = u0;
36 do {
37 proc_uptime(fd, &u1, &i1);
38 assert(u1 >= u0);
39 assert(i1 >= i0);
40 u0 = u1;
41 i0 = i1;
42 } while (u1 - start < 100);
43
44 return 0;
45}
diff --git a/tools/testing/selftests/proc/proc-uptime-002.c b/tools/testing/selftests/proc/proc-uptime-002.c
new file mode 100644
index 000000000000..30e2b7849089
--- /dev/null
+++ b/tools/testing/selftests/proc/proc-uptime-002.c
@@ -0,0 +1,79 @@
1/*
2 * Copyright © 2018 Alexey Dobriyan <adobriyan@gmail.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16// Test that values in /proc/uptime increment monotonically
17// while shifting across CPUs.
18#define _GNU_SOURCE
19#undef NDEBUG
20#include <assert.h>
21#include <unistd.h>
22#include <sys/syscall.h>
23#include <stdlib.h>
24#include <string.h>
25
26#include <stdint.h>
27#include <sys/types.h>
28#include <sys/stat.h>
29#include <fcntl.h>
30
31#include "proc-uptime.h"
32
33static inline int sys_sched_getaffinity(pid_t pid, unsigned int len, unsigned long *m)
34{
35 return syscall(SYS_sched_getaffinity, pid, len, m);
36}
37
38static inline int sys_sched_setaffinity(pid_t pid, unsigned int len, unsigned long *m)
39{
40 return syscall(SYS_sched_setaffinity, pid, len, m);
41}
42
43int main(void)
44{
45 unsigned int len;
46 unsigned long *m;
47 unsigned int cpu;
48 uint64_t u0, u1, i0, i1;
49 int fd;
50
51 /* find out "nr_cpu_ids" */
52 m = NULL;
53 len = 0;
54 do {
55 len += sizeof(unsigned long);
56 free(m);
57 m = malloc(len);
58 } while (sys_sched_getaffinity(0, len, m) == -EINVAL);
59
60 fd = open("/proc/uptime", O_RDONLY);
61 assert(fd >= 0);
62
63 proc_uptime(fd, &u0, &i0);
64 for (cpu = 0; cpu < len * 8; cpu++) {
65 memset(m, 0, len);
66 m[cpu / (8 * sizeof(unsigned long))] |= 1UL << (cpu % (8 * sizeof(unsigned long)));
67
68 /* CPU might not exist, ignore error */
69 sys_sched_setaffinity(0, len, m);
70
71 proc_uptime(fd, &u1, &i1);
72 assert(u1 >= u0);
73 assert(i1 >= i0);
74 u0 = u1;
75 i0 = i1;
76 }
77
78 return 0;
79}
diff --git a/tools/testing/selftests/proc/proc-uptime.h b/tools/testing/selftests/proc/proc-uptime.h
new file mode 100644
index 000000000000..0e464b50e9d9
--- /dev/null
+++ b/tools/testing/selftests/proc/proc-uptime.h
@@ -0,0 +1,74 @@
1/*
2 * Copyright © 2018 Alexey Dobriyan <adobriyan@gmail.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#undef NDEBUG
17#include <assert.h>
18#include <errno.h>
19#include <string.h>
20#include <stdlib.h>
21#include <unistd.h>
22
23static unsigned long long xstrtoull(const char *p, char **end)
24{
25 if (*p == '0') {
26 *end = (char *)p + 1;
27 return 0;
28 } else if ('1' <= *p && *p <= '9') {
29 unsigned long long val;
30
31 errno = 0;
32 val = strtoull(p, end, 10);
33 assert(errno == 0);
34 return val;
35 } else
36 assert(0);
37}
38
39static void proc_uptime(int fd, uint64_t *uptime, uint64_t *idle)
40{
41 uint64_t val1, val2;
42 char buf[64], *p;
43 ssize_t rv;
44
45 /* save "p < end" checks */
46 memset(buf, 0, sizeof(buf));
47 rv = pread(fd, buf, sizeof(buf), 0);
48 assert(0 <= rv && rv <= sizeof(buf));
49 buf[sizeof(buf) - 1] = '\0';
50
51 p = buf;
52
53 val1 = xstrtoull(p, &p);
54 assert(p[0] == '.');
55 assert('0' <= p[1] && p[1] <= '9');
56 assert('0' <= p[2] && p[2] <= '9');
57 assert(p[3] == ' ');
58
59 val2 = (p[1] - '0') * 10 + p[2] - '0';
60 *uptime = val1 * 100 + val2;
61
62 p += 4;
63
64 val1 = xstrtoull(p, &p);
65 assert(p[0] == '.');
66 assert('0' <= p[1] && p[1] <= '9');
67 assert('0' <= p[2] && p[2] <= '9');
68 assert(p[3] == '\n');
69
70 val2 = (p[1] - '0') * 10 + p[2] - '0';
71 *idle = val1 * 100 + val2;
72
73 assert(p + 4 == buf + rv);
74}
diff --git a/tools/testing/selftests/proc/read.c b/tools/testing/selftests/proc/read.c
new file mode 100644
index 000000000000..1e73c2232097
--- /dev/null
+++ b/tools/testing/selftests/proc/read.c
@@ -0,0 +1,147 @@
1/*
2 * Copyright © 2018 Alexey Dobriyan <adobriyan@gmail.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16// Test
17// 1) read of every file in /proc
18// 2) readlink of every symlink in /proc
19// 3) recursively (1) + (2) for every directory in /proc
20// 4) write to /proc/*/clear_refs and /proc/*/task/*/clear_refs
21// 5) write to /proc/sysrq-trigger
22#undef NDEBUG
23#include <assert.h>
24#include <errno.h>
25#include <sys/types.h>
26#include <dirent.h>
27#include <stdbool.h>
28#include <stdlib.h>
29#include <string.h>
30#include <sys/stat.h>
31#include <fcntl.h>
32#include <unistd.h>
33
34static inline bool streq(const char *s1, const char *s2)
35{
36 return strcmp(s1, s2) == 0;
37}
38
39static struct dirent *xreaddir(DIR *d)
40{
41 struct dirent *de;
42
43 errno = 0;
44 de = readdir(d);
45 if (!de && errno != 0) {
46 exit(1);
47 }
48 return de;
49}
50
51static void f_reg(DIR *d, const char *filename)
52{
53 char buf[4096];
54 int fd;
55 ssize_t rv;
56
57 /* read from /proc/kmsg can block */
58 fd = openat(dirfd(d), filename, O_RDONLY|O_NONBLOCK);
59 if (fd == -1)
60 return;
61 rv = read(fd, buf, sizeof(buf));
62 assert((0 <= rv && rv <= sizeof(buf)) || rv == -1);
63 close(fd);
64}
65
66static void f_reg_write(DIR *d, const char *filename, const char *buf, size_t len)
67{
68 int fd;
69 ssize_t rv;
70
71 fd = openat(dirfd(d), filename, O_WRONLY);
72 if (fd == -1)
73 return;
74 rv = write(fd, buf, len);
75 assert((0 <= rv && rv <= len) || rv == -1);
76 close(fd);
77}
78
79static void f_lnk(DIR *d, const char *filename)
80{
81 char buf[4096];
82 ssize_t rv;
83
84 rv = readlinkat(dirfd(d), filename, buf, sizeof(buf));
85 assert((0 <= rv && rv <= sizeof(buf)) || rv == -1);
86}
87
88static void f(DIR *d, unsigned int level)
89{
90 struct dirent *de;
91
92 de = xreaddir(d);
93 assert(de->d_type == DT_DIR);
94 assert(streq(de->d_name, "."));
95
96 de = xreaddir(d);
97 assert(de->d_type == DT_DIR);
98 assert(streq(de->d_name, ".."));
99
100 while ((de = xreaddir(d))) {
101 assert(!streq(de->d_name, "."));
102 assert(!streq(de->d_name, ".."));
103
104 switch (de->d_type) {
105 DIR *dd;
106 int fd;
107
108 case DT_REG:
109 if (level == 0 && streq(de->d_name, "sysrq-trigger")) {
110 f_reg_write(d, de->d_name, "h", 1);
111 } else if (level == 1 && streq(de->d_name, "clear_refs")) {
112 f_reg_write(d, de->d_name, "1", 1);
113 } else if (level == 3 && streq(de->d_name, "clear_refs")) {
114 f_reg_write(d, de->d_name, "1", 1);
115 } else {
116 f_reg(d, de->d_name);
117 }
118 break;
119 case DT_DIR:
120 fd = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY);
121 if (fd == -1)
122 continue;
123 dd = fdopendir(fd);
124 if (!dd)
125 continue;
126 f(dd, level + 1);
127 closedir(dd);
128 break;
129 case DT_LNK:
130 f_lnk(d, de->d_name);
131 break;
132 default:
133 assert(0);
134 }
135 }
136}
137
138int main(void)
139{
140 DIR *d;
141
142 d = opendir("/proc");
143 if (!d)
144 return 2;
145 f(d, 0);
146 return 0;
147}
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index 5df609950a66..168c66d74fc5 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -2860,6 +2860,7 @@ TEST(get_metadata)
2860 int pipefd[2]; 2860 int pipefd[2];
2861 char buf; 2861 char buf;
2862 struct seccomp_metadata md; 2862 struct seccomp_metadata md;
2863 long ret;
2863 2864
2864 ASSERT_EQ(0, pipe(pipefd)); 2865 ASSERT_EQ(0, pipe(pipefd));
2865 2866
@@ -2893,16 +2894,26 @@ TEST(get_metadata)
2893 ASSERT_EQ(0, ptrace(PTRACE_ATTACH, pid)); 2894 ASSERT_EQ(0, ptrace(PTRACE_ATTACH, pid));
2894 ASSERT_EQ(pid, waitpid(pid, NULL, 0)); 2895 ASSERT_EQ(pid, waitpid(pid, NULL, 0));
2895 2896
2897 /* Past here must not use ASSERT or child process is never killed. */
2898
2896 md.filter_off = 0; 2899 md.filter_off = 0;
2897 ASSERT_EQ(sizeof(md), ptrace(PTRACE_SECCOMP_GET_METADATA, pid, sizeof(md), &md)); 2900 errno = 0;
2901 ret = ptrace(PTRACE_SECCOMP_GET_METADATA, pid, sizeof(md), &md);
2902 EXPECT_EQ(sizeof(md), ret) {
2903 if (errno == EINVAL)
2904 XFAIL(goto skip, "Kernel does not support PTRACE_SECCOMP_GET_METADATA (missing CONFIG_CHECKPOINT_RESTORE?)");
2905 }
2906
2898 EXPECT_EQ(md.flags, SECCOMP_FILTER_FLAG_LOG); 2907 EXPECT_EQ(md.flags, SECCOMP_FILTER_FLAG_LOG);
2899 EXPECT_EQ(md.filter_off, 0); 2908 EXPECT_EQ(md.filter_off, 0);
2900 2909
2901 md.filter_off = 1; 2910 md.filter_off = 1;
2902 ASSERT_EQ(sizeof(md), ptrace(PTRACE_SECCOMP_GET_METADATA, pid, sizeof(md), &md)); 2911 ret = ptrace(PTRACE_SECCOMP_GET_METADATA, pid, sizeof(md), &md);
2912 EXPECT_EQ(sizeof(md), ret);
2903 EXPECT_EQ(md.flags, 0); 2913 EXPECT_EQ(md.flags, 0);
2904 EXPECT_EQ(md.filter_off, 1); 2914 EXPECT_EQ(md.filter_off, 1);
2905 2915
2916skip:
2906 ASSERT_EQ(0, kill(pid, SIGKILL)); 2917 ASSERT_EQ(0, kill(pid, SIGKILL));
2907} 2918}
2908 2919
diff --git a/tools/thermal/tmon/sysfs.c b/tools/thermal/tmon/sysfs.c
index 1c12536f2081..18f523557983 100644
--- a/tools/thermal/tmon/sysfs.c
+++ b/tools/thermal/tmon/sysfs.c
@@ -486,6 +486,7 @@ int zone_instance_to_index(int zone_inst)
486int update_thermal_data() 486int update_thermal_data()
487{ 487{
488 int i; 488 int i;
489 int next_thermal_record = cur_thermal_record + 1;
489 char tz_name[256]; 490 char tz_name[256];
490 static unsigned long samples; 491 static unsigned long samples;
491 492
@@ -495,9 +496,9 @@ int update_thermal_data()
495 } 496 }
496 497
497 /* circular buffer for keeping historic data */ 498 /* circular buffer for keeping historic data */
498 if (cur_thermal_record >= NR_THERMAL_RECORDS) 499 if (next_thermal_record >= NR_THERMAL_RECORDS)
499 cur_thermal_record = 0; 500 next_thermal_record = 0;
500 gettimeofday(&trec[cur_thermal_record].tv, NULL); 501 gettimeofday(&trec[next_thermal_record].tv, NULL);
501 if (tmon_log) { 502 if (tmon_log) {
502 fprintf(tmon_log, "%lu ", ++samples); 503 fprintf(tmon_log, "%lu ", ++samples);
503 fprintf(tmon_log, "%3.1f ", p_param.t_target); 504 fprintf(tmon_log, "%3.1f ", p_param.t_target);
@@ -507,11 +508,12 @@ int update_thermal_data()
507 snprintf(tz_name, 256, "%s/%s%d", THERMAL_SYSFS, TZONE, 508 snprintf(tz_name, 256, "%s/%s%d", THERMAL_SYSFS, TZONE,
508 ptdata.tzi[i].instance); 509 ptdata.tzi[i].instance);
509 sysfs_get_ulong(tz_name, "temp", 510 sysfs_get_ulong(tz_name, "temp",
510 &trec[cur_thermal_record].temp[i]); 511 &trec[next_thermal_record].temp[i]);
511 if (tmon_log) 512 if (tmon_log)
512 fprintf(tmon_log, "%lu ", 513 fprintf(tmon_log, "%lu ",
513 trec[cur_thermal_record].temp[i]/1000); 514 trec[next_thermal_record].temp[i] / 1000);
514 } 515 }
516 cur_thermal_record = next_thermal_record;
515 for (i = 0; i < ptdata.nr_cooling_dev; i++) { 517 for (i = 0; i < ptdata.nr_cooling_dev; i++) {
516 char cdev_name[256]; 518 char cdev_name[256];
517 unsigned long val; 519 unsigned long val;
diff --git a/tools/thermal/tmon/tmon.c b/tools/thermal/tmon/tmon.c
index 9aa19652e8e8..b43138f8b862 100644
--- a/tools/thermal/tmon/tmon.c
+++ b/tools/thermal/tmon/tmon.c
@@ -336,7 +336,6 @@ int main(int argc, char **argv)
336 show_data_w(); 336 show_data_w();
337 show_cooling_device(); 337 show_cooling_device();
338 } 338 }
339 cur_thermal_record++;
340 time_elapsed += ticktime; 339 time_elapsed += ticktime;
341 controller_handler(trec[0].temp[target_tz_index] / 1000, 340 controller_handler(trec[0].temp[target_tz_index] / 1000,
342 &yk); 341 &yk);
diff --git a/tools/virtio/ringtest/ptr_ring.c b/tools/virtio/ringtest/ptr_ring.c
index 477899c12c51..2d566fbd236b 100644
--- a/tools/virtio/ringtest/ptr_ring.c
+++ b/tools/virtio/ringtest/ptr_ring.c
@@ -17,6 +17,8 @@
17#define likely(x) (__builtin_expect(!!(x), 1)) 17#define likely(x) (__builtin_expect(!!(x), 1))
18#define ALIGN(x, a) (((x) + (a) - 1) / (a) * (a)) 18#define ALIGN(x, a) (((x) + (a) - 1) / (a) * (a))
19#define SIZE_MAX (~(size_t)0) 19#define SIZE_MAX (~(size_t)0)
20#define KMALLOC_MAX_SIZE SIZE_MAX
21#define BUG_ON(x) assert(x)
20 22
21typedef pthread_spinlock_t spinlock_t; 23typedef pthread_spinlock_t spinlock_t;
22 24
@@ -57,6 +59,9 @@ static void kfree(void *p)
57 free(p); 59 free(p);
58} 60}
59 61
62#define kvmalloc_array kmalloc_array
63#define kvfree kfree
64
60static void spin_lock_init(spinlock_t *lock) 65static void spin_lock_init(spinlock_t *lock)
61{ 66{
62 int r = pthread_spin_init(lock, 0); 67 int r = pthread_spin_init(lock, 0);