aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile7
-rw-r--r--tools/gpio/Build3
-rw-r--r--tools/gpio/Makefile75
-rw-r--r--tools/gpio/gpio-event-mon.c192
-rw-r--r--tools/gpio/gpio-hammer.c189
-rwxr-xr-xtools/hv/bondvf.sh193
-rw-r--r--tools/lib/api/Build5
-rw-r--r--tools/lib/bpf/libbpf.c7
-rw-r--r--tools/objtool/.gitignore1
-rw-r--r--tools/objtool/Makefile2
-rw-r--r--tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk11
-rw-r--r--tools/objtool/arch/x86/insn/inat.h17
-rw-r--r--tools/objtool/arch/x86/insn/insn.c18
-rw-r--r--tools/objtool/arch/x86/insn/insn.h12
-rw-r--r--tools/objtool/arch/x86/insn/x86-opcode-map.txt265
-rw-r--r--tools/objtool/builtin-check.c140
-rw-r--r--tools/perf/arch/s390/util/Build2
-rw-r--r--tools/perf/arch/s390/util/machine.c19
-rw-r--r--tools/perf/arch/x86/tests/insn-x86-dat-32.c2
-rw-r--r--tools/perf/arch/x86/tests/insn-x86-dat-64.c2
-rw-r--r--tools/perf/arch/x86/tests/insn-x86-dat-src.c4
-rw-r--r--tools/perf/builtin-kmem.c1
-rw-r--r--tools/perf/scripts/python/netdev-times.py11
-rw-r--r--tools/perf/util/Build5
-rw-r--r--tools/perf/util/intel-pt-decoder/x86-opcode-map.txt2
-rw-r--r--tools/perf/util/machine.c8
-rw-r--r--tools/perf/util/machine.h1
-rw-r--r--tools/perf/util/python-ext-sources1
-rw-r--r--tools/testing/nvdimm/Kbuild10
-rw-r--r--tools/testing/nvdimm/config_check.c1
-rw-r--r--tools/testing/nvdimm/pmem-dax.c54
-rw-r--r--tools/testing/nvdimm/test/Kbuild2
-rw-r--r--tools/testing/nvdimm/test/iomap.c38
-rw-r--r--tools/testing/nvdimm/test/nfit.c199
-rw-r--r--tools/testing/nvdimm/test/nfit_test.h2
-rw-r--r--tools/testing/radix-tree/linux/gfp.h2
-rw-r--r--tools/testing/selftests/exec/Makefile3
-rwxr-xr-x[-rw-r--r--]tools/testing/selftests/lib/printf.sh0
-rw-r--r--tools/testing/selftests/media_tests/.gitignore2
-rw-r--r--tools/testing/selftests/media_tests/Makefile4
-rwxr-xr-xtools/testing/selftests/media_tests/bind_unbind_sample.sh12
-rw-r--r--tools/testing/selftests/media_tests/media_device_open.c81
-rw-r--r--tools/testing/selftests/media_tests/media_device_test.c19
-rwxr-xr-xtools/testing/selftests/media_tests/open_loop_test.sh10
-rw-r--r--tools/testing/selftests/media_tests/regression_test.txt43
-rw-r--r--tools/testing/selftests/media_tests/video_device_test.c100
-rw-r--r--tools/testing/selftests/powerpc/Makefile3
-rw-r--r--tools/testing/selftests/powerpc/alignment/.gitignore5
-rw-r--r--tools/testing/selftests/powerpc/alignment/Makefile10
-rw-r--r--tools/testing/selftests/powerpc/alignment/copy_first_unaligned.c41
-rw-r--r--tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.c53
-rw-r--r--tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.h26
-rw-r--r--tools/testing/selftests/powerpc/alignment/copy_unaligned.c41
-rw-r--r--tools/testing/selftests/powerpc/alignment/paste_last_unaligned.c43
-rw-r--r--tools/testing/selftests/powerpc/alignment/paste_unaligned.c43
-rw-r--r--tools/testing/selftests/powerpc/benchmarks/.gitignore2
-rw-r--r--tools/testing/selftests/powerpc/benchmarks/Makefile3
-rw-r--r--tools/testing/selftests/powerpc/benchmarks/context_switch.c17
-rw-r--r--tools/testing/selftests/powerpc/benchmarks/futex_bench.c42
-rw-r--r--tools/testing/selftests/powerpc/benchmarks/mmap_bench.c41
-rw-r--r--tools/testing/selftests/powerpc/instructions.h68
-rw-r--r--tools/testing/selftests/powerpc/mm/.gitignore1
-rw-r--r--tools/testing/selftests/powerpc/mm/Makefile4
-rw-r--r--tools/testing/selftests/powerpc/mm/prot_sao.c42
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/.gitignore2
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/Makefile2
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.c143
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.h39
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr_regs.c37
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/instruction_count_test.c2
-rw-r--r--tools/testing/selftests/powerpc/pmu/lib.c6
-rw-r--r--tools/testing/selftests/powerpc/reg.h5
-rw-r--r--tools/testing/selftests/powerpc/tm/.gitignore1
-rw-r--r--tools/testing/selftests/powerpc/tm/Makefile7
-rw-r--r--tools/testing/selftests/powerpc/tm/tm-exec.c70
-rw-r--r--tools/testing/selftests/powerpc/tm/tm-syscall.c15
-rw-r--r--tools/testing/selftests/powerpc/tm/tm.h23
-rw-r--r--tools/testing/selftests/powerpc/utils.h5
-rw-r--r--tools/testing/selftests/seccomp/seccomp_bpf.c176
-rw-r--r--tools/testing/selftests/timers/Makefile3
-rw-r--r--tools/testing/selftests/timers/rtctest.c13
-rw-r--r--tools/testing/selftests/timers/set-tz.c119
-rw-r--r--tools/testing/selftests/vm/compaction_test.c8
-rw-r--r--tools/testing/selftests/vm/on-fault-limit.c2
-rw-r--r--tools/virtio/ringtest/Makefile5
-rw-r--r--tools/virtio/ringtest/ptr_ring.c197
-rw-r--r--tools/vm/page_owner_sort.c9
87 files changed, 2764 insertions, 387 deletions
diff --git a/tools/Makefile b/tools/Makefile
index f10b64d8c674..daa8fb3e4363 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -85,7 +85,7 @@ tmon: FORCE
85freefall: FORCE 85freefall: FORCE
86 $(call descend,laptop/$@) 86 $(call descend,laptop/$@)
87 87
88all: acpi cgroup cpupower hv firewire lguest \ 88all: acpi cgroup cpupower gpio hv firewire lguest \
89 perf selftests turbostat usb \ 89 perf selftests turbostat usb \
90 virtio vm net x86_energy_perf_policy \ 90 virtio vm net x86_energy_perf_policy \
91 tmon freefall objtool 91 tmon freefall objtool
@@ -96,7 +96,7 @@ acpi_install:
96cpupower_install: 96cpupower_install:
97 $(call descend,power/$(@:_install=),install) 97 $(call descend,power/$(@:_install=),install)
98 98
99cgroup_install firewire_install hv_install lguest_install perf_install usb_install virtio_install vm_install net_install objtool_install: 99cgroup_install firewire_install gpio_install hv_install lguest_install perf_install usb_install virtio_install vm_install net_install objtool_install:
100 $(call descend,$(@:_install=),install) 100 $(call descend,$(@:_install=),install)
101 101
102selftests_install: 102selftests_install:
@@ -114,7 +114,8 @@ freefall_install:
114kvm_stat_install: 114kvm_stat_install:
115 $(call descend,kvm/$(@:_install=),install) 115 $(call descend,kvm/$(@:_install=),install)
116 116
117install: acpi_install cgroup_install cpupower_install hv_install firewire_install lguest_install \ 117install: acpi_install cgroup_install cpupower_install gpio_install \
118 hv_install firewire_install lguest_install \
118 perf_install selftests_install turbostat_install usb_install \ 119 perf_install selftests_install turbostat_install usb_install \
119 virtio_install vm_install net_install x86_energy_perf_policy_install \ 120 virtio_install vm_install net_install x86_energy_perf_policy_install \
120 tmon_install freefall_install objtool_install kvm_stat_install 121 tmon_install freefall_install objtool_install kvm_stat_install
diff --git a/tools/gpio/Build b/tools/gpio/Build
new file mode 100644
index 000000000000..620c1937d957
--- /dev/null
+++ b/tools/gpio/Build
@@ -0,0 +1,3 @@
1lsgpio-y += lsgpio.o gpio-utils.o
2gpio-hammer-y += gpio-hammer.o gpio-utils.o
3gpio-event-mon-y += gpio-event-mon.o gpio-utils.o
diff --git a/tools/gpio/Makefile b/tools/gpio/Makefile
index c155d6bc47a7..250a891e6ef0 100644
--- a/tools/gpio/Makefile
+++ b/tools/gpio/Makefile
@@ -1,12 +1,75 @@
1include ../scripts/Makefile.include
2
3bindir ?= /usr/bin
4
5ifeq ($(srctree),)
6srctree := $(patsubst %/,%,$(dir $(shell pwd)))
7srctree := $(patsubst %/,%,$(dir $(srctree)))
8endif
9
10# Do not use make's built-in rules
11# (this improves performance and avoids hard-to-debug behaviour);
12MAKEFLAGS += -r
13
1CC = $(CROSS_COMPILE)gcc 14CC = $(CROSS_COMPILE)gcc
2CFLAGS += -O2 -Wall -g -D_GNU_SOURCE 15LD = $(CROSS_COMPILE)ld
16CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include
17
18ALL_TARGETS := lsgpio gpio-hammer gpio-event-mon
19ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS))
20
21all: $(ALL_PROGRAMS)
3 22
4all: lsgpio 23export srctree OUTPUT CC LD CFLAGS
24include $(srctree)/tools/build/Makefile.include
5 25
6lsgpio: lsgpio.o gpio-utils.o 26#
27# We need the following to be outside of kernel tree
28#
29$(OUTPUT)include/linux/gpio.h: ../../include/uapi/linux/gpio.h
30 mkdir -p $(OUTPUT)include/linux 2>&1 || true
31 ln -sf $(CURDIR)/../../include/uapi/linux/gpio.h $@
7 32
8%.o: %.c gpio-utils.h 33prepare: $(OUTPUT)include/linux/gpio.h
34
35#
36# lsgpio
37#
38LSGPIO_IN := $(OUTPUT)lsgpio-in.o
39$(LSGPIO_IN): prepare FORCE
40 $(Q)$(MAKE) $(build)=lsgpio
41$(OUTPUT)lsgpio: $(LSGPIO_IN)
42 $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
43
44#
45# gpio-hammer
46#
47GPIO_HAMMER_IN := $(OUTPUT)gpio-hammer-in.o
48$(GPIO_HAMMER_IN): prepare FORCE
49 $(Q)$(MAKE) $(build)=gpio-hammer
50$(OUTPUT)gpio-hammer: $(GPIO_HAMMER_IN)
51 $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
52
53#
54# gpio-event-mon
55#
56GPIO_EVENT_MON_IN := $(OUTPUT)gpio-event-mon-in.o
57$(GPIO_EVENT_MON_IN): prepare FORCE
58 $(Q)$(MAKE) $(build)=gpio-event-mon
59$(OUTPUT)gpio-event-mon: $(GPIO_EVENT_MON_IN)
60 $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
9 61
10.PHONY: clean
11clean: 62clean:
12 rm -f *.o lsgpio 63 rm -f $(ALL_PROGRAMS)
64 rm -f $(OUTPUT)include/linux/gpio.h
65 find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete
66
67install: $(ALL_PROGRAMS)
68 install -d -m 755 $(DESTDIR)$(bindir); \
69 for program in $(ALL_PROGRAMS); do \
70 install $$program $(DESTDIR)$(bindir); \
71 done
72
73FORCE:
74
75.PHONY: all install clean FORCE prepare
diff --git a/tools/gpio/gpio-event-mon.c b/tools/gpio/gpio-event-mon.c
new file mode 100644
index 000000000000..448ed96b3b4f
--- /dev/null
+++ b/tools/gpio/gpio-event-mon.c
@@ -0,0 +1,192 @@
1/*
2 * gpio-hammer - example swiss army knife to shake GPIO lines on a system
3 *
4 * Copyright (C) 2016 Linus Walleij
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 *
10 * Usage:
11 * gpio-event-mon -n <device-name> -o <offset>
12 */
13
14#include <unistd.h>
15#include <stdlib.h>
16#include <stdbool.h>
17#include <stdio.h>
18#include <dirent.h>
19#include <errno.h>
20#include <string.h>
21#include <poll.h>
22#include <fcntl.h>
23#include <getopt.h>
24#include <inttypes.h>
25#include <sys/ioctl.h>
26#include <linux/gpio.h>
27
28int monitor_device(const char *device_name,
29 unsigned int line,
30 u_int32_t handleflags,
31 u_int32_t eventflags,
32 unsigned int loops)
33{
34 struct gpioevent_request req;
35 struct gpiohandle_data data;
36 char *chrdev_name;
37 int fd;
38 int ret;
39 int i = 0;
40
41 ret = asprintf(&chrdev_name, "/dev/%s", device_name);
42 if (ret < 0)
43 return -ENOMEM;
44
45 fd = open(chrdev_name, 0);
46 if (fd == -1) {
47 ret = -errno;
48 fprintf(stderr, "Failed to open %s\n", chrdev_name);
49 goto exit_close_error;
50 }
51
52 req.lineoffset = line;
53 req.handleflags = handleflags;
54 req.eventflags = eventflags;
55 strcpy(req.consumer_label, "gpio-event-mon");
56
57 ret = ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, &req);
58 if (ret == -1) {
59 ret = -errno;
60 fprintf(stderr, "Failed to issue GET EVENT "
61 "IOCTL (%d)\n",
62 ret);
63 goto exit_close_error;
64 }
65
66 /* Read initial states */
67 ret = ioctl(req.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
68 if (ret == -1) {
69 ret = -errno;
70 fprintf(stderr, "Failed to issue GPIOHANDLE GET LINE "
71 "VALUES IOCTL (%d)\n",
72 ret);
73 goto exit_close_error;
74 }
75
76 fprintf(stdout, "Monitoring line %d on %s\n", line, device_name);
77 fprintf(stdout, "Initial line value: %d\n", data.values[0]);
78
79 while (1) {
80 struct gpioevent_data event;
81
82 ret = read(req.fd, &event, sizeof(event));
83 if (ret == -1) {
84 if (errno == -EAGAIN) {
85 fprintf(stderr, "nothing available\n");
86 continue;
87 } else {
88 ret = -errno;
89 fprintf(stderr, "Failed to read event (%d)\n",
90 ret);
91 break;
92 }
93 }
94
95 if (ret != sizeof(event)) {
96 fprintf(stderr, "Reading event failed\n");
97 ret = -EIO;
98 break;
99 }
100 fprintf(stdout, "GPIO EVENT %" PRIu64 ": ", event.timestamp);
101 switch (event.id) {
102 case GPIOEVENT_EVENT_RISING_EDGE:
103 fprintf(stdout, "rising edge");
104 break;
105 case GPIOEVENT_EVENT_FALLING_EDGE:
106 fprintf(stdout, "falling edge");
107 break;
108 default:
109 fprintf(stdout, "unknown event");
110 }
111 fprintf(stdout, "\n");
112
113 i++;
114 if (i == loops)
115 break;
116 }
117
118exit_close_error:
119 if (close(fd) == -1)
120 perror("Failed to close GPIO character device file");
121 free(chrdev_name);
122 return ret;
123}
124
125void print_usage(void)
126{
127 fprintf(stderr, "Usage: gpio-event-mon [options]...\n"
128 "Listen to events on GPIO lines, 0->1 1->0\n"
129 " -n <name> Listen on GPIOs on a named device (must be stated)\n"
130 " -o <n> Offset to monitor\n"
131 " -d Set line as open drain\n"
132 " -s Set line as open source\n"
133 " -r Listen for rising edges\n"
134 " -f Listen for falling edges\n"
135 " [-c <n>] Do <n> loops (optional, infinite loop if not stated)\n"
136 " -? This helptext\n"
137 "\n"
138 "Example:\n"
139 "gpio-event-mon -n gpiochip0 -o 4 -r -f\n"
140 );
141}
142
143int main(int argc, char **argv)
144{
145 const char *device_name = NULL;
146 unsigned int line = -1;
147 unsigned int loops = 0;
148 u_int32_t handleflags = GPIOHANDLE_REQUEST_INPUT;
149 u_int32_t eventflags = 0;
150 int c;
151
152 while ((c = getopt(argc, argv, "c:n:o:dsrf?")) != -1) {
153 switch (c) {
154 case 'c':
155 loops = strtoul(optarg, NULL, 10);
156 break;
157 case 'n':
158 device_name = optarg;
159 break;
160 case 'o':
161 line = strtoul(optarg, NULL, 10);
162 break;
163 case 'd':
164 handleflags |= GPIOHANDLE_REQUEST_OPEN_DRAIN;
165 break;
166 case 's':
167 handleflags |= GPIOHANDLE_REQUEST_OPEN_SOURCE;
168 break;
169 case 'r':
170 eventflags |= GPIOEVENT_REQUEST_RISING_EDGE;
171 break;
172 case 'f':
173 eventflags |= GPIOEVENT_REQUEST_FALLING_EDGE;
174 break;
175 case '?':
176 print_usage();
177 return -1;
178 }
179 }
180
181 if (!device_name || line == -1) {
182 print_usage();
183 return -1;
184 }
185 if (!eventflags) {
186 printf("No flags specified, listening on both rising and "
187 "falling edges\n");
188 eventflags = GPIOEVENT_REQUEST_BOTH_EDGES;
189 }
190 return monitor_device(device_name, line, handleflags,
191 eventflags, loops);
192}
diff --git a/tools/gpio/gpio-hammer.c b/tools/gpio/gpio-hammer.c
new file mode 100644
index 000000000000..37b3f141053d
--- /dev/null
+++ b/tools/gpio/gpio-hammer.c
@@ -0,0 +1,189 @@
1/*
2 * gpio-hammer - example swiss army knife to shake GPIO lines on a system
3 *
4 * Copyright (C) 2016 Linus Walleij
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 *
10 * Usage:
11 * gpio-hammer -n <device-name> -o <offset1> -o <offset2>
12 */
13
14#include <unistd.h>
15#include <stdlib.h>
16#include <stdbool.h>
17#include <stdio.h>
18#include <dirent.h>
19#include <errno.h>
20#include <string.h>
21#include <poll.h>
22#include <fcntl.h>
23#include <getopt.h>
24#include <sys/ioctl.h>
25#include <linux/gpio.h>
26
27int hammer_device(const char *device_name, unsigned int *lines, int nlines,
28 unsigned int loops)
29{
30 struct gpiohandle_request req;
31 struct gpiohandle_data data;
32 char *chrdev_name;
33 char swirr[] = "-\\|/";
34 int fd;
35 int ret;
36 int i, j;
37 unsigned int iteration = 0;
38
39 ret = asprintf(&chrdev_name, "/dev/%s", device_name);
40 if (ret < 0)
41 return -ENOMEM;
42
43 fd = open(chrdev_name, 0);
44 if (fd == -1) {
45 ret = -errno;
46 fprintf(stderr, "Failed to open %s\n", chrdev_name);
47 goto exit_close_error;
48 }
49
50 /* Request lines as output */
51 for (i = 0; i < nlines; i++)
52 req.lineoffsets[i] = lines[i];
53 req.flags = GPIOHANDLE_REQUEST_OUTPUT; /* Request as output */
54 strcpy(req.consumer_label, "gpio-hammer");
55 req.lines = nlines;
56 ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
57 if (ret == -1) {
58 ret = -errno;
59 fprintf(stderr, "Failed to issue GET LINEHANDLE "
60 "IOCTL (%d)\n",
61 ret);
62 goto exit_close_error;
63 }
64
65 /* Read initial states */
66 ret = ioctl(req.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
67 if (ret == -1) {
68 ret = -errno;
69 fprintf(stderr, "Failed to issue GPIOHANDLE GET LINE "
70 "VALUES IOCTL (%d)\n",
71 ret);
72 goto exit_close_error;
73 }
74 fprintf(stdout, "Hammer lines [");
75 for (i = 0; i < nlines; i++) {
76 fprintf(stdout, "%d", lines[i]);
77 if (i != (nlines - 1))
78 fprintf(stdout, ", ");
79 }
80 fprintf(stdout, "] on %s, initial states: [", device_name);
81 for (i = 0; i < nlines; i++) {
82 fprintf(stdout, "%d", data.values[i]);
83 if (i != (nlines - 1))
84 fprintf(stdout, ", ");
85 }
86 fprintf(stdout, "]\n");
87
88 /* Hammertime! */
89 j = 0;
90 while (1) {
91 /* Invert all lines so we blink */
92 for (i = 0; i < nlines; i++)
93 data.values[i] = !data.values[i];
94
95 ret = ioctl(req.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
96 if (ret == -1) {
97 ret = -errno;
98 fprintf(stderr, "Failed to issue GPIOHANDLE SET LINE "
99 "VALUES IOCTL (%d)\n",
100 ret);
101 goto exit_close_error;
102 }
103 /* Re-read values to get status */
104 ret = ioctl(req.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
105 if (ret == -1) {
106 ret = -errno;
107 fprintf(stderr, "Failed to issue GPIOHANDLE GET LINE "
108 "VALUES IOCTL (%d)\n",
109 ret);
110 goto exit_close_error;
111 }
112
113 fprintf(stdout, "[%c] ", swirr[j]);
114 j++;
115 if (j == sizeof(swirr)-1)
116 j = 0;
117
118 fprintf(stdout, "[");
119 for (i = 0; i < nlines; i++) {
120 fprintf(stdout, "%d: %d", lines[i], data.values[i]);
121 if (i != (nlines - 1))
122 fprintf(stdout, ", ");
123 }
124 fprintf(stdout, "]\r");
125 fflush(stdout);
126 sleep(1);
127 iteration++;
128 if (loops && iteration == loops)
129 break;
130 }
131 fprintf(stdout, "\n");
132 ret = 0;
133
134exit_close_error:
135 if (close(fd) == -1)
136 perror("Failed to close GPIO character device file");
137 free(chrdev_name);
138 return ret;
139}
140
141void print_usage(void)
142{
143 fprintf(stderr, "Usage: gpio-hammer [options]...\n"
144 "Hammer GPIO lines, 0->1->0->1...\n"
145 " -n <name> Hammer GPIOs on a named device (must be stated)\n"
146 " -o <n> Offset[s] to hammer, at least one, several can be stated\n"
147 " [-c <n>] Do <n> loops (optional, infinite loop if not stated)\n"
148 " -? This helptext\n"
149 "\n"
150 "Example:\n"
151 "gpio-hammer -n gpiochip0 -o 4\n"
152 );
153}
154
155int main(int argc, char **argv)
156{
157 const char *device_name = NULL;
158 unsigned int lines[GPIOHANDLES_MAX];
159 unsigned int loops = 0;
160 int nlines;
161 int c;
162 int i;
163
164 i = 0;
165 while ((c = getopt(argc, argv, "c:n:o:?")) != -1) {
166 switch (c) {
167 case 'c':
168 loops = strtoul(optarg, NULL, 10);
169 break;
170 case 'n':
171 device_name = optarg;
172 break;
173 case 'o':
174 lines[i] = strtoul(optarg, NULL, 10);
175 i++;
176 break;
177 case '?':
178 print_usage();
179 return -1;
180 }
181 }
182 nlines = i;
183
184 if (!device_name || !nlines) {
185 print_usage();
186 return -1;
187 }
188 return hammer_device(device_name, lines, nlines, loops);
189}
diff --git a/tools/hv/bondvf.sh b/tools/hv/bondvf.sh
new file mode 100755
index 000000000000..8e960234013d
--- /dev/null
+++ b/tools/hv/bondvf.sh
@@ -0,0 +1,193 @@
1#!/bin/bash
2
3# This example script creates bonding network devices based on synthetic NIC
4# (the virtual network adapter usually provided by Hyper-V) and the matching
5# VF NIC (SRIOV virtual function). So the synthetic NIC and VF NIC can
6# function as one network device, and fail over to the synthetic NIC if VF is
7# down.
8#
9# Usage:
10# - After configured vSwitch and vNIC with SRIOV, start Linux virtual
11# machine (VM)
12# - Run this scripts on the VM. It will create configuration files in
13# distro specific directory.
14# - Reboot the VM, so that the bonding config are enabled.
15#
16# The config files are DHCP by default. You may edit them if you need to change
17# to Static IP or change other settings.
18#
19
20sysdir=/sys/class/net
21netvsc_cls={f8615163-df3e-46c5-913f-f2d2f965ed0e}
22bondcnt=0
23
24# Detect Distro
25if [ -f /etc/redhat-release ];
26then
27 cfgdir=/etc/sysconfig/network-scripts
28 distro=redhat
29elif grep -q 'Ubuntu' /etc/issue
30then
31 cfgdir=/etc/network
32 distro=ubuntu
33elif grep -q 'SUSE' /etc/issue
34then
35 cfgdir=/etc/sysconfig/network
36 distro=suse
37else
38 echo "Unsupported Distro"
39 exit 1
40fi
41
42echo Detected Distro: $distro, or compatible
43
44# Get a list of ethernet names
45list_eth=(`cd $sysdir && ls -d */ | cut -d/ -f1 | grep -v bond`)
46eth_cnt=${#list_eth[@]}
47
48echo List of net devices:
49
50# Get the MAC addresses
51for (( i=0; i < $eth_cnt; i++ ))
52do
53 list_mac[$i]=`cat $sysdir/${list_eth[$i]}/address`
54 echo ${list_eth[$i]}, ${list_mac[$i]}
55done
56
57# Find NIC with matching MAC
58for (( i=0; i < $eth_cnt-1; i++ ))
59do
60 for (( j=i+1; j < $eth_cnt; j++ ))
61 do
62 if [ "${list_mac[$i]}" = "${list_mac[$j]}" ]
63 then
64 list_match[$i]=${list_eth[$j]}
65 break
66 fi
67 done
68done
69
70function create_eth_cfg_redhat {
71 local fn=$cfgdir/ifcfg-$1
72
73 rm -f $fn
74 echo DEVICE=$1 >>$fn
75 echo TYPE=Ethernet >>$fn
76 echo BOOTPROTO=none >>$fn
77 echo ONBOOT=yes >>$fn
78 echo NM_CONTROLLED=no >>$fn
79 echo PEERDNS=yes >>$fn
80 echo IPV6INIT=yes >>$fn
81 echo MASTER=$2 >>$fn
82 echo SLAVE=yes >>$fn
83}
84
85function create_eth_cfg_pri_redhat {
86 create_eth_cfg_redhat $1 $2
87}
88
89function create_bond_cfg_redhat {
90 local fn=$cfgdir/ifcfg-$1
91
92 rm -f $fn
93 echo DEVICE=$1 >>$fn
94 echo TYPE=Bond >>$fn
95 echo BOOTPROTO=dhcp >>$fn
96 echo ONBOOT=yes >>$fn
97 echo NM_CONTROLLED=no >>$fn
98 echo PEERDNS=yes >>$fn
99 echo IPV6INIT=yes >>$fn
100 echo BONDING_MASTER=yes >>$fn
101 echo BONDING_OPTS=\"mode=active-backup miimon=100 primary=$2\" >>$fn
102}
103
104function create_eth_cfg_ubuntu {
105 local fn=$cfgdir/interfaces
106
107 echo $'\n'auto $1 >>$fn
108 echo iface $1 inet manual >>$fn
109 echo bond-master $2 >>$fn
110}
111
112function create_eth_cfg_pri_ubuntu {
113 local fn=$cfgdir/interfaces
114
115 create_eth_cfg_ubuntu $1 $2
116 echo bond-primary $1 >>$fn
117}
118
119function create_bond_cfg_ubuntu {
120 local fn=$cfgdir/interfaces
121
122 echo $'\n'auto $1 >>$fn
123 echo iface $1 inet dhcp >>$fn
124 echo bond-mode active-backup >>$fn
125 echo bond-miimon 100 >>$fn
126 echo bond-slaves none >>$fn
127}
128
129function create_eth_cfg_suse {
130 local fn=$cfgdir/ifcfg-$1
131
132 rm -f $fn
133 echo BOOTPROTO=none >>$fn
134 echo STARTMODE=auto >>$fn
135}
136
137function create_eth_cfg_pri_suse {
138 create_eth_cfg_suse $1
139}
140
141function create_bond_cfg_suse {
142 local fn=$cfgdir/ifcfg-$1
143
144 rm -f $fn
145 echo BOOTPROTO=dhcp >>$fn
146 echo STARTMODE=auto >>$fn
147 echo BONDING_MASTER=yes >>$fn
148 echo BONDING_SLAVE_0=$2 >>$fn
149 echo BONDING_SLAVE_1=$3 >>$fn
150 echo BONDING_MODULE_OPTS=\'mode=active-backup miimon=100 primary=$2\' >>$fn
151}
152
153function create_bond {
154 local bondname=bond$bondcnt
155 local primary
156 local secondary
157
158 local class_id1=`cat $sysdir/$1/device/class_id 2>/dev/null`
159 local class_id2=`cat $sysdir/$2/device/class_id 2>/dev/null`
160
161 if [ "$class_id1" = "$netvsc_cls" ]
162 then
163 primary=$2
164 secondary=$1
165 elif [ "$class_id2" = "$netvsc_cls" ]
166 then
167 primary=$1
168 secondary=$2
169 else
170 return 0
171 fi
172
173 echo $'\nBond name:' $bondname
174
175 echo configuring $primary
176 create_eth_cfg_pri_$distro $primary $bondname
177
178 echo configuring $secondary
179 create_eth_cfg_$distro $secondary $bondname
180
181 echo creating: $bondname with primary slave: $primary
182 create_bond_cfg_$distro $bondname $primary $secondary
183
184 let bondcnt=bondcnt+1
185}
186
187for (( i=0; i < $eth_cnt-1; i++ ))
188do
189 if [ -n "${list_match[$i]}" ]
190 then
191 create_bond ${list_eth[$i]} ${list_match[$i]}
192 fi
193done
diff --git a/tools/lib/api/Build b/tools/lib/api/Build
index 954c644f7ad9..6e2373db5598 100644
--- a/tools/lib/api/Build
+++ b/tools/lib/api/Build
@@ -2,3 +2,8 @@ libapi-y += fd/
2libapi-y += fs/ 2libapi-y += fs/
3libapi-y += cpu.o 3libapi-y += cpu.o
4libapi-y += debug.o 4libapi-y += debug.o
5libapi-y += str_error_r.o
6
7$(OUTPUT)str_error_r.o: ../str_error_r.c FORCE
8 $(call rule_mkdir)
9 $(call if_changed_dep,cc_o_c)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 32e6b6bc6f7d..b699aea9a025 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -37,6 +37,10 @@
37#include "libbpf.h" 37#include "libbpf.h"
38#include "bpf.h" 38#include "bpf.h"
39 39
40#ifndef EM_BPF
41#define EM_BPF 247
42#endif
43
40#define __printf(a, b) __attribute__((format(printf, a, b))) 44#define __printf(a, b) __attribute__((format(printf, a, b)))
41 45
42__printf(1, 2) 46__printf(1, 2)
@@ -439,7 +443,8 @@ static int bpf_object__elf_init(struct bpf_object *obj)
439 } 443 }
440 ep = &obj->efile.ehdr; 444 ep = &obj->efile.ehdr;
441 445
442 if ((ep->e_type != ET_REL) || (ep->e_machine != 0)) { 446 /* Old LLVM set e_machine to EM_NONE */
447 if ((ep->e_type != ET_REL) || (ep->e_machine && (ep->e_machine != EM_BPF))) {
443 pr_warning("%s is not an eBPF object file\n", 448 pr_warning("%s is not an eBPF object file\n",
444 obj->path); 449 obj->path);
445 err = -LIBBPF_ERRNO__FORMAT; 450 err = -LIBBPF_ERRNO__FORMAT;
diff --git a/tools/objtool/.gitignore b/tools/objtool/.gitignore
index a0b3128bb31f..d3102c865a95 100644
--- a/tools/objtool/.gitignore
+++ b/tools/objtool/.gitignore
@@ -1,2 +1,3 @@
1arch/x86/insn/inat-tables.c 1arch/x86/insn/inat-tables.c
2objtool 2objtool
3fixdep
diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
index 0b437700f688..041b493ad3ab 100644
--- a/tools/objtool/Makefile
+++ b/tools/objtool/Makefile
@@ -51,7 +51,7 @@ $(OBJTOOL): $(LIBSUBCMD) $(OBJTOOL_IN)
51 diff -I'^#include' arch/x86/insn/insn.h ../../arch/x86/include/asm/insn.h >/dev/null && \ 51 diff -I'^#include' arch/x86/insn/insn.h ../../arch/x86/include/asm/insn.h >/dev/null && \
52 diff -I'^#include' arch/x86/insn/inat.h ../../arch/x86/include/asm/inat.h >/dev/null && \ 52 diff -I'^#include' arch/x86/insn/inat.h ../../arch/x86/include/asm/inat.h >/dev/null && \
53 diff -I'^#include' arch/x86/insn/inat_types.h ../../arch/x86/include/asm/inat_types.h >/dev/null) \ 53 diff -I'^#include' arch/x86/insn/inat_types.h ../../arch/x86/include/asm/inat_types.h >/dev/null) \
54 || echo "Warning: objtool: x86 instruction decoder differs from kernel" >&2 )) || true 54 || echo "warning: objtool: x86 instruction decoder differs from kernel" >&2 )) || true
55 $(QUIET_LINK)$(CC) $(OBJTOOL_IN) $(LDFLAGS) -o $@ 55 $(QUIET_LINK)$(CC) $(OBJTOOL_IN) $(LDFLAGS) -o $@
56 56
57 57
diff --git a/tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk b/tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk
index 093a892026f9..a3d2c62fd805 100644
--- a/tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk
+++ b/tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk
@@ -72,12 +72,14 @@ BEGIN {
72 lprefix_expr = "\\((66|F2|F3)\\)" 72 lprefix_expr = "\\((66|F2|F3)\\)"
73 max_lprefix = 4 73 max_lprefix = 4
74 74
75 # All opcodes starting with lower-case 'v' or with (v1) superscript 75 # All opcodes starting with lower-case 'v', 'k' or with (v1) superscript
76 # accepts VEX prefix 76 # accepts VEX prefix
77 vexok_opcode_expr = "^v.*" 77 vexok_opcode_expr = "^[vk].*"
78 vexok_expr = "\\(v1\\)" 78 vexok_expr = "\\(v1\\)"
79 # All opcodes with (v) superscript supports *only* VEX prefix 79 # All opcodes with (v) superscript supports *only* VEX prefix
80 vexonly_expr = "\\(v\\)" 80 vexonly_expr = "\\(v\\)"
81 # All opcodes with (ev) superscript supports *only* EVEX prefix
82 evexonly_expr = "\\(ev\\)"
81 83
82 prefix_expr = "\\(Prefix\\)" 84 prefix_expr = "\\(Prefix\\)"
83 prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ" 85 prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ"
@@ -95,6 +97,7 @@ BEGIN {
95 prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ" 97 prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ"
96 prefix_num["VEX+1byte"] = "INAT_PFX_VEX2" 98 prefix_num["VEX+1byte"] = "INAT_PFX_VEX2"
97 prefix_num["VEX+2byte"] = "INAT_PFX_VEX3" 99 prefix_num["VEX+2byte"] = "INAT_PFX_VEX3"
100 prefix_num["EVEX"] = "INAT_PFX_EVEX"
98 101
99 clear_vars() 102 clear_vars()
100} 103}
@@ -319,7 +322,9 @@ function convert_operands(count,opnd, i,j,imm,mod)
319 flags = add_flags(flags, "INAT_MODRM") 322 flags = add_flags(flags, "INAT_MODRM")
320 323
321 # check VEX codes 324 # check VEX codes
322 if (match(ext, vexonly_expr)) 325 if (match(ext, evexonly_expr))
326 flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY")
327 else if (match(ext, vexonly_expr))
323 flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY") 328 flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY")
324 else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr)) 329 else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr))
325 flags = add_flags(flags, "INAT_VEXOK") 330 flags = add_flags(flags, "INAT_VEXOK")
diff --git a/tools/objtool/arch/x86/insn/inat.h b/tools/objtool/arch/x86/insn/inat.h
index 611645e903a8..125ecd2a300d 100644
--- a/tools/objtool/arch/x86/insn/inat.h
+++ b/tools/objtool/arch/x86/insn/inat.h
@@ -48,6 +48,7 @@
48/* AVX VEX prefixes */ 48/* AVX VEX prefixes */
49#define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */ 49#define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */
50#define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */ 50#define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */
51#define INAT_PFX_EVEX 15 /* EVEX prefix */
51 52
52#define INAT_LSTPFX_MAX 3 53#define INAT_LSTPFX_MAX 3
53#define INAT_LGCPFX_MAX 11 54#define INAT_LGCPFX_MAX 11
@@ -89,6 +90,7 @@
89#define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4)) 90#define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4))
90#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5)) 91#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5))
91#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6)) 92#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6))
93#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7))
92/* Attribute making macros for attribute tables */ 94/* Attribute making macros for attribute tables */
93#define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS) 95#define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS)
94#define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS) 96#define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS)
@@ -141,7 +143,13 @@ static inline int inat_last_prefix_id(insn_attr_t attr)
141static inline int inat_is_vex_prefix(insn_attr_t attr) 143static inline int inat_is_vex_prefix(insn_attr_t attr)
142{ 144{
143 attr &= INAT_PFX_MASK; 145 attr &= INAT_PFX_MASK;
144 return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3; 146 return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 ||
147 attr == INAT_PFX_EVEX;
148}
149
150static inline int inat_is_evex_prefix(insn_attr_t attr)
151{
152 return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX;
145} 153}
146 154
147static inline int inat_is_vex3_prefix(insn_attr_t attr) 155static inline int inat_is_vex3_prefix(insn_attr_t attr)
@@ -216,6 +224,11 @@ static inline int inat_accept_vex(insn_attr_t attr)
216 224
217static inline int inat_must_vex(insn_attr_t attr) 225static inline int inat_must_vex(insn_attr_t attr)
218{ 226{
219 return attr & INAT_VEXONLY; 227 return attr & (INAT_VEXONLY | INAT_EVEXONLY);
228}
229
230static inline int inat_must_evex(insn_attr_t attr)
231{
232 return attr & INAT_EVEXONLY;
220} 233}
221#endif 234#endif
diff --git a/tools/objtool/arch/x86/insn/insn.c b/tools/objtool/arch/x86/insn/insn.c
index 9f26eae6c9f0..ca983e2bea8b 100644
--- a/tools/objtool/arch/x86/insn/insn.c
+++ b/tools/objtool/arch/x86/insn/insn.c
@@ -155,14 +155,24 @@ found:
155 /* 155 /*
156 * In 32-bits mode, if the [7:6] bits (mod bits of 156 * In 32-bits mode, if the [7:6] bits (mod bits of
157 * ModRM) on the second byte are not 11b, it is 157 * ModRM) on the second byte are not 11b, it is
158 * LDS or LES. 158 * LDS or LES or BOUND.
159 */ 159 */
160 if (X86_MODRM_MOD(b2) != 3) 160 if (X86_MODRM_MOD(b2) != 3)
161 goto vex_end; 161 goto vex_end;
162 } 162 }
163 insn->vex_prefix.bytes[0] = b; 163 insn->vex_prefix.bytes[0] = b;
164 insn->vex_prefix.bytes[1] = b2; 164 insn->vex_prefix.bytes[1] = b2;
165 if (inat_is_vex3_prefix(attr)) { 165 if (inat_is_evex_prefix(attr)) {
166 b2 = peek_nbyte_next(insn_byte_t, insn, 2);
167 insn->vex_prefix.bytes[2] = b2;
168 b2 = peek_nbyte_next(insn_byte_t, insn, 3);
169 insn->vex_prefix.bytes[3] = b2;
170 insn->vex_prefix.nbytes = 4;
171 insn->next_byte += 4;
172 if (insn->x86_64 && X86_VEX_W(b2))
173 /* VEX.W overrides opnd_size */
174 insn->opnd_bytes = 8;
175 } else if (inat_is_vex3_prefix(attr)) {
166 b2 = peek_nbyte_next(insn_byte_t, insn, 2); 176 b2 = peek_nbyte_next(insn_byte_t, insn, 2);
167 insn->vex_prefix.bytes[2] = b2; 177 insn->vex_prefix.bytes[2] = b2;
168 insn->vex_prefix.nbytes = 3; 178 insn->vex_prefix.nbytes = 3;
@@ -221,7 +231,9 @@ void insn_get_opcode(struct insn *insn)
221 m = insn_vex_m_bits(insn); 231 m = insn_vex_m_bits(insn);
222 p = insn_vex_p_bits(insn); 232 p = insn_vex_p_bits(insn);
223 insn->attr = inat_get_avx_attribute(op, m, p); 233 insn->attr = inat_get_avx_attribute(op, m, p);
224 if (!inat_accept_vex(insn->attr) && !inat_is_group(insn->attr)) 234 if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) ||
235 (!inat_accept_vex(insn->attr) &&
236 !inat_is_group(insn->attr)))
225 insn->attr = 0; /* This instruction is bad */ 237 insn->attr = 0; /* This instruction is bad */
226 goto end; /* VEX has only 1 byte for opcode */ 238 goto end; /* VEX has only 1 byte for opcode */
227 } 239 }
diff --git a/tools/objtool/arch/x86/insn/insn.h b/tools/objtool/arch/x86/insn/insn.h
index dd12da0f4593..e23578c7b1be 100644
--- a/tools/objtool/arch/x86/insn/insn.h
+++ b/tools/objtool/arch/x86/insn/insn.h
@@ -91,6 +91,7 @@ struct insn {
91#define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */ 91#define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */
92#define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */ 92#define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */
93/* VEX bit fields */ 93/* VEX bit fields */
94#define X86_EVEX_M(vex) ((vex) & 0x03) /* EVEX Byte1 */
94#define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */ 95#define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */
95#define X86_VEX2_M 1 /* VEX2.M always 1 */ 96#define X86_VEX2_M 1 /* VEX2.M always 1 */
96#define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */ 97#define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */
@@ -133,6 +134,13 @@ static inline int insn_is_avx(struct insn *insn)
133 return (insn->vex_prefix.value != 0); 134 return (insn->vex_prefix.value != 0);
134} 135}
135 136
137static inline int insn_is_evex(struct insn *insn)
138{
139 if (!insn->prefixes.got)
140 insn_get_prefixes(insn);
141 return (insn->vex_prefix.nbytes == 4);
142}
143
136/* Ensure this instruction is decoded completely */ 144/* Ensure this instruction is decoded completely */
137static inline int insn_complete(struct insn *insn) 145static inline int insn_complete(struct insn *insn)
138{ 146{
@@ -144,8 +152,10 @@ static inline insn_byte_t insn_vex_m_bits(struct insn *insn)
144{ 152{
145 if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */ 153 if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */
146 return X86_VEX2_M; 154 return X86_VEX2_M;
147 else 155 else if (insn->vex_prefix.nbytes == 3) /* 3 bytes VEX */
148 return X86_VEX3_M(insn->vex_prefix.bytes[1]); 156 return X86_VEX3_M(insn->vex_prefix.bytes[1]);
157 else /* EVEX */
158 return X86_EVEX_M(insn->vex_prefix.bytes[1]);
149} 159}
150 160
151static inline insn_byte_t insn_vex_p_bits(struct insn *insn) 161static inline insn_byte_t insn_vex_p_bits(struct insn *insn)
diff --git a/tools/objtool/arch/x86/insn/x86-opcode-map.txt b/tools/objtool/arch/x86/insn/x86-opcode-map.txt
index d388de72eaca..767be7c76034 100644
--- a/tools/objtool/arch/x86/insn/x86-opcode-map.txt
+++ b/tools/objtool/arch/x86/insn/x86-opcode-map.txt
@@ -13,12 +13,17 @@
13# opcode: escape # escaped-name 13# opcode: escape # escaped-name
14# EndTable 14# EndTable
15# 15#
16# mnemonics that begin with lowercase 'v' accept a VEX or EVEX prefix
17# mnemonics that begin with lowercase 'k' accept a VEX prefix
18#
16#<group maps> 19#<group maps>
17# GrpTable: GrpXXX 20# GrpTable: GrpXXX
18# reg: mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...] 21# reg: mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
19# EndTable 22# EndTable
20# 23#
21# AVX Superscripts 24# AVX Superscripts
25# (ev): this opcode requires EVEX prefix.
26# (evo): this opcode is changed by EVEX prefix (EVEX opcode)
22# (v): this opcode requires VEX prefix. 27# (v): this opcode requires VEX prefix.
23# (v1): this opcode only supports 128bit VEX. 28# (v1): this opcode only supports 128bit VEX.
24# 29#
@@ -137,7 +142,7 @@ AVXcode:
137# 0x60 - 0x6f 142# 0x60 - 0x6f
13860: PUSHA/PUSHAD (i64) 14360: PUSHA/PUSHAD (i64)
13961: POPA/POPAD (i64) 14461: POPA/POPAD (i64)
14062: BOUND Gv,Ma (i64) 14562: BOUND Gv,Ma (i64) | EVEX (Prefix)
14163: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64) 14663: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64)
14264: SEG=FS (Prefix) 14764: SEG=FS (Prefix)
14365: SEG=GS (Prefix) 14865: SEG=GS (Prefix)
@@ -399,17 +404,17 @@ AVXcode: 1
3993f: 4043f:
400# 0x0f 0x40-0x4f 405# 0x0f 0x40-0x4f
40140: CMOVO Gv,Ev 40640: CMOVO Gv,Ev
40241: CMOVNO Gv,Ev 40741: CMOVNO Gv,Ev | kandw/q Vk,Hk,Uk | kandb/d Vk,Hk,Uk (66)
40342: CMOVB/C/NAE Gv,Ev 40842: CMOVB/C/NAE Gv,Ev | kandnw/q Vk,Hk,Uk | kandnb/d Vk,Hk,Uk (66)
40443: CMOVAE/NB/NC Gv,Ev 40943: CMOVAE/NB/NC Gv,Ev
40544: CMOVE/Z Gv,Ev 41044: CMOVE/Z Gv,Ev | knotw/q Vk,Uk | knotb/d Vk,Uk (66)
40645: CMOVNE/NZ Gv,Ev 41145: CMOVNE/NZ Gv,Ev | korw/q Vk,Hk,Uk | korb/d Vk,Hk,Uk (66)
40746: CMOVBE/NA Gv,Ev 41246: CMOVBE/NA Gv,Ev | kxnorw/q Vk,Hk,Uk | kxnorb/d Vk,Hk,Uk (66)
40847: CMOVA/NBE Gv,Ev 41347: CMOVA/NBE Gv,Ev | kxorw/q Vk,Hk,Uk | kxorb/d Vk,Hk,Uk (66)
40948: CMOVS Gv,Ev 41448: CMOVS Gv,Ev
41049: CMOVNS Gv,Ev 41549: CMOVNS Gv,Ev
4114a: CMOVP/PE Gv,Ev 4164a: CMOVP/PE Gv,Ev | kaddw/q Vk,Hk,Uk | kaddb/d Vk,Hk,Uk (66)
4124b: CMOVNP/PO Gv,Ev 4174b: CMOVNP/PO Gv,Ev | kunpckbw Vk,Hk,Uk (66) | kunpckwd/dq Vk,Hk,Uk
4134c: CMOVL/NGE Gv,Ev 4184c: CMOVL/NGE Gv,Ev
4144d: CMOVNL/GE Gv,Ev 4194d: CMOVNL/GE Gv,Ev
4154e: CMOVLE/NG Gv,Ev 4204e: CMOVLE/NG Gv,Ev
@@ -426,7 +431,7 @@ AVXcode: 1
42658: vaddps Vps,Hps,Wps | vaddpd Vpd,Hpd,Wpd (66) | vaddss Vss,Hss,Wss (F3),(v1) | vaddsd Vsd,Hsd,Wsd (F2),(v1) 43158: vaddps Vps,Hps,Wps | vaddpd Vpd,Hpd,Wpd (66) | vaddss Vss,Hss,Wss (F3),(v1) | vaddsd Vsd,Hsd,Wsd (F2),(v1)
42759: vmulps Vps,Hps,Wps | vmulpd Vpd,Hpd,Wpd (66) | vmulss Vss,Hss,Wss (F3),(v1) | vmulsd Vsd,Hsd,Wsd (F2),(v1) 43259: vmulps Vps,Hps,Wps | vmulpd Vpd,Hpd,Wpd (66) | vmulss Vss,Hss,Wss (F3),(v1) | vmulsd Vsd,Hsd,Wsd (F2),(v1)
4285a: vcvtps2pd Vpd,Wps | vcvtpd2ps Vps,Wpd (66) | vcvtss2sd Vsd,Hx,Wss (F3),(v1) | vcvtsd2ss Vss,Hx,Wsd (F2),(v1) 4335a: vcvtps2pd Vpd,Wps | vcvtpd2ps Vps,Wpd (66) | vcvtss2sd Vsd,Hx,Wss (F3),(v1) | vcvtsd2ss Vss,Hx,Wsd (F2),(v1)
4295b: vcvtdq2ps Vps,Wdq | vcvtps2dq Vdq,Wps (66) | vcvttps2dq Vdq,Wps (F3) 4345b: vcvtdq2ps Vps,Wdq | vcvtqq2ps Vps,Wqq (evo) | vcvtps2dq Vdq,Wps (66) | vcvttps2dq Vdq,Wps (F3)
4305c: vsubps Vps,Hps,Wps | vsubpd Vpd,Hpd,Wpd (66) | vsubss Vss,Hss,Wss (F3),(v1) | vsubsd Vsd,Hsd,Wsd (F2),(v1) 4355c: vsubps Vps,Hps,Wps | vsubpd Vpd,Hpd,Wpd (66) | vsubss Vss,Hss,Wss (F3),(v1) | vsubsd Vsd,Hsd,Wsd (F2),(v1)
4315d: vminps Vps,Hps,Wps | vminpd Vpd,Hpd,Wpd (66) | vminss Vss,Hss,Wss (F3),(v1) | vminsd Vsd,Hsd,Wsd (F2),(v1) 4365d: vminps Vps,Hps,Wps | vminpd Vpd,Hpd,Wpd (66) | vminss Vss,Hss,Wss (F3),(v1) | vminsd Vsd,Hsd,Wsd (F2),(v1)
4325e: vdivps Vps,Hps,Wps | vdivpd Vpd,Hpd,Wpd (66) | vdivss Vss,Hss,Wss (F3),(v1) | vdivsd Vsd,Hsd,Wsd (F2),(v1) 4375e: vdivps Vps,Hps,Wps | vdivpd Vpd,Hpd,Wpd (66) | vdivss Vss,Hss,Wss (F3),(v1) | vdivsd Vsd,Hsd,Wsd (F2),(v1)
@@ -447,7 +452,7 @@ AVXcode: 1
4476c: vpunpcklqdq Vx,Hx,Wx (66),(v1) 4526c: vpunpcklqdq Vx,Hx,Wx (66),(v1)
4486d: vpunpckhqdq Vx,Hx,Wx (66),(v1) 4536d: vpunpckhqdq Vx,Hx,Wx (66),(v1)
4496e: movd/q Pd,Ey | vmovd/q Vy,Ey (66),(v1) 4546e: movd/q Pd,Ey | vmovd/q Vy,Ey (66),(v1)
4506f: movq Pq,Qq | vmovdqa Vx,Wx (66) | vmovdqu Vx,Wx (F3) 4556f: movq Pq,Qq | vmovdqa Vx,Wx (66) | vmovdqa32/64 Vx,Wx (66),(evo) | vmovdqu Vx,Wx (F3) | vmovdqu32/64 Vx,Wx (F3),(evo) | vmovdqu8/16 Vx,Wx (F2),(ev)
451# 0x0f 0x70-0x7f 456# 0x0f 0x70-0x7f
45270: pshufw Pq,Qq,Ib | vpshufd Vx,Wx,Ib (66),(v1) | vpshufhw Vx,Wx,Ib (F3),(v1) | vpshuflw Vx,Wx,Ib (F2),(v1) 45770: pshufw Pq,Qq,Ib | vpshufd Vx,Wx,Ib (66),(v1) | vpshufhw Vx,Wx,Ib (F3),(v1) | vpshuflw Vx,Wx,Ib (F2),(v1)
45371: Grp12 (1A) 45871: Grp12 (1A)
@@ -458,14 +463,14 @@ AVXcode: 1
45876: pcmpeqd Pq,Qq | vpcmpeqd Vx,Hx,Wx (66),(v1) 46376: pcmpeqd Pq,Qq | vpcmpeqd Vx,Hx,Wx (66),(v1)
459# Note: Remove (v), because vzeroall and vzeroupper becomes emms without VEX. 464# Note: Remove (v), because vzeroall and vzeroupper becomes emms without VEX.
46077: emms | vzeroupper | vzeroall 46577: emms | vzeroupper | vzeroall
46178: VMREAD Ey,Gy 46678: VMREAD Ey,Gy | vcvttps2udq/pd2udq Vx,Wpd (evo) | vcvttsd2usi Gv,Wx (F2),(ev) | vcvttss2usi Gv,Wx (F3),(ev) | vcvttps2uqq/pd2uqq Vx,Wx (66),(ev)
46279: VMWRITE Gy,Ey 46779: VMWRITE Gy,Ey | vcvtps2udq/pd2udq Vx,Wpd (evo) | vcvtsd2usi Gv,Wx (F2),(ev) | vcvtss2usi Gv,Wx (F3),(ev) | vcvtps2uqq/pd2uqq Vx,Wx (66),(ev)
4637a: 4687a: vcvtudq2pd/uqq2pd Vpd,Wx (F3),(ev) | vcvtudq2ps/uqq2ps Vpd,Wx (F2),(ev) | vcvttps2qq/pd2qq Vx,Wx (66),(ev)
4647b: 4697b: vcvtusi2sd Vpd,Hpd,Ev (F2),(ev) | vcvtusi2ss Vps,Hps,Ev (F3),(ev) | vcvtps2qq/pd2qq Vx,Wx (66),(ev)
4657c: vhaddpd Vpd,Hpd,Wpd (66) | vhaddps Vps,Hps,Wps (F2) 4707c: vhaddpd Vpd,Hpd,Wpd (66) | vhaddps Vps,Hps,Wps (F2)
4667d: vhsubpd Vpd,Hpd,Wpd (66) | vhsubps Vps,Hps,Wps (F2) 4717d: vhsubpd Vpd,Hpd,Wpd (66) | vhsubps Vps,Hps,Wps (F2)
4677e: movd/q Ey,Pd | vmovd/q Ey,Vy (66),(v1) | vmovq Vq,Wq (F3),(v1) 4727e: movd/q Ey,Pd | vmovd/q Ey,Vy (66),(v1) | vmovq Vq,Wq (F3),(v1)
4687f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqu Wx,Vx (F3) 4737f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqa32/64 Wx,Vx (66),(evo) | vmovdqu Wx,Vx (F3) | vmovdqu32/64 Wx,Vx (F3),(evo) | vmovdqu8/16 Wx,Vx (F2),(ev)
469# 0x0f 0x80-0x8f 474# 0x0f 0x80-0x8f
470# Note: "forced64" is Intel CPU behavior (see comment about CALL insn). 475# Note: "forced64" is Intel CPU behavior (see comment about CALL insn).
47180: JO Jz (f64) 47680: JO Jz (f64)
@@ -485,16 +490,16 @@ AVXcode: 1
4858e: JLE/JNG Jz (f64) 4908e: JLE/JNG Jz (f64)
4868f: JNLE/JG Jz (f64) 4918f: JNLE/JG Jz (f64)
487# 0x0f 0x90-0x9f 492# 0x0f 0x90-0x9f
48890: SETO Eb 49390: SETO Eb | kmovw/q Vk,Wk | kmovb/d Vk,Wk (66)
48991: SETNO Eb 49491: SETNO Eb | kmovw/q Mv,Vk | kmovb/d Mv,Vk (66)
49092: SETB/C/NAE Eb 49592: SETB/C/NAE Eb | kmovw Vk,Rv | kmovb Vk,Rv (66) | kmovq/d Vk,Rv (F2)
49193: SETAE/NB/NC Eb 49693: SETAE/NB/NC Eb | kmovw Gv,Uk | kmovb Gv,Uk (66) | kmovq/d Gv,Uk (F2)
49294: SETE/Z Eb 49794: SETE/Z Eb
49395: SETNE/NZ Eb 49895: SETNE/NZ Eb
49496: SETBE/NA Eb 49996: SETBE/NA Eb
49597: SETA/NBE Eb 50097: SETA/NBE Eb
49698: SETS Eb 50198: SETS Eb | kortestw/q Vk,Uk | kortestb/d Vk,Uk (66)
49799: SETNS Eb 50299: SETNS Eb | ktestw/q Vk,Uk | ktestb/d Vk,Uk (66)
4989a: SETP/PE Eb 5039a: SETP/PE Eb
4999b: SETNP/PO Eb 5049b: SETNP/PO Eb
5009c: SETL/NGE Eb 5059c: SETL/NGE Eb
@@ -564,11 +569,11 @@ d7: pmovmskb Gd,Nq | vpmovmskb Gd,Ux (66),(v1)
564d8: psubusb Pq,Qq | vpsubusb Vx,Hx,Wx (66),(v1) 569d8: psubusb Pq,Qq | vpsubusb Vx,Hx,Wx (66),(v1)
565d9: psubusw Pq,Qq | vpsubusw Vx,Hx,Wx (66),(v1) 570d9: psubusw Pq,Qq | vpsubusw Vx,Hx,Wx (66),(v1)
566da: pminub Pq,Qq | vpminub Vx,Hx,Wx (66),(v1) 571da: pminub Pq,Qq | vpminub Vx,Hx,Wx (66),(v1)
567db: pand Pq,Qq | vpand Vx,Hx,Wx (66),(v1) 572db: pand Pq,Qq | vpand Vx,Hx,Wx (66),(v1) | vpandd/q Vx,Hx,Wx (66),(evo)
568dc: paddusb Pq,Qq | vpaddusb Vx,Hx,Wx (66),(v1) 573dc: paddusb Pq,Qq | vpaddusb Vx,Hx,Wx (66),(v1)
569dd: paddusw Pq,Qq | vpaddusw Vx,Hx,Wx (66),(v1) 574dd: paddusw Pq,Qq | vpaddusw Vx,Hx,Wx (66),(v1)
570de: pmaxub Pq,Qq | vpmaxub Vx,Hx,Wx (66),(v1) 575de: pmaxub Pq,Qq | vpmaxub Vx,Hx,Wx (66),(v1)
571df: pandn Pq,Qq | vpandn Vx,Hx,Wx (66),(v1) 576df: pandn Pq,Qq | vpandn Vx,Hx,Wx (66),(v1) | vpandnd/q Vx,Hx,Wx (66),(evo)
572# 0x0f 0xe0-0xef 577# 0x0f 0xe0-0xef
573e0: pavgb Pq,Qq | vpavgb Vx,Hx,Wx (66),(v1) 578e0: pavgb Pq,Qq | vpavgb Vx,Hx,Wx (66),(v1)
574e1: psraw Pq,Qq | vpsraw Vx,Hx,Wx (66),(v1) 579e1: psraw Pq,Qq | vpsraw Vx,Hx,Wx (66),(v1)
@@ -576,16 +581,16 @@ e2: psrad Pq,Qq | vpsrad Vx,Hx,Wx (66),(v1)
576e3: pavgw Pq,Qq | vpavgw Vx,Hx,Wx (66),(v1) 581e3: pavgw Pq,Qq | vpavgw Vx,Hx,Wx (66),(v1)
577e4: pmulhuw Pq,Qq | vpmulhuw Vx,Hx,Wx (66),(v1) 582e4: pmulhuw Pq,Qq | vpmulhuw Vx,Hx,Wx (66),(v1)
578e5: pmulhw Pq,Qq | vpmulhw Vx,Hx,Wx (66),(v1) 583e5: pmulhw Pq,Qq | vpmulhw Vx,Hx,Wx (66),(v1)
579e6: vcvttpd2dq Vx,Wpd (66) | vcvtdq2pd Vx,Wdq (F3) | vcvtpd2dq Vx,Wpd (F2) 584e6: vcvttpd2dq Vx,Wpd (66) | vcvtdq2pd Vx,Wdq (F3) | vcvtdq2pd/qq2pd Vx,Wdq (F3),(evo) | vcvtpd2dq Vx,Wpd (F2)
580e7: movntq Mq,Pq | vmovntdq Mx,Vx (66) 585e7: movntq Mq,Pq | vmovntdq Mx,Vx (66)
581e8: psubsb Pq,Qq | vpsubsb Vx,Hx,Wx (66),(v1) 586e8: psubsb Pq,Qq | vpsubsb Vx,Hx,Wx (66),(v1)
582e9: psubsw Pq,Qq | vpsubsw Vx,Hx,Wx (66),(v1) 587e9: psubsw Pq,Qq | vpsubsw Vx,Hx,Wx (66),(v1)
583ea: pminsw Pq,Qq | vpminsw Vx,Hx,Wx (66),(v1) 588ea: pminsw Pq,Qq | vpminsw Vx,Hx,Wx (66),(v1)
584eb: por Pq,Qq | vpor Vx,Hx,Wx (66),(v1) 589eb: por Pq,Qq | vpor Vx,Hx,Wx (66),(v1) | vpord/q Vx,Hx,Wx (66),(evo)
585ec: paddsb Pq,Qq | vpaddsb Vx,Hx,Wx (66),(v1) 590ec: paddsb Pq,Qq | vpaddsb Vx,Hx,Wx (66),(v1)
586ed: paddsw Pq,Qq | vpaddsw Vx,Hx,Wx (66),(v1) 591ed: paddsw Pq,Qq | vpaddsw Vx,Hx,Wx (66),(v1)
587ee: pmaxsw Pq,Qq | vpmaxsw Vx,Hx,Wx (66),(v1) 592ee: pmaxsw Pq,Qq | vpmaxsw Vx,Hx,Wx (66),(v1)
588ef: pxor Pq,Qq | vpxor Vx,Hx,Wx (66),(v1) 593ef: pxor Pq,Qq | vpxor Vx,Hx,Wx (66),(v1) | vpxord/q Vx,Hx,Wx (66),(evo)
589# 0x0f 0xf0-0xff 594# 0x0f 0xf0-0xff
590f0: vlddqu Vx,Mx (F2) 595f0: vlddqu Vx,Mx (F2)
591f1: psllw Pq,Qq | vpsllw Vx,Hx,Wx (66),(v1) 596f1: psllw Pq,Qq | vpsllw Vx,Hx,Wx (66),(v1)
@@ -626,81 +631,105 @@ AVXcode: 2
6260e: vtestps Vx,Wx (66),(v) 6310e: vtestps Vx,Wx (66),(v)
6270f: vtestpd Vx,Wx (66),(v) 6320f: vtestpd Vx,Wx (66),(v)
628# 0x0f 0x38 0x10-0x1f 633# 0x0f 0x38 0x10-0x1f
62910: pblendvb Vdq,Wdq (66) 63410: pblendvb Vdq,Wdq (66) | vpsrlvw Vx,Hx,Wx (66),(evo) | vpmovuswb Wx,Vx (F3),(ev)
63011: 63511: vpmovusdb Wx,Vd (F3),(ev) | vpsravw Vx,Hx,Wx (66),(ev)
63112: 63612: vpmovusqb Wx,Vq (F3),(ev) | vpsllvw Vx,Hx,Wx (66),(ev)
63213: vcvtph2ps Vx,Wx,Ib (66),(v) 63713: vcvtph2ps Vx,Wx (66),(v) | vpmovusdw Wx,Vd (F3),(ev)
63314: blendvps Vdq,Wdq (66) 63814: blendvps Vdq,Wdq (66) | vpmovusqw Wx,Vq (F3),(ev) | vprorvd/q Vx,Hx,Wx (66),(evo)
63415: blendvpd Vdq,Wdq (66) 63915: blendvpd Vdq,Wdq (66) | vpmovusqd Wx,Vq (F3),(ev) | vprolvd/q Vx,Hx,Wx (66),(evo)
63516: vpermps Vqq,Hqq,Wqq (66),(v) 64016: vpermps Vqq,Hqq,Wqq (66),(v) | vpermps/d Vqq,Hqq,Wqq (66),(evo)
63617: vptest Vx,Wx (66) 64117: vptest Vx,Wx (66)
63718: vbroadcastss Vx,Wd (66),(v) 64218: vbroadcastss Vx,Wd (66),(v)
63819: vbroadcastsd Vqq,Wq (66),(v) 64319: vbroadcastsd Vqq,Wq (66),(v) | vbroadcastf32x2 Vqq,Wq (66),(evo)
6391a: vbroadcastf128 Vqq,Mdq (66),(v) 6441a: vbroadcastf128 Vqq,Mdq (66),(v) | vbroadcastf32x4/64x2 Vqq,Wq (66),(evo)
6401b: 6451b: vbroadcastf32x8/64x4 Vqq,Mdq (66),(ev)
6411c: pabsb Pq,Qq | vpabsb Vx,Wx (66),(v1) 6461c: pabsb Pq,Qq | vpabsb Vx,Wx (66),(v1)
6421d: pabsw Pq,Qq | vpabsw Vx,Wx (66),(v1) 6471d: pabsw Pq,Qq | vpabsw Vx,Wx (66),(v1)
6431e: pabsd Pq,Qq | vpabsd Vx,Wx (66),(v1) 6481e: pabsd Pq,Qq | vpabsd Vx,Wx (66),(v1)
6441f: 6491f: vpabsq Vx,Wx (66),(ev)
645# 0x0f 0x38 0x20-0x2f 650# 0x0f 0x38 0x20-0x2f
64620: vpmovsxbw Vx,Ux/Mq (66),(v1) 65120: vpmovsxbw Vx,Ux/Mq (66),(v1) | vpmovswb Wx,Vx (F3),(ev)
64721: vpmovsxbd Vx,Ux/Md (66),(v1) 65221: vpmovsxbd Vx,Ux/Md (66),(v1) | vpmovsdb Wx,Vd (F3),(ev)
64822: vpmovsxbq Vx,Ux/Mw (66),(v1) 65322: vpmovsxbq Vx,Ux/Mw (66),(v1) | vpmovsqb Wx,Vq (F3),(ev)
64923: vpmovsxwd Vx,Ux/Mq (66),(v1) 65423: vpmovsxwd Vx,Ux/Mq (66),(v1) | vpmovsdw Wx,Vd (F3),(ev)
65024: vpmovsxwq Vx,Ux/Md (66),(v1) 65524: vpmovsxwq Vx,Ux/Md (66),(v1) | vpmovsqw Wx,Vq (F3),(ev)
65125: vpmovsxdq Vx,Ux/Mq (66),(v1) 65625: vpmovsxdq Vx,Ux/Mq (66),(v1) | vpmovsqd Wx,Vq (F3),(ev)
65226: 65726: vptestmb/w Vk,Hx,Wx (66),(ev) | vptestnmb/w Vk,Hx,Wx (F3),(ev)
65327: 65827: vptestmd/q Vk,Hx,Wx (66),(ev) | vptestnmd/q Vk,Hx,Wx (F3),(ev)
65428: vpmuldq Vx,Hx,Wx (66),(v1) 65928: vpmuldq Vx,Hx,Wx (66),(v1) | vpmovm2b/w Vx,Uk (F3),(ev)
65529: vpcmpeqq Vx,Hx,Wx (66),(v1) 66029: vpcmpeqq Vx,Hx,Wx (66),(v1) | vpmovb2m/w2m Vk,Ux (F3),(ev)
6562a: vmovntdqa Vx,Mx (66),(v1) 6612a: vmovntdqa Vx,Mx (66),(v1) | vpbroadcastmb2q Vx,Uk (F3),(ev)
6572b: vpackusdw Vx,Hx,Wx (66),(v1) 6622b: vpackusdw Vx,Hx,Wx (66),(v1)
6582c: vmaskmovps Vx,Hx,Mx (66),(v) 6632c: vmaskmovps Vx,Hx,Mx (66),(v) | vscalefps/d Vx,Hx,Wx (66),(evo)
6592d: vmaskmovpd Vx,Hx,Mx (66),(v) 6642d: vmaskmovpd Vx,Hx,Mx (66),(v) | vscalefss/d Vx,Hx,Wx (66),(evo)
6602e: vmaskmovps Mx,Hx,Vx (66),(v) 6652e: vmaskmovps Mx,Hx,Vx (66),(v)
6612f: vmaskmovpd Mx,Hx,Vx (66),(v) 6662f: vmaskmovpd Mx,Hx,Vx (66),(v)
662# 0x0f 0x38 0x30-0x3f 667# 0x0f 0x38 0x30-0x3f
66330: vpmovzxbw Vx,Ux/Mq (66),(v1) 66830: vpmovzxbw Vx,Ux/Mq (66),(v1) | vpmovwb Wx,Vx (F3),(ev)
66431: vpmovzxbd Vx,Ux/Md (66),(v1) 66931: vpmovzxbd Vx,Ux/Md (66),(v1) | vpmovdb Wx,Vd (F3),(ev)
66532: vpmovzxbq Vx,Ux/Mw (66),(v1) 67032: vpmovzxbq Vx,Ux/Mw (66),(v1) | vpmovqb Wx,Vq (F3),(ev)
66633: vpmovzxwd Vx,Ux/Mq (66),(v1) 67133: vpmovzxwd Vx,Ux/Mq (66),(v1) | vpmovdw Wx,Vd (F3),(ev)
66734: vpmovzxwq Vx,Ux/Md (66),(v1) 67234: vpmovzxwq Vx,Ux/Md (66),(v1) | vpmovqw Wx,Vq (F3),(ev)
66835: vpmovzxdq Vx,Ux/Mq (66),(v1) 67335: vpmovzxdq Vx,Ux/Mq (66),(v1) | vpmovqd Wx,Vq (F3),(ev)
66936: vpermd Vqq,Hqq,Wqq (66),(v) 67436: vpermd Vqq,Hqq,Wqq (66),(v) | vpermd/q Vqq,Hqq,Wqq (66),(evo)
67037: vpcmpgtq Vx,Hx,Wx (66),(v1) 67537: vpcmpgtq Vx,Hx,Wx (66),(v1)
67138: vpminsb Vx,Hx,Wx (66),(v1) 67638: vpminsb Vx,Hx,Wx (66),(v1) | vpmovm2d/q Vx,Uk (F3),(ev)
67239: vpminsd Vx,Hx,Wx (66),(v1) 67739: vpminsd Vx,Hx,Wx (66),(v1) | vpminsd/q Vx,Hx,Wx (66),(evo) | vpmovd2m/q2m Vk,Ux (F3),(ev)
6733a: vpminuw Vx,Hx,Wx (66),(v1) 6783a: vpminuw Vx,Hx,Wx (66),(v1) | vpbroadcastmw2d Vx,Uk (F3),(ev)
6743b: vpminud Vx,Hx,Wx (66),(v1) 6793b: vpminud Vx,Hx,Wx (66),(v1) | vpminud/q Vx,Hx,Wx (66),(evo)
6753c: vpmaxsb Vx,Hx,Wx (66),(v1) 6803c: vpmaxsb Vx,Hx,Wx (66),(v1)
6763d: vpmaxsd Vx,Hx,Wx (66),(v1) 6813d: vpmaxsd Vx,Hx,Wx (66),(v1) | vpmaxsd/q Vx,Hx,Wx (66),(evo)
6773e: vpmaxuw Vx,Hx,Wx (66),(v1) 6823e: vpmaxuw Vx,Hx,Wx (66),(v1)
6783f: vpmaxud Vx,Hx,Wx (66),(v1) 6833f: vpmaxud Vx,Hx,Wx (66),(v1) | vpmaxud/q Vx,Hx,Wx (66),(evo)
679# 0x0f 0x38 0x40-0x8f 684# 0x0f 0x38 0x40-0x8f
68040: vpmulld Vx,Hx,Wx (66),(v1) 68540: vpmulld Vx,Hx,Wx (66),(v1) | vpmulld/q Vx,Hx,Wx (66),(evo)
68141: vphminposuw Vdq,Wdq (66),(v1) 68641: vphminposuw Vdq,Wdq (66),(v1)
68242: 68742: vgetexpps/d Vx,Wx (66),(ev)
68343: 68843: vgetexpss/d Vx,Hx,Wx (66),(ev)
68444: 68944: vplzcntd/q Vx,Wx (66),(ev)
68545: vpsrlvd/q Vx,Hx,Wx (66),(v) 69045: vpsrlvd/q Vx,Hx,Wx (66),(v)
68646: vpsravd Vx,Hx,Wx (66),(v) 69146: vpsravd Vx,Hx,Wx (66),(v) | vpsravd/q Vx,Hx,Wx (66),(evo)
68747: vpsllvd/q Vx,Hx,Wx (66),(v) 69247: vpsllvd/q Vx,Hx,Wx (66),(v)
688# Skip 0x48-0x57 693# Skip 0x48-0x4b
6944c: vrcp14ps/d Vpd,Wpd (66),(ev)
6954d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev)
6964e: vrsqrt14ps/d Vpd,Wpd (66),(ev)
6974f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev)
698# Skip 0x50-0x57
68958: vpbroadcastd Vx,Wx (66),(v) 69958: vpbroadcastd Vx,Wx (66),(v)
69059: vpbroadcastq Vx,Wx (66),(v) 70059: vpbroadcastq Vx,Wx (66),(v) | vbroadcasti32x2 Vx,Wx (66),(evo)
6915a: vbroadcasti128 Vqq,Mdq (66),(v) 7015a: vbroadcasti128 Vqq,Mdq (66),(v) | vbroadcasti32x4/64x2 Vx,Wx (66),(evo)
692# Skip 0x5b-0x77 7025b: vbroadcasti32x8/64x4 Vqq,Mdq (66),(ev)
703# Skip 0x5c-0x63
70464: vpblendmd/q Vx,Hx,Wx (66),(ev)
70565: vblendmps/d Vx,Hx,Wx (66),(ev)
70666: vpblendmb/w Vx,Hx,Wx (66),(ev)
707# Skip 0x67-0x74
70875: vpermi2b/w Vx,Hx,Wx (66),(ev)
70976: vpermi2d/q Vx,Hx,Wx (66),(ev)
71077: vpermi2ps/d Vx,Hx,Wx (66),(ev)
69378: vpbroadcastb Vx,Wx (66),(v) 71178: vpbroadcastb Vx,Wx (66),(v)
69479: vpbroadcastw Vx,Wx (66),(v) 71279: vpbroadcastw Vx,Wx (66),(v)
695# Skip 0x7a-0x7f 7137a: vpbroadcastb Vx,Rv (66),(ev)
7147b: vpbroadcastw Vx,Rv (66),(ev)
7157c: vpbroadcastd/q Vx,Rv (66),(ev)
7167d: vpermt2b/w Vx,Hx,Wx (66),(ev)
7177e: vpermt2d/q Vx,Hx,Wx (66),(ev)
7187f: vpermt2ps/d Vx,Hx,Wx (66),(ev)
69680: INVEPT Gy,Mdq (66) 71980: INVEPT Gy,Mdq (66)
69781: INVPID Gy,Mdq (66) 72081: INVPID Gy,Mdq (66)
69882: INVPCID Gy,Mdq (66) 72182: INVPCID Gy,Mdq (66)
72283: vpmultishiftqb Vx,Hx,Wx (66),(ev)
72388: vexpandps/d Vpd,Wpd (66),(ev)
72489: vpexpandd/q Vx,Wx (66),(ev)
7258a: vcompressps/d Wx,Vx (66),(ev)
7268b: vpcompressd/q Wx,Vx (66),(ev)
6998c: vpmaskmovd/q Vx,Hx,Mx (66),(v) 7278c: vpmaskmovd/q Vx,Hx,Mx (66),(v)
7288d: vpermb/w Vx,Hx,Wx (66),(ev)
7008e: vpmaskmovd/q Mx,Vx,Hx (66),(v) 7298e: vpmaskmovd/q Mx,Vx,Hx (66),(v)
701# 0x0f 0x38 0x90-0xbf (FMA) 730# 0x0f 0x38 0x90-0xbf (FMA)
70290: vgatherdd/q Vx,Hx,Wx (66),(v) 73190: vgatherdd/q Vx,Hx,Wx (66),(v) | vpgatherdd/q Vx,Wx (66),(evo)
70391: vgatherqd/q Vx,Hx,Wx (66),(v) 73291: vgatherqd/q Vx,Hx,Wx (66),(v) | vpgatherqd/q Vx,Wx (66),(evo)
70492: vgatherdps/d Vx,Hx,Wx (66),(v) 73392: vgatherdps/d Vx,Hx,Wx (66),(v)
70593: vgatherqps/d Vx,Hx,Wx (66),(v) 73493: vgatherqps/d Vx,Hx,Wx (66),(v)
70694: 73594:
@@ -715,6 +744,10 @@ AVXcode: 2
7159d: vfnmadd132ss/d Vx,Hx,Wx (66),(v),(v1) 7449d: vfnmadd132ss/d Vx,Hx,Wx (66),(v),(v1)
7169e: vfnmsub132ps/d Vx,Hx,Wx (66),(v) 7459e: vfnmsub132ps/d Vx,Hx,Wx (66),(v)
7179f: vfnmsub132ss/d Vx,Hx,Wx (66),(v),(v1) 7469f: vfnmsub132ss/d Vx,Hx,Wx (66),(v),(v1)
747a0: vpscatterdd/q Wx,Vx (66),(ev)
748a1: vpscatterqd/q Wx,Vx (66),(ev)
749a2: vscatterdps/d Wx,Vx (66),(ev)
750a3: vscatterqps/d Wx,Vx (66),(ev)
718a6: vfmaddsub213ps/d Vx,Hx,Wx (66),(v) 751a6: vfmaddsub213ps/d Vx,Hx,Wx (66),(v)
719a7: vfmsubadd213ps/d Vx,Hx,Wx (66),(v) 752a7: vfmsubadd213ps/d Vx,Hx,Wx (66),(v)
720a8: vfmadd213ps/d Vx,Hx,Wx (66),(v) 753a8: vfmadd213ps/d Vx,Hx,Wx (66),(v)
@@ -725,6 +758,8 @@ ac: vfnmadd213ps/d Vx,Hx,Wx (66),(v)
725ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1) 758ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1)
726ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v) 759ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v)
727af: vfnmsub213ss/d Vx,Hx,Wx (66),(v),(v1) 760af: vfnmsub213ss/d Vx,Hx,Wx (66),(v),(v1)
761b4: vpmadd52luq Vx,Hx,Wx (66),(ev)
762b5: vpmadd52huq Vx,Hx,Wx (66),(ev)
728b6: vfmaddsub231ps/d Vx,Hx,Wx (66),(v) 763b6: vfmaddsub231ps/d Vx,Hx,Wx (66),(v)
729b7: vfmsubadd231ps/d Vx,Hx,Wx (66),(v) 764b7: vfmsubadd231ps/d Vx,Hx,Wx (66),(v)
730b8: vfmadd231ps/d Vx,Hx,Wx (66),(v) 765b8: vfmadd231ps/d Vx,Hx,Wx (66),(v)
@@ -736,12 +771,15 @@ bd: vfnmadd231ss/d Vx,Hx,Wx (66),(v),(v1)
736be: vfnmsub231ps/d Vx,Hx,Wx (66),(v) 771be: vfnmsub231ps/d Vx,Hx,Wx (66),(v)
737bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1) 772bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1)
738# 0x0f 0x38 0xc0-0xff 773# 0x0f 0x38 0xc0-0xff
739c8: sha1nexte Vdq,Wdq 774c4: vpconflictd/q Vx,Wx (66),(ev)
775c6: Grp18 (1A)
776c7: Grp19 (1A)
777c8: sha1nexte Vdq,Wdq | vexp2ps/d Vx,Wx (66),(ev)
740c9: sha1msg1 Vdq,Wdq 778c9: sha1msg1 Vdq,Wdq
741ca: sha1msg2 Vdq,Wdq 779ca: sha1msg2 Vdq,Wdq | vrcp28ps/d Vx,Wx (66),(ev)
742cb: sha256rnds2 Vdq,Wdq 780cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev)
743cc: sha256msg1 Vdq,Wdq 781cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev)
744cd: sha256msg2 Vdq,Wdq 782cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev)
745db: VAESIMC Vdq,Wdq (66),(v1) 783db: VAESIMC Vdq,Wdq (66),(v1)
746dc: VAESENC Vdq,Hdq,Wdq (66),(v1) 784dc: VAESENC Vdq,Hdq,Wdq (66),(v1)
747dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1) 785dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1)
@@ -763,15 +801,15 @@ AVXcode: 3
76300: vpermq Vqq,Wqq,Ib (66),(v) 80100: vpermq Vqq,Wqq,Ib (66),(v)
76401: vpermpd Vqq,Wqq,Ib (66),(v) 80201: vpermpd Vqq,Wqq,Ib (66),(v)
76502: vpblendd Vx,Hx,Wx,Ib (66),(v) 80302: vpblendd Vx,Hx,Wx,Ib (66),(v)
76603: 80403: valignd/q Vx,Hx,Wx,Ib (66),(ev)
76704: vpermilps Vx,Wx,Ib (66),(v) 80504: vpermilps Vx,Wx,Ib (66),(v)
76805: vpermilpd Vx,Wx,Ib (66),(v) 80605: vpermilpd Vx,Wx,Ib (66),(v)
76906: vperm2f128 Vqq,Hqq,Wqq,Ib (66),(v) 80706: vperm2f128 Vqq,Hqq,Wqq,Ib (66),(v)
77007: 80807:
77108: vroundps Vx,Wx,Ib (66) 80908: vroundps Vx,Wx,Ib (66) | vrndscaleps Vx,Wx,Ib (66),(evo)
77209: vroundpd Vx,Wx,Ib (66) 81009: vroundpd Vx,Wx,Ib (66) | vrndscalepd Vx,Wx,Ib (66),(evo)
7730a: vroundss Vss,Wss,Ib (66),(v1) 8110a: vroundss Vss,Wss,Ib (66),(v1) | vrndscaless Vx,Hx,Wx,Ib (66),(evo)
7740b: vroundsd Vsd,Wsd,Ib (66),(v1) 8120b: vroundsd Vsd,Wsd,Ib (66),(v1) | vrndscalesd Vx,Hx,Wx,Ib (66),(evo)
7750c: vblendps Vx,Hx,Wx,Ib (66) 8130c: vblendps Vx,Hx,Wx,Ib (66)
7760d: vblendpd Vx,Hx,Wx,Ib (66) 8140d: vblendpd Vx,Hx,Wx,Ib (66)
7770e: vpblendw Vx,Hx,Wx,Ib (66),(v1) 8150e: vpblendw Vx,Hx,Wx,Ib (66),(v1)
@@ -780,26 +818,51 @@ AVXcode: 3
78015: vpextrw Rd/Mw,Vdq,Ib (66),(v1) 81815: vpextrw Rd/Mw,Vdq,Ib (66),(v1)
78116: vpextrd/q Ey,Vdq,Ib (66),(v1) 81916: vpextrd/q Ey,Vdq,Ib (66),(v1)
78217: vextractps Ed,Vdq,Ib (66),(v1) 82017: vextractps Ed,Vdq,Ib (66),(v1)
78318: vinsertf128 Vqq,Hqq,Wqq,Ib (66),(v) 82118: vinsertf128 Vqq,Hqq,Wqq,Ib (66),(v) | vinsertf32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo)
78419: vextractf128 Wdq,Vqq,Ib (66),(v) 82219: vextractf128 Wdq,Vqq,Ib (66),(v) | vextractf32x4/64x2 Wdq,Vqq,Ib (66),(evo)
8231a: vinsertf32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev)
8241b: vextractf32x8/64x4 Wdq,Vqq,Ib (66),(ev)
7851d: vcvtps2ph Wx,Vx,Ib (66),(v) 8251d: vcvtps2ph Wx,Vx,Ib (66),(v)
8261e: vpcmpud/q Vk,Hd,Wd,Ib (66),(ev)
8271f: vpcmpd/q Vk,Hd,Wd,Ib (66),(ev)
78620: vpinsrb Vdq,Hdq,Ry/Mb,Ib (66),(v1) 82820: vpinsrb Vdq,Hdq,Ry/Mb,Ib (66),(v1)
78721: vinsertps Vdq,Hdq,Udq/Md,Ib (66),(v1) 82921: vinsertps Vdq,Hdq,Udq/Md,Ib (66),(v1)
78822: vpinsrd/q Vdq,Hdq,Ey,Ib (66),(v1) 83022: vpinsrd/q Vdq,Hdq,Ey,Ib (66),(v1)
78938: vinserti128 Vqq,Hqq,Wqq,Ib (66),(v) 83123: vshuff32x4/64x2 Vx,Hx,Wx,Ib (66),(ev)
79039: vextracti128 Wdq,Vqq,Ib (66),(v) 83225: vpternlogd/q Vx,Hx,Wx,Ib (66),(ev)
83326: vgetmantps/d Vx,Wx,Ib (66),(ev)
83427: vgetmantss/d Vx,Hx,Wx,Ib (66),(ev)
83530: kshiftrb/w Vk,Uk,Ib (66),(v)
83631: kshiftrd/q Vk,Uk,Ib (66),(v)
83732: kshiftlb/w Vk,Uk,Ib (66),(v)
83833: kshiftld/q Vk,Uk,Ib (66),(v)
83938: vinserti128 Vqq,Hqq,Wqq,Ib (66),(v) | vinserti32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo)
84039: vextracti128 Wdq,Vqq,Ib (66),(v) | vextracti32x4/64x2 Wdq,Vqq,Ib (66),(evo)
8413a: vinserti32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev)
8423b: vextracti32x8/64x4 Wdq,Vqq,Ib (66),(ev)
8433e: vpcmpub/w Vk,Hk,Wx,Ib (66),(ev)
8443f: vpcmpb/w Vk,Hk,Wx,Ib (66),(ev)
79140: vdpps Vx,Hx,Wx,Ib (66) 84540: vdpps Vx,Hx,Wx,Ib (66)
79241: vdppd Vdq,Hdq,Wdq,Ib (66),(v1) 84641: vdppd Vdq,Hdq,Wdq,Ib (66),(v1)
79342: vmpsadbw Vx,Hx,Wx,Ib (66),(v1) 84742: vmpsadbw Vx,Hx,Wx,Ib (66),(v1) | vdbpsadbw Vx,Hx,Wx,Ib (66),(evo)
84843: vshufi32x4/64x2 Vx,Hx,Wx,Ib (66),(ev)
79444: vpclmulqdq Vdq,Hdq,Wdq,Ib (66),(v1) 84944: vpclmulqdq Vdq,Hdq,Wdq,Ib (66),(v1)
79546: vperm2i128 Vqq,Hqq,Wqq,Ib (66),(v) 85046: vperm2i128 Vqq,Hqq,Wqq,Ib (66),(v)
7964a: vblendvps Vx,Hx,Wx,Lx (66),(v) 8514a: vblendvps Vx,Hx,Wx,Lx (66),(v)
7974b: vblendvpd Vx,Hx,Wx,Lx (66),(v) 8524b: vblendvpd Vx,Hx,Wx,Lx (66),(v)
7984c: vpblendvb Vx,Hx,Wx,Lx (66),(v1) 8534c: vpblendvb Vx,Hx,Wx,Lx (66),(v1)
85450: vrangeps/d Vx,Hx,Wx,Ib (66),(ev)
85551: vrangess/d Vx,Hx,Wx,Ib (66),(ev)
85654: vfixupimmps/d Vx,Hx,Wx,Ib (66),(ev)
85755: vfixupimmss/d Vx,Hx,Wx,Ib (66),(ev)
85856: vreduceps/d Vx,Wx,Ib (66),(ev)
85957: vreducess/d Vx,Hx,Wx,Ib (66),(ev)
79960: vpcmpestrm Vdq,Wdq,Ib (66),(v1) 86060: vpcmpestrm Vdq,Wdq,Ib (66),(v1)
80061: vpcmpestri Vdq,Wdq,Ib (66),(v1) 86161: vpcmpestri Vdq,Wdq,Ib (66),(v1)
80162: vpcmpistrm Vdq,Wdq,Ib (66),(v1) 86262: vpcmpistrm Vdq,Wdq,Ib (66),(v1)
80263: vpcmpistri Vdq,Wdq,Ib (66),(v1) 86363: vpcmpistri Vdq,Wdq,Ib (66),(v1)
86466: vfpclassps/d Vk,Wx,Ib (66),(ev)
86567: vfpclassss/d Vk,Wx,Ib (66),(ev)
803cc: sha1rnds4 Vdq,Wdq,Ib 866cc: sha1rnds4 Vdq,Wdq,Ib
804df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1) 867df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1)
805f0: RORX Gy,Ey,Ib (F2),(v) 868f0: RORX Gy,Ey,Ib (F2),(v)
@@ -927,8 +990,10 @@ GrpTable: Grp12
927EndTable 990EndTable
928 991
929GrpTable: Grp13 992GrpTable: Grp13
9930: vprord/q Hx,Wx,Ib (66),(ev)
9941: vprold/q Hx,Wx,Ib (66),(ev)
9302: psrld Nq,Ib (11B) | vpsrld Hx,Ux,Ib (66),(11B),(v1) 9952: psrld Nq,Ib (11B) | vpsrld Hx,Ux,Ib (66),(11B),(v1)
9314: psrad Nq,Ib (11B) | vpsrad Hx,Ux,Ib (66),(11B),(v1) 9964: psrad Nq,Ib (11B) | vpsrad Hx,Ux,Ib (66),(11B),(v1) | vpsrad/q Hx,Ux,Ib (66),(evo)
9326: pslld Nq,Ib (11B) | vpslld Hx,Ux,Ib (66),(11B),(v1) 9976: pslld Nq,Ib (11B) | vpslld Hx,Ux,Ib (66),(11B),(v1)
933EndTable 998EndTable
934 999
@@ -947,7 +1012,7 @@ GrpTable: Grp15
9474: XSAVE 10124: XSAVE
9485: XRSTOR | lfence (11B) 10135: XRSTOR | lfence (11B)
9496: XSAVEOPT | clwb (66) | mfence (11B) 10146: XSAVEOPT | clwb (66) | mfence (11B)
9507: clflush | clflushopt (66) | sfence (11B) | pcommit (66),(11B) 10157: clflush | clflushopt (66) | sfence (11B)
951EndTable 1016EndTable
952 1017
953GrpTable: Grp16 1018GrpTable: Grp16
@@ -963,6 +1028,20 @@ GrpTable: Grp17
9633: BLSI By,Ey (v) 10283: BLSI By,Ey (v)
964EndTable 1029EndTable
965 1030
1031GrpTable: Grp18
10321: vgatherpf0dps/d Wx (66),(ev)
10332: vgatherpf1dps/d Wx (66),(ev)
10345: vscatterpf0dps/d Wx (66),(ev)
10356: vscatterpf1dps/d Wx (66),(ev)
1036EndTable
1037
1038GrpTable: Grp19
10391: vgatherpf0qps/d Wx (66),(ev)
10402: vgatherpf1qps/d Wx (66),(ev)
10415: vscatterpf0qps/d Wx (66),(ev)
10426: vscatterpf1qps/d Wx (66),(ev)
1043EndTable
1044
966# AMD's Prefetch Group 1045# AMD's Prefetch Group
967GrpTable: GrpP 1046GrpTable: GrpP
9680: PREFETCH 10470: PREFETCH
diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
index 17fa7fc34fdf..bd09d0effef8 100644
--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -107,6 +107,12 @@ static struct instruction *next_insn_same_sec(struct objtool_file *file,
107 insn->offset < func->offset + func->len; \ 107 insn->offset < func->offset + func->len; \
108 insn = list_next_entry(insn, list)) 108 insn = list_next_entry(insn, list))
109 109
110#define func_for_each_insn_continue_reverse(file, func, insn) \
111 for (insn = list_prev_entry(insn, list); \
112 &insn->list != &file->insn_list && \
113 insn->sec == func->sec && insn->offset >= func->offset; \
114 insn = list_prev_entry(insn, list))
115
110#define sec_for_each_insn_from(file, insn) \ 116#define sec_for_each_insn_from(file, insn) \
111 for (; insn; insn = next_insn_same_sec(file, insn)) 117 for (; insn; insn = next_insn_same_sec(file, insn))
112 118
@@ -664,65 +670,95 @@ static int add_switch_table(struct objtool_file *file, struct symbol *func,
664 return 0; 670 return 0;
665} 671}
666 672
667static int add_func_switch_tables(struct objtool_file *file, 673/*
668 struct symbol *func) 674 * find_switch_table() - Given a dynamic jump, find the switch jump table in
675 * .rodata associated with it.
676 *
677 * There are 3 basic patterns:
678 *
679 * 1. jmpq *[rodata addr](,%reg,8)
680 *
681 * This is the most common case by far. It jumps to an address in a simple
682 * jump table which is stored in .rodata.
683 *
684 * 2. jmpq *[rodata addr](%rip)
685 *
686 * This is caused by a rare GCC quirk, currently only seen in three driver
687 * functions in the kernel, only with certain obscure non-distro configs.
688 *
689 * As part of an optimization, GCC makes a copy of an existing switch jump
690 * table, modifies it, and then hard-codes the jump (albeit with an indirect
691 * jump) to use a single entry in the table. The rest of the jump table and
692 * some of its jump targets remain as dead code.
693 *
694 * In such a case we can just crudely ignore all unreachable instruction
695 * warnings for the entire object file. Ideally we would just ignore them
696 * for the function, but that would require redesigning the code quite a
697 * bit. And honestly that's just not worth doing: unreachable instruction
698 * warnings are of questionable value anyway, and this is such a rare issue.
699 *
700 * 3. mov [rodata addr],%reg1
701 * ... some instructions ...
702 * jmpq *(%reg1,%reg2,8)
703 *
704 * This is a fairly uncommon pattern which is new for GCC 6. As of this
705 * writing, there are 11 occurrences of it in the allmodconfig kernel.
706 *
707 * TODO: Once we have DWARF CFI and smarter instruction decoding logic,
708 * ensure the same register is used in the mov and jump instructions.
709 */
710static struct rela *find_switch_table(struct objtool_file *file,
711 struct symbol *func,
712 struct instruction *insn)
669{ 713{
670 struct instruction *insn, *prev_jump; 714 struct rela *text_rela, *rodata_rela;
671 struct rela *text_rela, *rodata_rela, *prev_rela = NULL;
672 int ret;
673 715
674 prev_jump = NULL; 716 text_rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len);
717 if (text_rela && text_rela->sym == file->rodata->sym) {
718 /* case 1 */
719 rodata_rela = find_rela_by_dest(file->rodata,
720 text_rela->addend);
721 if (rodata_rela)
722 return rodata_rela;
675 723
676 func_for_each_insn(file, func, insn) { 724 /* case 2 */
677 if (insn->type != INSN_JUMP_DYNAMIC) 725 rodata_rela = find_rela_by_dest(file->rodata,
678 continue; 726 text_rela->addend + 4);
727 if (!rodata_rela)
728 return NULL;
729 file->ignore_unreachables = true;
730 return rodata_rela;
731 }
732
733 /* case 3 */
734 func_for_each_insn_continue_reverse(file, func, insn) {
735 if (insn->type == INSN_JUMP_UNCONDITIONAL ||
736 insn->type == INSN_JUMP_DYNAMIC)
737 break;
679 738
680 text_rela = find_rela_by_dest_range(insn->sec, insn->offset, 739 text_rela = find_rela_by_dest_range(insn->sec, insn->offset,
681 insn->len); 740 insn->len);
682 if (!text_rela || text_rela->sym != file->rodata->sym) 741 if (text_rela && text_rela->sym == file->rodata->sym)
683 continue; 742 return find_rela_by_dest(file->rodata,
743 text_rela->addend);
744 }
684 745
685 /* common case: jmpq *[addr](,%rax,8) */ 746 return NULL;
686 rodata_rela = find_rela_by_dest(file->rodata, 747}
687 text_rela->addend);
688 748
689 /* 749static int add_func_switch_tables(struct objtool_file *file,
690 * rare case: jmpq *[addr](%rip) 750 struct symbol *func)
691 * 751{
692 * This check is for a rare gcc quirk, currently only seen in 752 struct instruction *insn, *prev_jump = NULL;
693 * three driver functions in the kernel, only with certain 753 struct rela *rela, *prev_rela = NULL;
694 * obscure non-distro configs. 754 int ret;
695 *
696 * As part of an optimization, gcc makes a copy of an existing
697 * switch jump table, modifies it, and then hard-codes the jump
698 * (albeit with an indirect jump) to use a single entry in the
699 * table. The rest of the jump table and some of its jump
700 * targets remain as dead code.
701 *
702 * In such a case we can just crudely ignore all unreachable
703 * instruction warnings for the entire object file. Ideally we
704 * would just ignore them for the function, but that would
705 * require redesigning the code quite a bit. And honestly
706 * that's just not worth doing: unreachable instruction
707 * warnings are of questionable value anyway, and this is such
708 * a rare issue.
709 *
710 * kbuild reports:
711 * - https://lkml.kernel.org/r/201603231906.LWcVUpxm%25fengguang.wu@intel.com
712 * - https://lkml.kernel.org/r/201603271114.K9i45biy%25fengguang.wu@intel.com
713 * - https://lkml.kernel.org/r/201603291058.zuJ6ben1%25fengguang.wu@intel.com
714 *
715 * gcc bug:
716 * - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70604
717 */
718 if (!rodata_rela) {
719 rodata_rela = find_rela_by_dest(file->rodata,
720 text_rela->addend + 4);
721 if (rodata_rela)
722 file->ignore_unreachables = true;
723 }
724 755
725 if (!rodata_rela) 756 func_for_each_insn(file, func, insn) {
757 if (insn->type != INSN_JUMP_DYNAMIC)
758 continue;
759
760 rela = find_switch_table(file, func, insn);
761 if (!rela)
726 continue; 762 continue;
727 763
728 /* 764 /*
@@ -732,13 +768,13 @@ static int add_func_switch_tables(struct objtool_file *file,
732 */ 768 */
733 if (prev_jump) { 769 if (prev_jump) {
734 ret = add_switch_table(file, func, prev_jump, prev_rela, 770 ret = add_switch_table(file, func, prev_jump, prev_rela,
735 rodata_rela); 771 rela);
736 if (ret) 772 if (ret)
737 return ret; 773 return ret;
738 } 774 }
739 775
740 prev_jump = insn; 776 prev_jump = insn;
741 prev_rela = rodata_rela; 777 prev_rela = rela;
742 } 778 }
743 779
744 if (prev_jump) { 780 if (prev_jump) {
diff --git a/tools/perf/arch/s390/util/Build b/tools/perf/arch/s390/util/Build
index 8a61372bb47a..5bd7b9260cc0 100644
--- a/tools/perf/arch/s390/util/Build
+++ b/tools/perf/arch/s390/util/Build
@@ -2,3 +2,5 @@ libperf-y += header.o
2libperf-y += kvm-stat.o 2libperf-y += kvm-stat.o
3 3
4libperf-$(CONFIG_DWARF) += dwarf-regs.o 4libperf-$(CONFIG_DWARF) += dwarf-regs.o
5
6libperf-y += machine.o
diff --git a/tools/perf/arch/s390/util/machine.c b/tools/perf/arch/s390/util/machine.c
new file mode 100644
index 000000000000..b9a95a1a8e69
--- /dev/null
+++ b/tools/perf/arch/s390/util/machine.c
@@ -0,0 +1,19 @@
1#include <unistd.h>
2#include <stdio.h>
3#include <string.h>
4#include "util.h"
5#include "machine.h"
6#include "api/fs/fs.h"
7
8int arch__fix_module_text_start(u64 *start, const char *name)
9{
10 char path[PATH_MAX];
11
12 snprintf(path, PATH_MAX, "module/%.*s/sections/.text",
13 (int)strlen(name) - 2, name + 1);
14
15 if (sysfs__read_ull(path, (unsigned long long *)start) < 0)
16 return -1;
17
18 return 0;
19}
diff --git a/tools/perf/arch/x86/tests/insn-x86-dat-32.c b/tools/perf/arch/x86/tests/insn-x86-dat-32.c
index 3918dd52e903..0f196eec9f48 100644
--- a/tools/perf/arch/x86/tests/insn-x86-dat-32.c
+++ b/tools/perf/arch/x86/tests/insn-x86-dat-32.c
@@ -1664,5 +1664,3 @@
1664"0f c7 1d 78 56 34 12 \txrstors 0x12345678",}, 1664"0f c7 1d 78 56 34 12 \txrstors 0x12345678",},
1665{{0x0f, 0xc7, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "", 1665{{0x0f, 0xc7, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
1666"0f c7 9c c8 78 56 34 12 \txrstors 0x12345678(%eax,%ecx,8)",}, 1666"0f c7 9c c8 78 56 34 12 \txrstors 0x12345678(%eax,%ecx,8)",},
1667{{0x66, 0x0f, 0xae, 0xf8, }, 4, 0, "", "",
1668"66 0f ae f8 \tpcommit ",},
diff --git a/tools/perf/arch/x86/tests/insn-x86-dat-64.c b/tools/perf/arch/x86/tests/insn-x86-dat-64.c
index 9c8c61e06d5a..af25bc8240d0 100644
--- a/tools/perf/arch/x86/tests/insn-x86-dat-64.c
+++ b/tools/perf/arch/x86/tests/insn-x86-dat-64.c
@@ -1696,5 +1696,3 @@
1696"0f c7 9c c8 78 56 34 12 \txrstors 0x12345678(%rax,%rcx,8)",}, 1696"0f c7 9c c8 78 56 34 12 \txrstors 0x12345678(%rax,%rcx,8)",},
1697{{0x41, 0x0f, 0xc7, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "", 1697{{0x41, 0x0f, 0xc7, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
1698"41 0f c7 9c c8 78 56 34 12 \txrstors 0x12345678(%r8,%rcx,8)",}, 1698"41 0f c7 9c c8 78 56 34 12 \txrstors 0x12345678(%r8,%rcx,8)",},
1699{{0x66, 0x0f, 0xae, 0xf8, }, 4, 0, "", "",
1700"66 0f ae f8 \tpcommit ",},
diff --git a/tools/perf/arch/x86/tests/insn-x86-dat-src.c b/tools/perf/arch/x86/tests/insn-x86-dat-src.c
index 76e0ec379c8b..979487dae8d4 100644
--- a/tools/perf/arch/x86/tests/insn-x86-dat-src.c
+++ b/tools/perf/arch/x86/tests/insn-x86-dat-src.c
@@ -2655,10 +2655,6 @@ int main(void)
2655 2655
2656#endif /* #ifndef __x86_64__ */ 2656#endif /* #ifndef __x86_64__ */
2657 2657
2658 /* pcommit */
2659
2660 asm volatile("pcommit");
2661
2662 /* Following line is a marker for the awk script - do not change */ 2658 /* Following line is a marker for the awk script - do not change */
2663 asm volatile("rdtsc"); /* Stop here */ 2659 asm volatile("rdtsc"); /* Stop here */
2664 2660
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index b1d491c2e704..fdde1bd3e306 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -608,6 +608,7 @@ static const struct {
608 const char *compact; 608 const char *compact;
609} gfp_compact_table[] = { 609} gfp_compact_table[] = {
610 { "GFP_TRANSHUGE", "THP" }, 610 { "GFP_TRANSHUGE", "THP" },
611 { "GFP_TRANSHUGE_LIGHT", "THL" },
611 { "GFP_HIGHUSER_MOVABLE", "HUM" }, 612 { "GFP_HIGHUSER_MOVABLE", "HUM" },
612 { "GFP_HIGHUSER", "HU" }, 613 { "GFP_HIGHUSER", "HU" },
613 { "GFP_USER", "U" }, 614 { "GFP_USER", "U" },
diff --git a/tools/perf/scripts/python/netdev-times.py b/tools/perf/scripts/python/netdev-times.py
index 4d21ef2d601d..4c6f09ac7d12 100644
--- a/tools/perf/scripts/python/netdev-times.py
+++ b/tools/perf/scripts/python/netdev-times.py
@@ -252,9 +252,10 @@ def irq__irq_handler_exit(name, context, cpu, sec, nsec, pid, comm, callchain, i
252 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, irq, ret) 252 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, irq, ret)
253 all_event_list.append(event_info) 253 all_event_list.append(event_info)
254 254
255def napi__napi_poll(name, context, cpu, sec, nsec, pid, comm, callchain, napi, dev_name): 255def napi__napi_poll(name, context, cpu, sec, nsec, pid, comm, callchain, napi,
256 dev_name, work=None, budget=None):
256 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, 257 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
257 napi, dev_name) 258 napi, dev_name, work, budget)
258 all_event_list.append(event_info) 259 all_event_list.append(event_info)
259 260
260def net__netif_receive_skb(name, context, cpu, sec, nsec, pid, comm, callchain, skbaddr, 261def net__netif_receive_skb(name, context, cpu, sec, nsec, pid, comm, callchain, skbaddr,
@@ -354,11 +355,13 @@ def handle_irq_softirq_exit(event_info):
354 receive_hunk_list.append(rec_data) 355 receive_hunk_list.append(rec_data)
355 356
356def handle_napi_poll(event_info): 357def handle_napi_poll(event_info):
357 (name, context, cpu, time, pid, comm, napi, dev_name) = event_info 358 (name, context, cpu, time, pid, comm, napi, dev_name,
359 work, budget) = event_info
358 if cpu in net_rx_dic.keys(): 360 if cpu in net_rx_dic.keys():
359 event_list = net_rx_dic[cpu]['event_list'] 361 event_list = net_rx_dic[cpu]['event_list']
360 rec_data = {'event_name':'napi_poll', 362 rec_data = {'event_name':'napi_poll',
361 'dev':dev_name, 'event_t':time} 363 'dev':dev_name, 'event_t':time,
364 'work':work, 'budget':budget}
362 event_list.append(rec_data) 365 event_list.append(rec_data)
363 366
364def handle_netif_rx(event_info): 367def handle_netif_rx(event_info):
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 2fa7d8b69873..91c5f6e1af59 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -70,7 +70,6 @@ libperf-y += stat.o
70libperf-y += stat-shadow.o 70libperf-y += stat-shadow.o
71libperf-y += record.o 71libperf-y += record.o
72libperf-y += srcline.o 72libperf-y += srcline.o
73libperf-y += str_error_r.o
74libperf-y += data.o 73libperf-y += data.o
75libperf-y += tsc.o 74libperf-y += tsc.o
76libperf-y += cloexec.o 75libperf-y += cloexec.o
@@ -176,10 +175,6 @@ $(OUTPUT)util/libstring.o: ../lib/string.c FORCE
176 $(call rule_mkdir) 175 $(call rule_mkdir)
177 $(call if_changed_dep,cc_o_c) 176 $(call if_changed_dep,cc_o_c)
178 177
179$(OUTPUT)util/str_error_r.o: ../lib/str_error_r.c FORCE
180 $(call rule_mkdir)
181 $(call if_changed_dep,cc_o_c)
182
183$(OUTPUT)util/hweight.o: ../lib/hweight.c FORCE 178$(OUTPUT)util/hweight.o: ../lib/hweight.c FORCE
184 $(call rule_mkdir) 179 $(call rule_mkdir)
185 $(call if_changed_dep,cc_o_c) 180 $(call if_changed_dep,cc_o_c)
diff --git a/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt b/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt
index ec378cd7b71e..767be7c76034 100644
--- a/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt
+++ b/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt
@@ -1012,7 +1012,7 @@ GrpTable: Grp15
10124: XSAVE 10124: XSAVE
10135: XRSTOR | lfence (11B) 10135: XRSTOR | lfence (11B)
10146: XSAVEOPT | clwb (66) | mfence (11B) 10146: XSAVEOPT | clwb (66) | mfence (11B)
10157: clflush | clflushopt (66) | sfence (11B) | pcommit (66),(11B) 10157: clflush | clflushopt (66) | sfence (11B)
1016EndTable 1016EndTable
1017 1017
1018GrpTable: Grp16 1018GrpTable: Grp16
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index bc2cdbd09a25..cb6388dbdd98 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1093,12 +1093,20 @@ static int machine__set_modules_path(struct machine *machine)
1093 1093
1094 return map_groups__set_modules_path_dir(&machine->kmaps, modules_path, 0); 1094 return map_groups__set_modules_path_dir(&machine->kmaps, modules_path, 0);
1095} 1095}
1096int __weak arch__fix_module_text_start(u64 *start __maybe_unused,
1097 const char *name __maybe_unused)
1098{
1099 return 0;
1100}
1096 1101
1097static int machine__create_module(void *arg, const char *name, u64 start) 1102static int machine__create_module(void *arg, const char *name, u64 start)
1098{ 1103{
1099 struct machine *machine = arg; 1104 struct machine *machine = arg;
1100 struct map *map; 1105 struct map *map;
1101 1106
1107 if (arch__fix_module_text_start(&start, name) < 0)
1108 return -1;
1109
1102 map = machine__findnew_module_map(machine, start, name); 1110 map = machine__findnew_module_map(machine, start, name);
1103 if (map == NULL) 1111 if (map == NULL)
1104 return -1; 1112 return -1;
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index 41ac9cfd416b..20739f746bc4 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -216,6 +216,7 @@ struct symbol *machine__find_kernel_function_by_name(struct machine *machine,
216 216
217struct map *machine__findnew_module_map(struct machine *machine, u64 start, 217struct map *machine__findnew_module_map(struct machine *machine, u64 start,
218 const char *filename); 218 const char *filename);
219int arch__fix_module_text_start(u64 *start, const char *name);
219 220
220int __machine__load_kallsyms(struct machine *machine, const char *filename, 221int __machine__load_kallsyms(struct machine *machine, const char *filename,
221 enum map_type type, bool no_kcore, symbol_filter_t filter); 222 enum map_type type, bool no_kcore, symbol_filter_t filter);
diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources
index 5065ec98049c..b7d4f4aeee61 100644
--- a/tools/perf/util/python-ext-sources
+++ b/tools/perf/util/python-ext-sources
@@ -13,7 +13,6 @@ util/cpumap.c
13../lib/bitmap.c 13../lib/bitmap.c
14../lib/find_bit.c 14../lib/find_bit.c
15../lib/hweight.c 15../lib/hweight.c
16../lib/str_error_r.c
17../lib/vsprintf.c 16../lib/vsprintf.c
18util/thread_map.c 17util/thread_map.c
19util/util.c 18util/util.c
diff --git a/tools/testing/nvdimm/Kbuild b/tools/testing/nvdimm/Kbuild
index 785985677159..ad6dd0543019 100644
--- a/tools/testing/nvdimm/Kbuild
+++ b/tools/testing/nvdimm/Kbuild
@@ -11,12 +11,14 @@ ldflags-y += --wrap=__devm_release_region
11ldflags-y += --wrap=__request_region 11ldflags-y += --wrap=__request_region
12ldflags-y += --wrap=__release_region 12ldflags-y += --wrap=__release_region
13ldflags-y += --wrap=devm_memremap_pages 13ldflags-y += --wrap=devm_memremap_pages
14ldflags-y += --wrap=phys_to_pfn_t 14ldflags-y += --wrap=insert_resource
15ldflags-y += --wrap=remove_resource
15 16
16DRIVERS := ../../../drivers 17DRIVERS := ../../../drivers
17NVDIMM_SRC := $(DRIVERS)/nvdimm 18NVDIMM_SRC := $(DRIVERS)/nvdimm
18ACPI_SRC := $(DRIVERS)/acpi 19ACPI_SRC := $(DRIVERS)/acpi/nfit
19DAX_SRC := $(DRIVERS)/dax 20DAX_SRC := $(DRIVERS)/dax
21ccflags-y := -I$(src)/$(NVDIMM_SRC)/
20 22
21obj-$(CONFIG_LIBNVDIMM) += libnvdimm.o 23obj-$(CONFIG_LIBNVDIMM) += libnvdimm.o
22obj-$(CONFIG_BLK_DEV_PMEM) += nd_pmem.o 24obj-$(CONFIG_BLK_DEV_PMEM) += nd_pmem.o
@@ -27,10 +29,12 @@ obj-$(CONFIG_ACPI_NFIT) += nfit.o
27obj-$(CONFIG_DEV_DAX) += dax.o 29obj-$(CONFIG_DEV_DAX) += dax.o
28obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem.o 30obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem.o
29 31
30nfit-y := $(ACPI_SRC)/nfit.o 32nfit-y := $(ACPI_SRC)/core.o
33nfit-$(CONFIG_X86_MCE) += $(ACPI_SRC)/mce.o
31nfit-y += config_check.o 34nfit-y += config_check.o
32 35
33nd_pmem-y := $(NVDIMM_SRC)/pmem.o 36nd_pmem-y := $(NVDIMM_SRC)/pmem.o
37nd_pmem-y += pmem-dax.o
34nd_pmem-y += config_check.o 38nd_pmem-y += config_check.o
35 39
36nd_btt-y := $(NVDIMM_SRC)/btt.o 40nd_btt-y := $(NVDIMM_SRC)/btt.o
diff --git a/tools/testing/nvdimm/config_check.c b/tools/testing/nvdimm/config_check.c
index adf18bfeca00..878daf3429e8 100644
--- a/tools/testing/nvdimm/config_check.c
+++ b/tools/testing/nvdimm/config_check.c
@@ -10,6 +10,7 @@ void check(void)
10 BUILD_BUG_ON(!IS_MODULE(CONFIG_LIBNVDIMM)); 10 BUILD_BUG_ON(!IS_MODULE(CONFIG_LIBNVDIMM));
11 BUILD_BUG_ON(!IS_MODULE(CONFIG_BLK_DEV_PMEM)); 11 BUILD_BUG_ON(!IS_MODULE(CONFIG_BLK_DEV_PMEM));
12 BUILD_BUG_ON(!IS_MODULE(CONFIG_ND_BTT)); 12 BUILD_BUG_ON(!IS_MODULE(CONFIG_ND_BTT));
13 BUILD_BUG_ON(!IS_MODULE(CONFIG_ND_PFN));
13 BUILD_BUG_ON(!IS_MODULE(CONFIG_ND_BLK)); 14 BUILD_BUG_ON(!IS_MODULE(CONFIG_ND_BLK));
14 BUILD_BUG_ON(!IS_MODULE(CONFIG_ACPI_NFIT)); 15 BUILD_BUG_ON(!IS_MODULE(CONFIG_ACPI_NFIT));
15 BUILD_BUG_ON(!IS_MODULE(CONFIG_DEV_DAX)); 16 BUILD_BUG_ON(!IS_MODULE(CONFIG_DEV_DAX));
diff --git a/tools/testing/nvdimm/pmem-dax.c b/tools/testing/nvdimm/pmem-dax.c
new file mode 100644
index 000000000000..c9b8c48f85fc
--- /dev/null
+++ b/tools/testing/nvdimm/pmem-dax.c
@@ -0,0 +1,54 @@
1/*
2 * Copyright (c) 2014-2016, Intel Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 */
13#include "test/nfit_test.h"
14#include <linux/blkdev.h>
15#include <pmem.h>
16#include <nd.h>
17
18long pmem_direct_access(struct block_device *bdev, sector_t sector,
19 void **kaddr, pfn_t *pfn, long size)
20{
21 struct pmem_device *pmem = bdev->bd_queue->queuedata;
22 resource_size_t offset = sector * 512 + pmem->data_offset;
23
24 if (unlikely(is_bad_pmem(&pmem->bb, sector, size)))
25 return -EIO;
26
27 /*
28 * Limit dax to a single page at a time given vmalloc()-backed
29 * in the nfit_test case.
30 */
31 if (get_nfit_res(pmem->phys_addr + offset)) {
32 struct page *page;
33
34 *kaddr = pmem->virt_addr + offset;
35 page = vmalloc_to_page(pmem->virt_addr + offset);
36 *pfn = page_to_pfn_t(page);
37 dev_dbg_ratelimited(disk_to_dev(bdev->bd_disk)->parent,
38 "%s: sector: %#llx pfn: %#lx\n", __func__,
39 (unsigned long long) sector, page_to_pfn(page));
40
41 return PAGE_SIZE;
42 }
43
44 *kaddr = pmem->virt_addr + offset;
45 *pfn = phys_to_pfn_t(pmem->phys_addr + offset, pmem->pfn_flags);
46
47 /*
48 * If badblocks are present, limit known good range to the
49 * requested range.
50 */
51 if (unlikely(pmem->bb.count))
52 return size;
53 return pmem->size - pmem->pfn_pad - offset;
54}
diff --git a/tools/testing/nvdimm/test/Kbuild b/tools/testing/nvdimm/test/Kbuild
index 9241064970fe..d32f25bba42a 100644
--- a/tools/testing/nvdimm/test/Kbuild
+++ b/tools/testing/nvdimm/test/Kbuild
@@ -1,5 +1,5 @@
1ccflags-y := -I$(src)/../../../../drivers/nvdimm/ 1ccflags-y := -I$(src)/../../../../drivers/nvdimm/
2ccflags-y += -I$(src)/../../../../drivers/acpi/ 2ccflags-y += -I$(src)/../../../../drivers/acpi/nfit/
3 3
4obj-m += nfit_test.o 4obj-m += nfit_test.o
5obj-m += nfit_test_iomap.o 5obj-m += nfit_test_iomap.o
diff --git a/tools/testing/nvdimm/test/iomap.c b/tools/testing/nvdimm/test/iomap.c
index c842095f2801..c29f8dca9e67 100644
--- a/tools/testing/nvdimm/test/iomap.c
+++ b/tools/testing/nvdimm/test/iomap.c
@@ -10,11 +10,13 @@
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details. 11 * General Public License for more details.
12 */ 12 */
13#include <linux/memremap.h>
13#include <linux/rculist.h> 14#include <linux/rculist.h>
14#include <linux/export.h> 15#include <linux/export.h>
15#include <linux/ioport.h> 16#include <linux/ioport.h>
16#include <linux/module.h> 17#include <linux/module.h>
17#include <linux/types.h> 18#include <linux/types.h>
19#include <linux/pfn_t.h>
18#include <linux/io.h> 20#include <linux/io.h>
19#include <linux/mm.h> 21#include <linux/mm.h>
20#include "nfit_test.h" 22#include "nfit_test.h"
@@ -52,7 +54,7 @@ static struct nfit_test_resource *__get_nfit_res(resource_size_t resource)
52 return NULL; 54 return NULL;
53} 55}
54 56
55static struct nfit_test_resource *get_nfit_res(resource_size_t resource) 57struct nfit_test_resource *get_nfit_res(resource_size_t resource)
56{ 58{
57 struct nfit_test_resource *res; 59 struct nfit_test_resource *res;
58 60
@@ -62,6 +64,7 @@ static struct nfit_test_resource *get_nfit_res(resource_size_t resource)
62 64
63 return res; 65 return res;
64} 66}
67EXPORT_SYMBOL(get_nfit_res);
65 68
66void __iomem *__nfit_test_ioremap(resource_size_t offset, unsigned long size, 69void __iomem *__nfit_test_ioremap(resource_size_t offset, unsigned long size,
67 void __iomem *(*fallback_fn)(resource_size_t, unsigned long)) 70 void __iomem *(*fallback_fn)(resource_size_t, unsigned long))
@@ -97,10 +100,6 @@ void *__wrap_devm_memremap(struct device *dev, resource_size_t offset,
97} 100}
98EXPORT_SYMBOL(__wrap_devm_memremap); 101EXPORT_SYMBOL(__wrap_devm_memremap);
99 102
100#ifdef __HAVE_ARCH_PTE_DEVMAP
101#include <linux/memremap.h>
102#include <linux/pfn_t.h>
103
104void *__wrap_devm_memremap_pages(struct device *dev, struct resource *res, 103void *__wrap_devm_memremap_pages(struct device *dev, struct resource *res,
105 struct percpu_ref *ref, struct vmem_altmap *altmap) 104 struct percpu_ref *ref, struct vmem_altmap *altmap)
106{ 105{
@@ -122,19 +121,6 @@ pfn_t __wrap_phys_to_pfn_t(phys_addr_t addr, unsigned long flags)
122 return phys_to_pfn_t(addr, flags); 121 return phys_to_pfn_t(addr, flags);
123} 122}
124EXPORT_SYMBOL(__wrap_phys_to_pfn_t); 123EXPORT_SYMBOL(__wrap_phys_to_pfn_t);
125#else
126/* to be removed post 4.5-rc1 */
127void *__wrap_devm_memremap_pages(struct device *dev, struct resource *res)
128{
129 resource_size_t offset = res->start;
130 struct nfit_test_resource *nfit_res = get_nfit_res(offset);
131
132 if (nfit_res)
133 return nfit_res->buf + offset - nfit_res->res->start;
134 return devm_memremap_pages(dev, res);
135}
136EXPORT_SYMBOL(__wrap_devm_memremap_pages);
137#endif
138 124
139void *__wrap_memremap(resource_size_t offset, size_t size, 125void *__wrap_memremap(resource_size_t offset, size_t size,
140 unsigned long flags) 126 unsigned long flags)
@@ -229,6 +215,22 @@ struct resource *__wrap___request_region(struct resource *parent,
229} 215}
230EXPORT_SYMBOL(__wrap___request_region); 216EXPORT_SYMBOL(__wrap___request_region);
231 217
218int __wrap_insert_resource(struct resource *parent, struct resource *res)
219{
220 if (get_nfit_res(res->start))
221 return 0;
222 return insert_resource(parent, res);
223}
224EXPORT_SYMBOL(__wrap_insert_resource);
225
226int __wrap_remove_resource(struct resource *res)
227{
228 if (get_nfit_res(res->start))
229 return 0;
230 return remove_resource(res);
231}
232EXPORT_SYMBOL(__wrap_remove_resource);
233
232struct resource *__wrap___devm_request_region(struct device *dev, 234struct resource *__wrap___devm_request_region(struct device *dev,
233 struct resource *parent, resource_size_t start, 235 struct resource *parent, resource_size_t start,
234 resource_size_t n, const char *name) 236 resource_size_t n, const char *name)
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index c919866853a0..5404efa578a3 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -98,11 +98,13 @@
98enum { 98enum {
99 NUM_PM = 3, 99 NUM_PM = 3,
100 NUM_DCR = 5, 100 NUM_DCR = 5,
101 NUM_HINTS = 8,
101 NUM_BDW = NUM_DCR, 102 NUM_BDW = NUM_DCR,
102 NUM_SPA = NUM_PM + NUM_DCR + NUM_BDW, 103 NUM_SPA = NUM_PM + NUM_DCR + NUM_BDW,
103 NUM_MEM = NUM_DCR + NUM_BDW + 2 /* spa0 iset */ + 4 /* spa1 iset */, 104 NUM_MEM = NUM_DCR + NUM_BDW + 2 /* spa0 iset */ + 4 /* spa1 iset */,
104 DIMM_SIZE = SZ_32M, 105 DIMM_SIZE = SZ_32M,
105 LABEL_SIZE = SZ_128K, 106 LABEL_SIZE = SZ_128K,
107 SPA_VCD_SIZE = SZ_4M,
106 SPA0_SIZE = DIMM_SIZE, 108 SPA0_SIZE = DIMM_SIZE,
107 SPA1_SIZE = DIMM_SIZE*2, 109 SPA1_SIZE = DIMM_SIZE*2,
108 SPA2_SIZE = DIMM_SIZE, 110 SPA2_SIZE = DIMM_SIZE,
@@ -470,11 +472,7 @@ static void release_nfit_res(void *data)
470 list_del(&nfit_res->list); 472 list_del(&nfit_res->list);
471 spin_unlock(&nfit_test_lock); 473 spin_unlock(&nfit_test_lock);
472 474
473 if (is_vmalloc_addr(nfit_res->buf)) 475 vfree(nfit_res->buf);
474 vfree(nfit_res->buf);
475 else
476 dma_free_coherent(nfit_res->dev, resource_size(res),
477 nfit_res->buf, res->start);
478 kfree(res); 476 kfree(res);
479 kfree(nfit_res); 477 kfree(nfit_res);
480} 478}
@@ -507,9 +505,7 @@ static void *__test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma,
507 505
508 return nfit_res->buf; 506 return nfit_res->buf;
509 err: 507 err:
510 if (buf && !is_vmalloc_addr(buf)) 508 if (buf)
511 dma_free_coherent(dev, size, buf, *dma);
512 else if (buf)
513 vfree(buf); 509 vfree(buf);
514 kfree(res); 510 kfree(res);
515 kfree(nfit_res); 511 kfree(nfit_res);
@@ -524,15 +520,6 @@ static void *test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma)
524 return __test_alloc(t, size, dma, buf); 520 return __test_alloc(t, size, dma, buf);
525} 521}
526 522
527static void *test_alloc_coherent(struct nfit_test *t, size_t size,
528 dma_addr_t *dma)
529{
530 struct device *dev = &t->pdev.dev;
531 void *buf = dma_alloc_coherent(dev, size, dma, GFP_KERNEL);
532
533 return __test_alloc(t, size, dma, buf);
534}
535
536static struct nfit_test_resource *nfit_test_lookup(resource_size_t addr) 523static struct nfit_test_resource *nfit_test_lookup(resource_size_t addr)
537{ 524{
538 int i; 525 int i;
@@ -584,7 +571,8 @@ static int nfit_test0_alloc(struct nfit_test *t)
584 + offsetof(struct acpi_nfit_control_region, 571 + offsetof(struct acpi_nfit_control_region,
585 window_size) * NUM_DCR 572 window_size) * NUM_DCR
586 + sizeof(struct acpi_nfit_data_region) * NUM_BDW 573 + sizeof(struct acpi_nfit_data_region) * NUM_BDW
587 + sizeof(struct acpi_nfit_flush_address) * NUM_DCR; 574 + (sizeof(struct acpi_nfit_flush_address)
575 + sizeof(u64) * NUM_HINTS) * NUM_DCR;
588 int i; 576 int i;
589 577
590 t->nfit_buf = test_alloc(t, nfit_size, &t->nfit_dma); 578 t->nfit_buf = test_alloc(t, nfit_size, &t->nfit_dma);
@@ -592,15 +580,15 @@ static int nfit_test0_alloc(struct nfit_test *t)
592 return -ENOMEM; 580 return -ENOMEM;
593 t->nfit_size = nfit_size; 581 t->nfit_size = nfit_size;
594 582
595 t->spa_set[0] = test_alloc_coherent(t, SPA0_SIZE, &t->spa_set_dma[0]); 583 t->spa_set[0] = test_alloc(t, SPA0_SIZE, &t->spa_set_dma[0]);
596 if (!t->spa_set[0]) 584 if (!t->spa_set[0])
597 return -ENOMEM; 585 return -ENOMEM;
598 586
599 t->spa_set[1] = test_alloc_coherent(t, SPA1_SIZE, &t->spa_set_dma[1]); 587 t->spa_set[1] = test_alloc(t, SPA1_SIZE, &t->spa_set_dma[1]);
600 if (!t->spa_set[1]) 588 if (!t->spa_set[1])
601 return -ENOMEM; 589 return -ENOMEM;
602 590
603 t->spa_set[2] = test_alloc_coherent(t, SPA0_SIZE, &t->spa_set_dma[2]); 591 t->spa_set[2] = test_alloc(t, SPA0_SIZE, &t->spa_set_dma[2]);
604 if (!t->spa_set[2]) 592 if (!t->spa_set[2])
605 return -ENOMEM; 593 return -ENOMEM;
606 594
@@ -614,7 +602,8 @@ static int nfit_test0_alloc(struct nfit_test *t)
614 return -ENOMEM; 602 return -ENOMEM;
615 sprintf(t->label[i], "label%d", i); 603 sprintf(t->label[i], "label%d", i);
616 604
617 t->flush[i] = test_alloc(t, 8, &t->flush_dma[i]); 605 t->flush[i] = test_alloc(t, sizeof(u64) * NUM_HINTS,
606 &t->flush_dma[i]);
618 if (!t->flush[i]) 607 if (!t->flush[i])
619 return -ENOMEM; 608 return -ENOMEM;
620 } 609 }
@@ -630,7 +619,7 @@ static int nfit_test0_alloc(struct nfit_test *t)
630 619
631static int nfit_test1_alloc(struct nfit_test *t) 620static int nfit_test1_alloc(struct nfit_test *t)
632{ 621{
633 size_t nfit_size = sizeof(struct acpi_nfit_system_address) 622 size_t nfit_size = sizeof(struct acpi_nfit_system_address) * 2
634 + sizeof(struct acpi_nfit_memory_map) 623 + sizeof(struct acpi_nfit_memory_map)
635 + offsetof(struct acpi_nfit_control_region, window_size); 624 + offsetof(struct acpi_nfit_control_region, window_size);
636 625
@@ -639,15 +628,31 @@ static int nfit_test1_alloc(struct nfit_test *t)
639 return -ENOMEM; 628 return -ENOMEM;
640 t->nfit_size = nfit_size; 629 t->nfit_size = nfit_size;
641 630
642 t->spa_set[0] = test_alloc_coherent(t, SPA2_SIZE, &t->spa_set_dma[0]); 631 t->spa_set[0] = test_alloc(t, SPA2_SIZE, &t->spa_set_dma[0]);
643 if (!t->spa_set[0]) 632 if (!t->spa_set[0])
644 return -ENOMEM; 633 return -ENOMEM;
645 634
635 t->spa_set[1] = test_alloc(t, SPA_VCD_SIZE, &t->spa_set_dma[1]);
636 if (!t->spa_set[1])
637 return -ENOMEM;
638
646 return ars_state_init(&t->pdev.dev, &t->ars_state); 639 return ars_state_init(&t->pdev.dev, &t->ars_state);
647} 640}
648 641
642static void dcr_common_init(struct acpi_nfit_control_region *dcr)
643{
644 dcr->vendor_id = 0xabcd;
645 dcr->device_id = 0;
646 dcr->revision_id = 1;
647 dcr->valid_fields = 1;
648 dcr->manufacturing_location = 0xa;
649 dcr->manufacturing_date = cpu_to_be16(2016);
650}
651
649static void nfit_test0_setup(struct nfit_test *t) 652static void nfit_test0_setup(struct nfit_test *t)
650{ 653{
654 const int flush_hint_size = sizeof(struct acpi_nfit_flush_address)
655 + (sizeof(u64) * NUM_HINTS);
651 struct acpi_nfit_desc *acpi_desc; 656 struct acpi_nfit_desc *acpi_desc;
652 struct acpi_nfit_memory_map *memdev; 657 struct acpi_nfit_memory_map *memdev;
653 void *nfit_buf = t->nfit_buf; 658 void *nfit_buf = t->nfit_buf;
@@ -655,7 +660,7 @@ static void nfit_test0_setup(struct nfit_test *t)
655 struct acpi_nfit_control_region *dcr; 660 struct acpi_nfit_control_region *dcr;
656 struct acpi_nfit_data_region *bdw; 661 struct acpi_nfit_data_region *bdw;
657 struct acpi_nfit_flush_address *flush; 662 struct acpi_nfit_flush_address *flush;
658 unsigned int offset; 663 unsigned int offset, i;
659 664
660 /* 665 /*
661 * spa0 (interleave first half of dimm0 and dimm1, note storage 666 * spa0 (interleave first half of dimm0 and dimm1, note storage
@@ -972,9 +977,7 @@ static void nfit_test0_setup(struct nfit_test *t)
972 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; 977 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
973 dcr->header.length = sizeof(struct acpi_nfit_control_region); 978 dcr->header.length = sizeof(struct acpi_nfit_control_region);
974 dcr->region_index = 0+1; 979 dcr->region_index = 0+1;
975 dcr->vendor_id = 0xabcd; 980 dcr_common_init(dcr);
976 dcr->device_id = 0;
977 dcr->revision_id = 1;
978 dcr->serial_number = ~handle[0]; 981 dcr->serial_number = ~handle[0];
979 dcr->code = NFIT_FIC_BLK; 982 dcr->code = NFIT_FIC_BLK;
980 dcr->windows = 1; 983 dcr->windows = 1;
@@ -989,9 +992,7 @@ static void nfit_test0_setup(struct nfit_test *t)
989 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; 992 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
990 dcr->header.length = sizeof(struct acpi_nfit_control_region); 993 dcr->header.length = sizeof(struct acpi_nfit_control_region);
991 dcr->region_index = 1+1; 994 dcr->region_index = 1+1;
992 dcr->vendor_id = 0xabcd; 995 dcr_common_init(dcr);
993 dcr->device_id = 0;
994 dcr->revision_id = 1;
995 dcr->serial_number = ~handle[1]; 996 dcr->serial_number = ~handle[1];
996 dcr->code = NFIT_FIC_BLK; 997 dcr->code = NFIT_FIC_BLK;
997 dcr->windows = 1; 998 dcr->windows = 1;
@@ -1006,9 +1007,7 @@ static void nfit_test0_setup(struct nfit_test *t)
1006 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; 1007 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1007 dcr->header.length = sizeof(struct acpi_nfit_control_region); 1008 dcr->header.length = sizeof(struct acpi_nfit_control_region);
1008 dcr->region_index = 2+1; 1009 dcr->region_index = 2+1;
1009 dcr->vendor_id = 0xabcd; 1010 dcr_common_init(dcr);
1010 dcr->device_id = 0;
1011 dcr->revision_id = 1;
1012 dcr->serial_number = ~handle[2]; 1011 dcr->serial_number = ~handle[2];
1013 dcr->code = NFIT_FIC_BLK; 1012 dcr->code = NFIT_FIC_BLK;
1014 dcr->windows = 1; 1013 dcr->windows = 1;
@@ -1023,9 +1022,7 @@ static void nfit_test0_setup(struct nfit_test *t)
1023 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; 1022 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1024 dcr->header.length = sizeof(struct acpi_nfit_control_region); 1023 dcr->header.length = sizeof(struct acpi_nfit_control_region);
1025 dcr->region_index = 3+1; 1024 dcr->region_index = 3+1;
1026 dcr->vendor_id = 0xabcd; 1025 dcr_common_init(dcr);
1027 dcr->device_id = 0;
1028 dcr->revision_id = 1;
1029 dcr->serial_number = ~handle[3]; 1026 dcr->serial_number = ~handle[3];
1030 dcr->code = NFIT_FIC_BLK; 1027 dcr->code = NFIT_FIC_BLK;
1031 dcr->windows = 1; 1028 dcr->windows = 1;
@@ -1042,9 +1039,7 @@ static void nfit_test0_setup(struct nfit_test *t)
1042 dcr->header.length = offsetof(struct acpi_nfit_control_region, 1039 dcr->header.length = offsetof(struct acpi_nfit_control_region,
1043 window_size); 1040 window_size);
1044 dcr->region_index = 4+1; 1041 dcr->region_index = 4+1;
1045 dcr->vendor_id = 0xabcd; 1042 dcr_common_init(dcr);
1046 dcr->device_id = 0;
1047 dcr->revision_id = 1;
1048 dcr->serial_number = ~handle[0]; 1043 dcr->serial_number = ~handle[0];
1049 dcr->code = NFIT_FIC_BYTEN; 1044 dcr->code = NFIT_FIC_BYTEN;
1050 dcr->windows = 0; 1045 dcr->windows = 0;
@@ -1056,9 +1051,7 @@ static void nfit_test0_setup(struct nfit_test *t)
1056 dcr->header.length = offsetof(struct acpi_nfit_control_region, 1051 dcr->header.length = offsetof(struct acpi_nfit_control_region,
1057 window_size); 1052 window_size);
1058 dcr->region_index = 5+1; 1053 dcr->region_index = 5+1;
1059 dcr->vendor_id = 0xabcd; 1054 dcr_common_init(dcr);
1060 dcr->device_id = 0;
1061 dcr->revision_id = 1;
1062 dcr->serial_number = ~handle[1]; 1055 dcr->serial_number = ~handle[1];
1063 dcr->code = NFIT_FIC_BYTEN; 1056 dcr->code = NFIT_FIC_BYTEN;
1064 dcr->windows = 0; 1057 dcr->windows = 0;
@@ -1070,9 +1063,7 @@ static void nfit_test0_setup(struct nfit_test *t)
1070 dcr->header.length = offsetof(struct acpi_nfit_control_region, 1063 dcr->header.length = offsetof(struct acpi_nfit_control_region,
1071 window_size); 1064 window_size);
1072 dcr->region_index = 6+1; 1065 dcr->region_index = 6+1;
1073 dcr->vendor_id = 0xabcd; 1066 dcr_common_init(dcr);
1074 dcr->device_id = 0;
1075 dcr->revision_id = 1;
1076 dcr->serial_number = ~handle[2]; 1067 dcr->serial_number = ~handle[2];
1077 dcr->code = NFIT_FIC_BYTEN; 1068 dcr->code = NFIT_FIC_BYTEN;
1078 dcr->windows = 0; 1069 dcr->windows = 0;
@@ -1084,9 +1075,7 @@ static void nfit_test0_setup(struct nfit_test *t)
1084 dcr->header.length = offsetof(struct acpi_nfit_control_region, 1075 dcr->header.length = offsetof(struct acpi_nfit_control_region,
1085 window_size); 1076 window_size);
1086 dcr->region_index = 7+1; 1077 dcr->region_index = 7+1;
1087 dcr->vendor_id = 0xabcd; 1078 dcr_common_init(dcr);
1088 dcr->device_id = 0;
1089 dcr->revision_id = 1;
1090 dcr->serial_number = ~handle[3]; 1079 dcr->serial_number = ~handle[3];
1091 dcr->code = NFIT_FIC_BYTEN; 1080 dcr->code = NFIT_FIC_BYTEN;
1092 dcr->windows = 0; 1081 dcr->windows = 0;
@@ -1141,45 +1130,47 @@ static void nfit_test0_setup(struct nfit_test *t)
1141 /* flush0 (dimm0) */ 1130 /* flush0 (dimm0) */
1142 flush = nfit_buf + offset; 1131 flush = nfit_buf + offset;
1143 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS; 1132 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1144 flush->header.length = sizeof(struct acpi_nfit_flush_address); 1133 flush->header.length = flush_hint_size;
1145 flush->device_handle = handle[0]; 1134 flush->device_handle = handle[0];
1146 flush->hint_count = 1; 1135 flush->hint_count = NUM_HINTS;
1147 flush->hint_address[0] = t->flush_dma[0]; 1136 for (i = 0; i < NUM_HINTS; i++)
1137 flush->hint_address[i] = t->flush_dma[0] + i * sizeof(u64);
1148 1138
1149 /* flush1 (dimm1) */ 1139 /* flush1 (dimm1) */
1150 flush = nfit_buf + offset + sizeof(struct acpi_nfit_flush_address) * 1; 1140 flush = nfit_buf + offset + flush_hint_size * 1;
1151 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS; 1141 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1152 flush->header.length = sizeof(struct acpi_nfit_flush_address); 1142 flush->header.length = flush_hint_size;
1153 flush->device_handle = handle[1]; 1143 flush->device_handle = handle[1];
1154 flush->hint_count = 1; 1144 flush->hint_count = NUM_HINTS;
1155 flush->hint_address[0] = t->flush_dma[1]; 1145 for (i = 0; i < NUM_HINTS; i++)
1146 flush->hint_address[i] = t->flush_dma[1] + i * sizeof(u64);
1156 1147
1157 /* flush2 (dimm2) */ 1148 /* flush2 (dimm2) */
1158 flush = nfit_buf + offset + sizeof(struct acpi_nfit_flush_address) * 2; 1149 flush = nfit_buf + offset + flush_hint_size * 2;
1159 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS; 1150 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1160 flush->header.length = sizeof(struct acpi_nfit_flush_address); 1151 flush->header.length = flush_hint_size;
1161 flush->device_handle = handle[2]; 1152 flush->device_handle = handle[2];
1162 flush->hint_count = 1; 1153 flush->hint_count = NUM_HINTS;
1163 flush->hint_address[0] = t->flush_dma[2]; 1154 for (i = 0; i < NUM_HINTS; i++)
1155 flush->hint_address[i] = t->flush_dma[2] + i * sizeof(u64);
1164 1156
1165 /* flush3 (dimm3) */ 1157 /* flush3 (dimm3) */
1166 flush = nfit_buf + offset + sizeof(struct acpi_nfit_flush_address) * 3; 1158 flush = nfit_buf + offset + flush_hint_size * 3;
1167 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS; 1159 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1168 flush->header.length = sizeof(struct acpi_nfit_flush_address); 1160 flush->header.length = flush_hint_size;
1169 flush->device_handle = handle[3]; 1161 flush->device_handle = handle[3];
1170 flush->hint_count = 1; 1162 flush->hint_count = NUM_HINTS;
1171 flush->hint_address[0] = t->flush_dma[3]; 1163 for (i = 0; i < NUM_HINTS; i++)
1164 flush->hint_address[i] = t->flush_dma[3] + i * sizeof(u64);
1172 1165
1173 if (t->setup_hotplug) { 1166 if (t->setup_hotplug) {
1174 offset = offset + sizeof(struct acpi_nfit_flush_address) * 4; 1167 offset = offset + flush_hint_size * 4;
1175 /* dcr-descriptor4: blk */ 1168 /* dcr-descriptor4: blk */
1176 dcr = nfit_buf + offset; 1169 dcr = nfit_buf + offset;
1177 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; 1170 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1178 dcr->header.length = sizeof(struct acpi_nfit_control_region); 1171 dcr->header.length = sizeof(struct acpi_nfit_control_region);
1179 dcr->region_index = 8+1; 1172 dcr->region_index = 8+1;
1180 dcr->vendor_id = 0xabcd; 1173 dcr_common_init(dcr);
1181 dcr->device_id = 0;
1182 dcr->revision_id = 1;
1183 dcr->serial_number = ~handle[4]; 1174 dcr->serial_number = ~handle[4];
1184 dcr->code = NFIT_FIC_BLK; 1175 dcr->code = NFIT_FIC_BLK;
1185 dcr->windows = 1; 1176 dcr->windows = 1;
@@ -1196,9 +1187,7 @@ static void nfit_test0_setup(struct nfit_test *t)
1196 dcr->header.length = offsetof(struct acpi_nfit_control_region, 1187 dcr->header.length = offsetof(struct acpi_nfit_control_region,
1197 window_size); 1188 window_size);
1198 dcr->region_index = 9+1; 1189 dcr->region_index = 9+1;
1199 dcr->vendor_id = 0xabcd; 1190 dcr_common_init(dcr);
1200 dcr->device_id = 0;
1201 dcr->revision_id = 1;
1202 dcr->serial_number = ~handle[4]; 1191 dcr->serial_number = ~handle[4];
1203 dcr->code = NFIT_FIC_BYTEN; 1192 dcr->code = NFIT_FIC_BYTEN;
1204 dcr->windows = 0; 1193 dcr->windows = 0;
@@ -1300,10 +1289,12 @@ static void nfit_test0_setup(struct nfit_test *t)
1300 /* flush3 (dimm4) */ 1289 /* flush3 (dimm4) */
1301 flush = nfit_buf + offset; 1290 flush = nfit_buf + offset;
1302 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS; 1291 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1303 flush->header.length = sizeof(struct acpi_nfit_flush_address); 1292 flush->header.length = flush_hint_size;
1304 flush->device_handle = handle[4]; 1293 flush->device_handle = handle[4];
1305 flush->hint_count = 1; 1294 flush->hint_count = NUM_HINTS;
1306 flush->hint_address[0] = t->flush_dma[4]; 1295 for (i = 0; i < NUM_HINTS; i++)
1296 flush->hint_address[i] = t->flush_dma[4]
1297 + i * sizeof(u64);
1307 } 1298 }
1308 1299
1309 post_ars_status(&t->ars_state, t->spa_set_dma[0], SPA0_SIZE); 1300 post_ars_status(&t->ars_state, t->spa_set_dma[0], SPA0_SIZE);
@@ -1339,7 +1330,16 @@ static void nfit_test1_setup(struct nfit_test *t)
1339 spa->address = t->spa_set_dma[0]; 1330 spa->address = t->spa_set_dma[0];
1340 spa->length = SPA2_SIZE; 1331 spa->length = SPA2_SIZE;
1341 1332
1342 offset += sizeof(*spa); 1333 /* virtual cd region */
1334 spa = nfit_buf + sizeof(*spa);
1335 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
1336 spa->header.length = sizeof(*spa);
1337 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_VCD), 16);
1338 spa->range_index = 0;
1339 spa->address = t->spa_set_dma[1];
1340 spa->length = SPA_VCD_SIZE;
1341
1342 offset += sizeof(*spa) * 2;
1343 /* mem-region0 (spa0, dimm0) */ 1343 /* mem-region0 (spa0, dimm0) */
1344 memdev = nfit_buf + offset; 1344 memdev = nfit_buf + offset;
1345 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; 1345 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
@@ -1365,9 +1365,7 @@ static void nfit_test1_setup(struct nfit_test *t)
1365 dcr->header.length = offsetof(struct acpi_nfit_control_region, 1365 dcr->header.length = offsetof(struct acpi_nfit_control_region,
1366 window_size); 1366 window_size);
1367 dcr->region_index = 0+1; 1367 dcr->region_index = 0+1;
1368 dcr->vendor_id = 0xabcd; 1368 dcr_common_init(dcr);
1369 dcr->device_id = 0;
1370 dcr->revision_id = 1;
1371 dcr->serial_number = ~0; 1369 dcr->serial_number = ~0;
1372 dcr->code = NFIT_FIC_BYTE; 1370 dcr->code = NFIT_FIC_BYTE;
1373 dcr->windows = 0; 1371 dcr->windows = 0;
@@ -1462,20 +1460,16 @@ static int nfit_test_probe(struct platform_device *pdev)
1462 nfit_test->setup(nfit_test); 1460 nfit_test->setup(nfit_test);
1463 acpi_desc = &nfit_test->acpi_desc; 1461 acpi_desc = &nfit_test->acpi_desc;
1464 acpi_nfit_desc_init(acpi_desc, &pdev->dev); 1462 acpi_nfit_desc_init(acpi_desc, &pdev->dev);
1465 acpi_desc->nfit = nfit_test->nfit_buf;
1466 acpi_desc->blk_do_io = nfit_test_blk_do_io; 1463 acpi_desc->blk_do_io = nfit_test_blk_do_io;
1467 nd_desc = &acpi_desc->nd_desc; 1464 nd_desc = &acpi_desc->nd_desc;
1468 nd_desc->provider_name = NULL; 1465 nd_desc->provider_name = NULL;
1466 nd_desc->module = THIS_MODULE;
1469 nd_desc->ndctl = nfit_test_ctl; 1467 nd_desc->ndctl = nfit_test_ctl;
1470 acpi_desc->nvdimm_bus = nvdimm_bus_register(&pdev->dev, nd_desc);
1471 if (!acpi_desc->nvdimm_bus)
1472 return -ENXIO;
1473 1468
1474 rc = acpi_nfit_init(acpi_desc, nfit_test->nfit_size); 1469 rc = acpi_nfit_init(acpi_desc, nfit_test->nfit_buf,
1475 if (rc) { 1470 nfit_test->nfit_size);
1476 nvdimm_bus_unregister(acpi_desc->nvdimm_bus); 1471 if (rc)
1477 return rc; 1472 return rc;
1478 }
1479 1473
1480 if (nfit_test->setup != nfit_test0_setup) 1474 if (nfit_test->setup != nfit_test0_setup)
1481 return 0; 1475 return 0;
@@ -1483,22 +1477,16 @@ static int nfit_test_probe(struct platform_device *pdev)
1483 nfit_test->setup_hotplug = 1; 1477 nfit_test->setup_hotplug = 1;
1484 nfit_test->setup(nfit_test); 1478 nfit_test->setup(nfit_test);
1485 1479
1486 rc = acpi_nfit_init(acpi_desc, nfit_test->nfit_size); 1480 rc = acpi_nfit_init(acpi_desc, nfit_test->nfit_buf,
1487 if (rc) { 1481 nfit_test->nfit_size);
1488 nvdimm_bus_unregister(acpi_desc->nvdimm_bus); 1482 if (rc)
1489 return rc; 1483 return rc;
1490 }
1491 1484
1492 return 0; 1485 return 0;
1493} 1486}
1494 1487
1495static int nfit_test_remove(struct platform_device *pdev) 1488static int nfit_test_remove(struct platform_device *pdev)
1496{ 1489{
1497 struct nfit_test *nfit_test = to_nfit_test(&pdev->dev);
1498 struct acpi_nfit_desc *acpi_desc = &nfit_test->acpi_desc;
1499
1500 nvdimm_bus_unregister(acpi_desc->nvdimm_bus);
1501
1502 return 0; 1490 return 0;
1503} 1491}
1504 1492
@@ -1523,12 +1511,6 @@ static struct platform_driver nfit_test_driver = {
1523 .id_table = nfit_test_id, 1511 .id_table = nfit_test_id,
1524}; 1512};
1525 1513
1526#ifdef CONFIG_CMA_SIZE_MBYTES
1527#define CMA_SIZE_MBYTES CONFIG_CMA_SIZE_MBYTES
1528#else
1529#define CMA_SIZE_MBYTES 0
1530#endif
1531
1532static __init int nfit_test_init(void) 1514static __init int nfit_test_init(void)
1533{ 1515{
1534 int rc, i; 1516 int rc, i;
@@ -1538,7 +1520,6 @@ static __init int nfit_test_init(void)
1538 for (i = 0; i < NUM_NFITS; i++) { 1520 for (i = 0; i < NUM_NFITS; i++) {
1539 struct nfit_test *nfit_test; 1521 struct nfit_test *nfit_test;
1540 struct platform_device *pdev; 1522 struct platform_device *pdev;
1541 static int once;
1542 1523
1543 nfit_test = kzalloc(sizeof(*nfit_test), GFP_KERNEL); 1524 nfit_test = kzalloc(sizeof(*nfit_test), GFP_KERNEL);
1544 if (!nfit_test) { 1525 if (!nfit_test) {
@@ -1577,20 +1558,6 @@ static __init int nfit_test_init(void)
1577 goto err_register; 1558 goto err_register;
1578 1559
1579 instances[i] = nfit_test; 1560 instances[i] = nfit_test;
1580
1581 if (!once++) {
1582 dma_addr_t dma;
1583 void *buf;
1584
1585 buf = dma_alloc_coherent(&pdev->dev, SZ_128M, &dma,
1586 GFP_KERNEL);
1587 if (!buf) {
1588 rc = -ENOMEM;
1589 dev_warn(&pdev->dev, "need 128M of free cma\n");
1590 goto err_register;
1591 }
1592 dma_free_coherent(&pdev->dev, SZ_128M, buf, dma);
1593 }
1594 } 1561 }
1595 1562
1596 rc = platform_driver_register(&nfit_test_driver); 1563 rc = platform_driver_register(&nfit_test_driver);
diff --git a/tools/testing/nvdimm/test/nfit_test.h b/tools/testing/nvdimm/test/nfit_test.h
index 96c5e16d7db9..9f18e2a4a862 100644
--- a/tools/testing/nvdimm/test/nfit_test.h
+++ b/tools/testing/nvdimm/test/nfit_test.h
@@ -12,6 +12,7 @@
12 */ 12 */
13#ifndef __NFIT_TEST_H__ 13#ifndef __NFIT_TEST_H__
14#define __NFIT_TEST_H__ 14#define __NFIT_TEST_H__
15#include <linux/list.h>
15 16
16struct nfit_test_resource { 17struct nfit_test_resource {
17 struct list_head list; 18 struct list_head list;
@@ -26,4 +27,5 @@ void __iomem *__wrap_ioremap_nocache(resource_size_t offset,
26void __wrap_iounmap(volatile void __iomem *addr); 27void __wrap_iounmap(volatile void __iomem *addr);
27void nfit_test_setup(nfit_test_lookup_fn lookup); 28void nfit_test_setup(nfit_test_lookup_fn lookup);
28void nfit_test_teardown(void); 29void nfit_test_teardown(void);
30struct nfit_test_resource *get_nfit_res(resource_size_t resource);
29#endif 31#endif
diff --git a/tools/testing/radix-tree/linux/gfp.h b/tools/testing/radix-tree/linux/gfp.h
index 0e37f7a760eb..5201b915f631 100644
--- a/tools/testing/radix-tree/linux/gfp.h
+++ b/tools/testing/radix-tree/linux/gfp.h
@@ -1,7 +1,7 @@
1#ifndef _GFP_H 1#ifndef _GFP_H
2#define _GFP_H 2#define _GFP_H
3 3
4#define __GFP_BITS_SHIFT 22 4#define __GFP_BITS_SHIFT 26
5#define __GFP_BITS_MASK ((gfp_t)((1 << __GFP_BITS_SHIFT) - 1)) 5#define __GFP_BITS_MASK ((gfp_t)((1 << __GFP_BITS_SHIFT) - 1))
6#define __GFP_WAIT 1 6#define __GFP_WAIT 1
7#define __GFP_ACCOUNT 0 7#define __GFP_ACCOUNT 0
diff --git a/tools/testing/selftests/exec/Makefile b/tools/testing/selftests/exec/Makefile
index 4e400eb83657..d4300602bf37 100644
--- a/tools/testing/selftests/exec/Makefile
+++ b/tools/testing/selftests/exec/Makefile
@@ -18,7 +18,8 @@ execveat.denatured: execveat
18 $(CC) $(CFLAGS) -o $@ $^ 18 $(CC) $(CFLAGS) -o $@ $^
19 19
20TEST_PROGS := execveat 20TEST_PROGS := execveat
21TEST_FILES := $(DEPS) 21# Makefile is a run-time dependency, since it's accessed by the execveat test
22TEST_FILES := $(DEPS) Makefile
22 23
23include ../lib.mk 24include ../lib.mk
24 25
diff --git a/tools/testing/selftests/lib/printf.sh b/tools/testing/selftests/lib/printf.sh
index 4fdc70fe6980..4fdc70fe6980 100644..100755
--- a/tools/testing/selftests/lib/printf.sh
+++ b/tools/testing/selftests/lib/printf.sh
diff --git a/tools/testing/selftests/media_tests/.gitignore b/tools/testing/selftests/media_tests/.gitignore
index 1c0711708b98..8745eba39012 100644
--- a/tools/testing/selftests/media_tests/.gitignore
+++ b/tools/testing/selftests/media_tests/.gitignore
@@ -1 +1,3 @@
1media_device_test 1media_device_test
2media_device_open
3video_device_test
diff --git a/tools/testing/selftests/media_tests/Makefile b/tools/testing/selftests/media_tests/Makefile
index 7071bcc1d066..6b34a0199468 100644
--- a/tools/testing/selftests/media_tests/Makefile
+++ b/tools/testing/selftests/media_tests/Makefile
@@ -1,7 +1,7 @@
1TEST_PROGS := media_device_test 1TEST_PROGS := media_device_test media_device_open video_device_test
2all: $(TEST_PROGS) 2all: $(TEST_PROGS)
3 3
4include ../lib.mk 4include ../lib.mk
5 5
6clean: 6clean:
7 rm -fr media_device_test 7 rm -fr media_device_test media_device_open video_device_test
diff --git a/tools/testing/selftests/media_tests/bind_unbind_sample.sh b/tools/testing/selftests/media_tests/bind_unbind_sample.sh
new file mode 100755
index 000000000000..9f362f10631a
--- /dev/null
+++ b/tools/testing/selftests/media_tests/bind_unbind_sample.sh
@@ -0,0 +1,12 @@
1#!/bin/bash
2# Find device number in /sys/bus/usb/drivers/drivername
3# Edit this file to update the driver numer and name
4# Example test for uvcvideo driver
5#i=0
6# while :; do
7# i=$((i+1))
8# echo 1-5:1.0 > /sys/bus/usb/drivers/uvcvideo/unbind;
9# echo 1-5:1.0 > /sys/bus/usb/drivers/uvcvideo/bind;
10# clear
11# echo $i
12#done
diff --git a/tools/testing/selftests/media_tests/media_device_open.c b/tools/testing/selftests/media_tests/media_device_open.c
new file mode 100644
index 000000000000..44343c091a20
--- /dev/null
+++ b/tools/testing/selftests/media_tests/media_device_open.c
@@ -0,0 +1,81 @@
1/*
2 * media_device_open.c - Media Controller Device Open Test
3 *
4 * Copyright (c) 2016 Shuah Khan <shuahkh@osg.samsung.com>
5 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
6 *
7 * This file is released under the GPLv2.
8 */
9
10/*
11 * This file adds a test for Media Controller API.
12 * This test should be run as root and should not be
13 * included in the Kselftest run. This test should be
14 * run when hardware and driver that makes use Media
15 * Controller API are present in the system.
16 *
17 * This test opens user specified Media Device and calls
18 * MEDIA_IOC_DEVICE_INFO ioctl, closes the file, and exits.
19 *
20 * Usage:
21 * sudo ./media_device_open -d /dev/mediaX
22 *
23 * Run this test is a loop and run bind/unbind on the driver.
24*/
25
26#include <stdio.h>
27#include <unistd.h>
28#include <stdlib.h>
29#include <errno.h>
30#include <string.h>
31#include <fcntl.h>
32#include <sys/ioctl.h>
33#include <sys/stat.h>
34#include <linux/media.h>
35
36int main(int argc, char **argv)
37{
38 int opt;
39 char media_device[256];
40 int count = 0;
41 struct media_device_info mdi;
42 int ret;
43 int fd;
44
45 if (argc < 2) {
46 printf("Usage: %s [-d </dev/mediaX>]\n", argv[0]);
47 exit(-1);
48 }
49
50 /* Process arguments */
51 while ((opt = getopt(argc, argv, "d:")) != -1) {
52 switch (opt) {
53 case 'd':
54 strncpy(media_device, optarg, sizeof(media_device) - 1);
55 media_device[sizeof(media_device)-1] = '\0';
56 break;
57 default:
58 printf("Usage: %s [-d </dev/mediaX>]\n", argv[0]);
59 exit(-1);
60 }
61 }
62
63 if (getuid() != 0) {
64 printf("Please run the test as root - Exiting.\n");
65 exit(-1);
66 }
67
68 /* Open Media device and keep it open */
69 fd = open(media_device, O_RDWR);
70 if (fd == -1) {
71 printf("Media Device open errno %s\n", strerror(errno));
72 exit(-1);
73 }
74
75 ret = ioctl(fd, MEDIA_IOC_DEVICE_INFO, &mdi);
76 if (ret < 0)
77 printf("Media Device Info errno %s\n", strerror(errno));
78 else
79 printf("Media device model %s driver %s\n",
80 mdi.model, mdi.driver);
81}
diff --git a/tools/testing/selftests/media_tests/media_device_test.c b/tools/testing/selftests/media_tests/media_device_test.c
index cbf53a032ab5..5d49943e77d0 100644
--- a/tools/testing/selftests/media_tests/media_device_test.c
+++ b/tools/testing/selftests/media_tests/media_device_test.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * media_devkref_test.c - Media Controller Device Kref API Test 2 * media_device_test.c - Media Controller Device ioctl loop Test
3 * 3 *
4 * Copyright (c) 2016 Shuah Khan <shuahkh@osg.samsung.com> 4 * Copyright (c) 2016 Shuah Khan <shuahkh@osg.samsung.com>
5 * Copyright (c) 2016 Samsung Electronics Co., Ltd. 5 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
@@ -35,13 +35,14 @@
35#include <fcntl.h> 35#include <fcntl.h>
36#include <sys/ioctl.h> 36#include <sys/ioctl.h>
37#include <sys/stat.h> 37#include <sys/stat.h>
38#include <time.h>
38#include <linux/media.h> 39#include <linux/media.h>
39 40
40int main(int argc, char **argv) 41int main(int argc, char **argv)
41{ 42{
42 int opt; 43 int opt;
43 char media_device[256]; 44 char media_device[256];
44 int count = 0; 45 int count;
45 struct media_device_info mdi; 46 struct media_device_info mdi;
46 int ret; 47 int ret;
47 int fd; 48 int fd;
@@ -69,6 +70,10 @@ int main(int argc, char **argv)
69 exit(-1); 70 exit(-1);
70 } 71 }
71 72
73 /* Generate random number of interations */
74 srand((unsigned int) time(NULL));
75 count = rand();
76
72 /* Open Media device and keep it open */ 77 /* Open Media device and keep it open */
73 fd = open(media_device, O_RDWR); 78 fd = open(media_device, O_RDWR);
74 if (fd == -1) { 79 if (fd == -1) {
@@ -82,14 +87,16 @@ int main(int argc, char **argv)
82 "other Oops in the dmesg. Enable KaSan kernel\n" 87 "other Oops in the dmesg. Enable KaSan kernel\n"
83 "config option for use-after-free error detection.\n\n"); 88 "config option for use-after-free error detection.\n\n");
84 89
85 while (count < 100) { 90 printf("Running test for %d iternations\n", count);
91
92 while (count > 0) {
86 ret = ioctl(fd, MEDIA_IOC_DEVICE_INFO, &mdi); 93 ret = ioctl(fd, MEDIA_IOC_DEVICE_INFO, &mdi);
87 if (ret < 0) 94 if (ret < 0)
88 printf("Media Device Info errno %s\n", strerror(errno)); 95 printf("Media Device Info errno %s\n", strerror(errno));
89 else 96 else
90 printf("Media device model %s driver %s\n", 97 printf("Media device model %s driver %s - count %d\n",
91 mdi.model, mdi.driver); 98 mdi.model, mdi.driver, count);
92 sleep(10); 99 sleep(10);
93 count++; 100 count--;
94 } 101 }
95} 102}
diff --git a/tools/testing/selftests/media_tests/open_loop_test.sh b/tools/testing/selftests/media_tests/open_loop_test.sh
new file mode 100755
index 000000000000..dcd3c17efc17
--- /dev/null
+++ b/tools/testing/selftests/media_tests/open_loop_test.sh
@@ -0,0 +1,10 @@
1#!/bin/bash
2 i=0
3file=/dev/media$1
4 while :; do
5 echo $file
6 i=$((i+1))
7 R=$(./media_device_open -d $file);
8 # clear
9 echo -e "Loop $i\n$R"
10 done
diff --git a/tools/testing/selftests/media_tests/regression_test.txt b/tools/testing/selftests/media_tests/regression_test.txt
new file mode 100644
index 000000000000..2627367681f7
--- /dev/null
+++ b/tools/testing/selftests/media_tests/regression_test.txt
@@ -0,0 +1,43 @@
1Testing for regressions in Media Controller API register, ioctl, syscall,
2and unregister paths. There have a few problems that result in user-after
3free on media_device, media_devnode, and cdev pointers when the driver is
4unbound while ioctl is in progress.
5
6Test Procedure:
7
8Run bin/unbind loop while ioctls are in progress.
9Run rmmod and modprobe.
10Disconnect the device.
11
12Setup:
13
14Build media_device_test
15cd tools/testing/selftests/media_tests
16make
17
18Regressions test for cdev user-after free error on /dev/mediaX when driver
19is unbound:
20
21Start media_device_test to regression test media devnode dynamic alloc
22and cdev user-after-free fixes. This opens media dev files and sits in
23a loop running media ioctl MEDIA_IOC_DEVICE_INFO command once every 10
24seconds. The idea is when device file goes away, media devnode and cdev
25should stick around until this test exits.
26
27The test for a random number of iterations or until user kills it with a
28sleep 10 in between the ioctl calls.
29
30sudo ./media_device_test -d /dev/mediaX
31
32Regression test for media_devnode unregister race with ioctl_syscall:
33
34Start 6 open_loop_test.sh tests with different /dev/mediaX files. When
35device file goes away after unbind, device file name changes. Start the
36test with possible device names. If we start with /dev/media0 for example,
37after unbind, /dev/media1 or /dev/media2 could get created. The idea is
38keep ioctls going while bind/unbind runs.
39
40Copy bind_unbind_sample.txt and make changes to specify the driver name
41and number to run bind and unbind. Start the bind_unbind.sh
42
43Run dmesg looking for any user-after free errors or mutex lock errors.
diff --git a/tools/testing/selftests/media_tests/video_device_test.c b/tools/testing/selftests/media_tests/video_device_test.c
new file mode 100644
index 000000000000..66d419c28653
--- /dev/null
+++ b/tools/testing/selftests/media_tests/video_device_test.c
@@ -0,0 +1,100 @@
1/*
2 * video_device_test - Video Device Test
3 *
4 * Copyright (c) 2016 Shuah Khan <shuahkh@osg.samsung.com>
5 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
6 *
7 * This file is released under the GPLv2.
8 */
9
10/*
11 * This file adds a test for Video Device. This test should not be included
12 * in the Kselftest run. This test should be run when hardware and driver
13 * that makes use of V4L2 API is present.
14 *
15 * This test opens user specified Video Device and calls video ioctls in a
16 * loop once every 10 seconds.
17 *
18 * Usage:
19 * sudo ./video_device_test -d /dev/videoX
20 *
21 * While test is running, remove the device or unbind the driver and
22 * ensure there are no use after free errors and other Oops in the
23 * dmesg.
24 * When possible, enable KaSan kernel config option for use-after-free
25 * error detection.
26*/
27
28#include <stdio.h>
29#include <unistd.h>
30#include <stdlib.h>
31#include <errno.h>
32#include <string.h>
33#include <fcntl.h>
34#include <sys/ioctl.h>
35#include <sys/stat.h>
36#include <time.h>
37#include <linux/videodev2.h>
38
39int main(int argc, char **argv)
40{
41 int opt;
42 char video_dev[256];
43 int count;
44 struct v4l2_tuner vtuner;
45 struct v4l2_capability vcap;
46 int ret;
47 int fd;
48
49 if (argc < 2) {
50 printf("Usage: %s [-d </dev/videoX>]\n", argv[0]);
51 exit(-1);
52 }
53
54 /* Process arguments */
55 while ((opt = getopt(argc, argv, "d:")) != -1) {
56 switch (opt) {
57 case 'd':
58 strncpy(video_dev, optarg, sizeof(video_dev) - 1);
59 video_dev[sizeof(video_dev)-1] = '\0';
60 break;
61 default:
62 printf("Usage: %s [-d </dev/videoX>]\n", argv[0]);
63 exit(-1);
64 }
65 }
66
67 /* Generate random number of interations */
68 srand((unsigned int) time(NULL));
69 count = rand();
70
71 /* Open Video device and keep it open */
72 fd = open(video_dev, O_RDWR);
73 if (fd == -1) {
74 printf("Video Device open errno %s\n", strerror(errno));
75 exit(-1);
76 }
77
78 printf("\nNote:\n"
79 "While test is running, remove the device or unbind\n"
80 "driver and ensure there are no use after free errors\n"
81 "and other Oops in the dmesg. When possible, enable KaSan\n"
82 "kernel config option for use-after-free error detection.\n\n");
83
84 while (count > 0) {
85 ret = ioctl(fd, VIDIOC_QUERYCAP, &vcap);
86 if (ret < 0)
87 printf("VIDIOC_QUERYCAP errno %s\n", strerror(errno));
88 else
89 printf("Video device driver %s\n", vcap.driver);
90
91 ret = ioctl(fd, VIDIOC_G_TUNER, &vtuner);
92 if (ret < 0)
93 printf("VIDIOC_G_TUNER, errno %s\n", strerror(errno));
94 else
95 printf("type %d rangelow %d rangehigh %d\n",
96 vtuner.type, vtuner.rangelow, vtuner.rangehigh);
97 sleep(10);
98 count--;
99 }
100}
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
index 4ca83fe80654..3c40c9d0e6c7 100644
--- a/tools/testing/selftests/powerpc/Makefile
+++ b/tools/testing/selftests/powerpc/Makefile
@@ -12,7 +12,8 @@ CFLAGS := -Wall -O2 -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CURDIR) $
12 12
13export CFLAGS 13export CFLAGS
14 14
15SUB_DIRS = benchmarks \ 15SUB_DIRS = alignment \
16 benchmarks \
16 copyloops \ 17 copyloops \
17 context_switch \ 18 context_switch \
18 dscr \ 19 dscr \
diff --git a/tools/testing/selftests/powerpc/alignment/.gitignore b/tools/testing/selftests/powerpc/alignment/.gitignore
new file mode 100644
index 000000000000..1d980e3d7039
--- /dev/null
+++ b/tools/testing/selftests/powerpc/alignment/.gitignore
@@ -0,0 +1,5 @@
1copy_unaligned
2copy_first_unaligned
3paste_unaligned
4paste_last_unaligned
5copy_paste_unaligned_common
diff --git a/tools/testing/selftests/powerpc/alignment/Makefile b/tools/testing/selftests/powerpc/alignment/Makefile
new file mode 100644
index 000000000000..ad6a4e49da91
--- /dev/null
+++ b/tools/testing/selftests/powerpc/alignment/Makefile
@@ -0,0 +1,10 @@
1TEST_PROGS := copy_unaligned copy_first_unaligned paste_unaligned paste_last_unaligned
2
3all: $(TEST_PROGS)
4
5$(TEST_PROGS): ../harness.c ../utils.c copy_paste_unaligned_common.c
6
7include ../../lib.mk
8
9clean:
10 rm -f $(TEST_PROGS)
diff --git a/tools/testing/selftests/powerpc/alignment/copy_first_unaligned.c b/tools/testing/selftests/powerpc/alignment/copy_first_unaligned.c
new file mode 100644
index 000000000000..47b73b3a08bd
--- /dev/null
+++ b/tools/testing/selftests/powerpc/alignment/copy_first_unaligned.c
@@ -0,0 +1,41 @@
1/*
2 * Copyright 2016, Chris Smart, IBM Corporation.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Calls to copy_first which are not 128-byte aligned should be
10 * caught and sent a SIGBUS.
11 *
12 */
13
14#include <string.h>
15#include <unistd.h>
16#include "utils.h"
17#include "instructions.h"
18#include "copy_paste_unaligned_common.h"
19
20unsigned int expected_instruction = PPC_INST_COPY_FIRST;
21unsigned int instruction_mask = 0xfc2007fe;
22
23int test_copy_first_unaligned(void)
24{
25 /* Only run this test on a P9 or later */
26 SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_00));
27
28 /* Register our signal handler with SIGBUS */
29 setup_signal_handler();
30
31 /* +1 makes buf unaligned */
32 copy_first(cacheline_buf+1);
33
34 /* We should not get here */
35 return 1;
36}
37
38int main(int argc, char *argv[])
39{
40 return test_harness(test_copy_first_unaligned, "test_copy_first_unaligned");
41}
diff --git a/tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.c b/tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.c
new file mode 100644
index 000000000000..d35fa5f5d2d3
--- /dev/null
+++ b/tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.c
@@ -0,0 +1,53 @@
1/*
2 * Copyright 2016, Chris Smart, IBM Corporation.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Common code for copy, copy_first, paste and paste_last unaligned
10 * tests.
11 *
12 */
13
14#include <signal.h>
15#include <string.h>
16#include <unistd.h>
17#include "utils.h"
18#include "instructions.h"
19#include "copy_paste_unaligned_common.h"
20
21unsigned int expected_instruction;
22unsigned int instruction_mask;
23
24char cacheline_buf[128] __cacheline_aligned;
25
26void signal_action_handler(int signal_num, siginfo_t *info, void *ptr)
27{
28 ucontext_t *ctx = ptr;
29#if defined(__powerpc64__)
30 unsigned int *pc = (unsigned int *)ctx->uc_mcontext.gp_regs[PT_NIP];
31#else
32 unsigned int *pc = (unsigned int *)ctx->uc_mcontext.uc_regs->gregs[PT_NIP];
33#endif
34
35 /*
36 * Check that the signal was on the correct instruction, using a
37 * mask because the compiler assigns the register at RB.
38 */
39 if ((*pc & instruction_mask) == expected_instruction)
40 _exit(0); /* We hit the right instruction */
41
42 _exit(1);
43}
44
45void setup_signal_handler(void)
46{
47 struct sigaction signal_action;
48
49 memset(&signal_action, 0, sizeof(signal_action));
50 signal_action.sa_sigaction = signal_action_handler;
51 signal_action.sa_flags = SA_SIGINFO;
52 sigaction(SIGBUS, &signal_action, NULL);
53}
diff --git a/tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.h b/tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.h
new file mode 100644
index 000000000000..053899fe506e
--- /dev/null
+++ b/tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright 2016, Chris Smart, IBM Corporation.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Declarations for common code for copy, copy_first, paste and
10 * paste_last unaligned tests.
11 *
12 */
13
14#ifndef _SELFTESTS_POWERPC_COPY_PASTE_H
15#define _SELFTESTS_POWERPC_COPY_PASTE_H
16
17#include <signal.h>
18
19int main(int argc, char *argv[]);
20void signal_action_handler(int signal_num, siginfo_t *info, void *ptr);
21void setup_signal_handler(void);
22extern char cacheline_buf[128] __cacheline_aligned;
23extern unsigned int expected_instruction;
24extern unsigned int instruction_mask;
25
26#endif /* _SELFTESTS_POWERPC_COPY_PASTE_H */
diff --git a/tools/testing/selftests/powerpc/alignment/copy_unaligned.c b/tools/testing/selftests/powerpc/alignment/copy_unaligned.c
new file mode 100644
index 000000000000..3a4e26461554
--- /dev/null
+++ b/tools/testing/selftests/powerpc/alignment/copy_unaligned.c
@@ -0,0 +1,41 @@
1/*
2 * Copyright 2016, Chris Smart, IBM Corporation.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Calls to copy which are not 128-byte aligned should be caught
10 * and sent a SIGBUS.
11 *
12 */
13
14#include <string.h>
15#include <unistd.h>
16#include "utils.h"
17#include "instructions.h"
18#include "copy_paste_unaligned_common.h"
19
20unsigned int expected_instruction = PPC_INST_COPY;
21unsigned int instruction_mask = 0xfc0007fe;
22
23int test_copy_unaligned(void)
24{
25 /* Only run this test on a P9 or later */
26 SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_00));
27
28 /* Register our signal handler with SIGBUS */
29 setup_signal_handler();
30
31 /* +1 makes buf unaligned */
32 copy(cacheline_buf+1);
33
34 /* We should not get here */
35 return 1;
36}
37
38int main(int argc, char *argv[])
39{
40 return test_harness(test_copy_unaligned, "test_copy_unaligned");
41}
diff --git a/tools/testing/selftests/powerpc/alignment/paste_last_unaligned.c b/tools/testing/selftests/powerpc/alignment/paste_last_unaligned.c
new file mode 100644
index 000000000000..6e0ad045fcc3
--- /dev/null
+++ b/tools/testing/selftests/powerpc/alignment/paste_last_unaligned.c
@@ -0,0 +1,43 @@
1/*
2 * Copyright 2016, Chris Smart, IBM Corporation.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Calls to paste_last which are not 128-byte aligned should be
10 * caught and sent a SIGBUS.
11 *
12 */
13
14#include <string.h>
15#include <unistd.h>
16#include "utils.h"
17#include "instructions.h"
18#include "copy_paste_unaligned_common.h"
19
20unsigned int expected_instruction = PPC_INST_PASTE_LAST;
21unsigned int instruction_mask = 0xfc2007ff;
22
23int test_paste_last_unaligned(void)
24{
25 /* Only run this test on a P9 or later */
26 SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_00));
27
28 /* Register our signal handler with SIGBUS */
29 setup_signal_handler();
30
31 copy(cacheline_buf);
32
33 /* +1 makes buf unaligned */
34 paste_last(cacheline_buf+1);
35
36 /* We should not get here */
37 return 1;
38}
39
40int main(int argc, char *argv[])
41{
42 return test_harness(test_paste_last_unaligned, "test_paste_last_unaligned");
43}
diff --git a/tools/testing/selftests/powerpc/alignment/paste_unaligned.c b/tools/testing/selftests/powerpc/alignment/paste_unaligned.c
new file mode 100644
index 000000000000..6f982b45e4bd
--- /dev/null
+++ b/tools/testing/selftests/powerpc/alignment/paste_unaligned.c
@@ -0,0 +1,43 @@
1/*
2 * Copyright 2016, Chris Smart, IBM Corporation.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Calls to paste which are not 128-byte aligned should be caught
10 * and sent a SIGBUS.
11 *
12 */
13
14#include <string.h>
15#include <unistd.h>
16#include "utils.h"
17#include "instructions.h"
18#include "copy_paste_unaligned_common.h"
19
20unsigned int expected_instruction = PPC_INST_PASTE;
21unsigned int instruction_mask = 0xfc0007fe;
22
23int test_paste_unaligned(void)
24{
25 /* Only run this test on a P9 or later */
26 SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_00));
27
28 /* Register our signal handler with SIGBUS */
29 setup_signal_handler();
30
31 copy(cacheline_buf);
32
33 /* +1 makes buf unaligned */
34 paste(cacheline_buf+1);
35
36 /* We should not get here */
37 return 1;
38}
39
40int main(int argc, char *argv[])
41{
42 return test_harness(test_paste_unaligned, "test_paste_unaligned");
43}
diff --git a/tools/testing/selftests/powerpc/benchmarks/.gitignore b/tools/testing/selftests/powerpc/benchmarks/.gitignore
index 6fa673316ac2..bce49ebd869e 100644
--- a/tools/testing/selftests/powerpc/benchmarks/.gitignore
+++ b/tools/testing/selftests/powerpc/benchmarks/.gitignore
@@ -1,2 +1,4 @@
1gettimeofday 1gettimeofday
2context_switch 2context_switch
3mmap_bench
4futex_bench \ No newline at end of file
diff --git a/tools/testing/selftests/powerpc/benchmarks/Makefile b/tools/testing/selftests/powerpc/benchmarks/Makefile
index 912445ff7ce7..a9adfb7de78f 100644
--- a/tools/testing/selftests/powerpc/benchmarks/Makefile
+++ b/tools/testing/selftests/powerpc/benchmarks/Makefile
@@ -1,4 +1,4 @@
1TEST_PROGS := gettimeofday context_switch 1TEST_PROGS := gettimeofday context_switch mmap_bench futex_bench
2 2
3CFLAGS += -O2 3CFLAGS += -O2
4 4
@@ -7,6 +7,7 @@ all: $(TEST_PROGS)
7$(TEST_PROGS): ../harness.c 7$(TEST_PROGS): ../harness.c
8 8
9context_switch: ../utils.c 9context_switch: ../utils.c
10context_switch: CFLAGS += -maltivec -mvsx -mabi=altivec
10context_switch: LDLIBS += -lpthread 11context_switch: LDLIBS += -lpthread
11 12
12include ../../lib.mk 13include ../../lib.mk
diff --git a/tools/testing/selftests/powerpc/benchmarks/context_switch.c b/tools/testing/selftests/powerpc/benchmarks/context_switch.c
index 7b785941adec..a36883ad48a4 100644
--- a/tools/testing/selftests/powerpc/benchmarks/context_switch.c
+++ b/tools/testing/selftests/powerpc/benchmarks/context_switch.c
@@ -25,7 +25,9 @@
25#include <sys/types.h> 25#include <sys/types.h>
26#include <sys/shm.h> 26#include <sys/shm.h>
27#include <linux/futex.h> 27#include <linux/futex.h>
28 28#ifdef __powerpc__
29#include <altivec.h>
30#endif
29#include "../utils.h" 31#include "../utils.h"
30 32
31static unsigned int timeout = 30; 33static unsigned int timeout = 30;
@@ -37,12 +39,15 @@ static int touch_fp = 1;
37double fp; 39double fp;
38 40
39static int touch_vector = 1; 41static int touch_vector = 1;
40typedef int v4si __attribute__ ((vector_size (16))); 42vector int a, b, c;
41v4si a, b, c;
42 43
43#ifdef __powerpc__ 44#ifdef __powerpc__
44static int touch_altivec = 1; 45static int touch_altivec = 1;
45 46
47/*
48 * Note: LTO (Link Time Optimisation) doesn't play well with this function
49 * attribute. Be very careful enabling LTO for this test.
50 */
46static void __attribute__((__target__("no-vsx"))) altivec_touch_fn(void) 51static void __attribute__((__target__("no-vsx"))) altivec_touch_fn(void)
47{ 52{
48 c = a + b; 53 c = a + b;
@@ -369,11 +374,11 @@ static void usage(void)
369 fprintf(stderr, "\t\t--process\tUse processes (default threads)\n"); 374 fprintf(stderr, "\t\t--process\tUse processes (default threads)\n");
370 fprintf(stderr, "\t\t--timeout=X\tDuration in seconds to run (default 30)\n"); 375 fprintf(stderr, "\t\t--timeout=X\tDuration in seconds to run (default 30)\n");
371 fprintf(stderr, "\t\t--vdso\t\ttouch VDSO\n"); 376 fprintf(stderr, "\t\t--vdso\t\ttouch VDSO\n");
372 fprintf(stderr, "\t\t--fp\t\ttouch FP\n"); 377 fprintf(stderr, "\t\t--no-fp\t\tDon't touch FP\n");
373#ifdef __powerpc__ 378#ifdef __powerpc__
374 fprintf(stderr, "\t\t--altivec\ttouch altivec\n"); 379 fprintf(stderr, "\t\t--no-altivec\tDon't touch altivec\n");
375#endif 380#endif
376 fprintf(stderr, "\t\t--vector\ttouch vector\n"); 381 fprintf(stderr, "\t\t--no-vector\tDon't touch vector\n");
377} 382}
378 383
379int main(int argc, char *argv[]) 384int main(int argc, char *argv[])
diff --git a/tools/testing/selftests/powerpc/benchmarks/futex_bench.c b/tools/testing/selftests/powerpc/benchmarks/futex_bench.c
new file mode 100644
index 000000000000..2fc711d9150d
--- /dev/null
+++ b/tools/testing/selftests/powerpc/benchmarks/futex_bench.c
@@ -0,0 +1,42 @@
1/*
2 * Copyright 2016, Anton Blanchard, Michael Ellerman, IBM Corp.
3 * Licensed under GPLv2.
4 */
5
6#define _GNU_SOURCE
7
8#include <stdio.h>
9#include <sys/syscall.h>
10#include <time.h>
11#include <unistd.h>
12#include <linux/futex.h>
13
14#include "utils.h"
15
16#define ITERATIONS 100000000
17
18#define futex(A, B, C, D, E, F) syscall(__NR_futex, A, B, C, D, E, F)
19
20int test_futex(void)
21{
22 struct timespec ts_start, ts_end;
23 unsigned long i = ITERATIONS;
24
25 clock_gettime(CLOCK_MONOTONIC, &ts_start);
26
27 while (i--) {
28 unsigned int addr = 0;
29 futex(&addr, FUTEX_WAKE, 1, NULL, NULL, 0);
30 }
31
32 clock_gettime(CLOCK_MONOTONIC, &ts_end);
33
34 printf("time = %.6f\n", ts_end.tv_sec - ts_start.tv_sec + (ts_end.tv_nsec - ts_start.tv_nsec) / 1e9);
35
36 return 0;
37}
38
39int main(void)
40{
41 return test_harness(test_futex, "futex_bench");
42}
diff --git a/tools/testing/selftests/powerpc/benchmarks/mmap_bench.c b/tools/testing/selftests/powerpc/benchmarks/mmap_bench.c
new file mode 100644
index 000000000000..8d084a2d6e74
--- /dev/null
+++ b/tools/testing/selftests/powerpc/benchmarks/mmap_bench.c
@@ -0,0 +1,41 @@
1/*
2 * Copyright 2016, Anton Blanchard, Michael Ellerman, IBM Corp.
3 * Licensed under GPLv2.
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <sys/mman.h>
9#include <time.h>
10
11#include "utils.h"
12
13#define ITERATIONS 5000000
14
15#define MEMSIZE (128 * 1024 * 1024)
16
17int test_mmap(void)
18{
19 struct timespec ts_start, ts_end;
20 unsigned long i = ITERATIONS;
21
22 clock_gettime(CLOCK_MONOTONIC, &ts_start);
23
24 while (i--) {
25 char *c = mmap(NULL, MEMSIZE, PROT_READ|PROT_WRITE,
26 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
27 FAIL_IF(c == MAP_FAILED);
28 munmap(c, MEMSIZE);
29 }
30
31 clock_gettime(CLOCK_MONOTONIC, &ts_end);
32
33 printf("time = %.6f\n", ts_end.tv_sec - ts_start.tv_sec + (ts_end.tv_nsec - ts_start.tv_nsec) / 1e9);
34
35 return 0;
36}
37
38int main(void)
39{
40 return test_harness(test_mmap, "mmap_bench");
41}
diff --git a/tools/testing/selftests/powerpc/instructions.h b/tools/testing/selftests/powerpc/instructions.h
new file mode 100644
index 000000000000..0fb0bd3b28c9
--- /dev/null
+++ b/tools/testing/selftests/powerpc/instructions.h
@@ -0,0 +1,68 @@
1#ifndef _SELFTESTS_POWERPC_INSTRUCTIONS_H
2#define _SELFTESTS_POWERPC_INSTRUCTIONS_H
3
4#include <stdio.h>
5#include <stdlib.h>
6
7/* This defines the "copy" instruction from Power ISA 3.0 Book II, section 4.4. */
8#define __COPY(RA, RB, L) \
9 (0x7c00060c | (RA) << (31-15) | (RB) << (31-20) | (L) << (31-10))
10#define COPY(RA, RB, L) \
11 .long __COPY((RA), (RB), (L))
12
13static inline void copy(void *i)
14{
15 asm volatile(str(COPY(0, %0, 0))";"
16 :
17 : "b" (i)
18 : "memory"
19 );
20}
21
22static inline void copy_first(void *i)
23{
24 asm volatile(str(COPY(0, %0, 1))";"
25 :
26 : "b" (i)
27 : "memory"
28 );
29}
30
31/* This defines the "paste" instruction from Power ISA 3.0 Book II, section 4.4. */
32#define __PASTE(RA, RB, L, RC) \
33 (0x7c00070c | (RA) << (31-15) | (RB) << (31-20) | (L) << (31-10) | (RC) << (31-31))
34#define PASTE(RA, RB, L, RC) \
35 .long __PASTE((RA), (RB), (L), (RC))
36
37static inline int paste(void *i)
38{
39 int cr;
40
41 asm volatile(str(PASTE(0, %1, 0, 0))";"
42 "mfcr %0;"
43 : "=r" (cr)
44 : "b" (i)
45 : "memory"
46 );
47 return cr;
48}
49
50static inline int paste_last(void *i)
51{
52 int cr;
53
54 asm volatile(str(PASTE(0, %1, 1, 1))";"
55 "mfcr %0;"
56 : "=r" (cr)
57 : "b" (i)
58 : "memory"
59 );
60 return cr;
61}
62
63#define PPC_INST_COPY __COPY(0, 0, 0)
64#define PPC_INST_COPY_FIRST __COPY(0, 0, 1)
65#define PPC_INST_PASTE __PASTE(0, 0, 0, 0)
66#define PPC_INST_PASTE_LAST __PASTE(0, 0, 1, 1)
67
68#endif /* _SELFTESTS_POWERPC_INSTRUCTIONS_H */
diff --git a/tools/testing/selftests/powerpc/mm/.gitignore b/tools/testing/selftests/powerpc/mm/.gitignore
index b43ade0ec861..e715a3f2fbf4 100644
--- a/tools/testing/selftests/powerpc/mm/.gitignore
+++ b/tools/testing/selftests/powerpc/mm/.gitignore
@@ -1,3 +1,4 @@
1hugetlb_vs_thp_test 1hugetlb_vs_thp_test
2subpage_prot 2subpage_prot
3tempfile 3tempfile
4prot_sao \ No newline at end of file
diff --git a/tools/testing/selftests/powerpc/mm/Makefile b/tools/testing/selftests/powerpc/mm/Makefile
index ee179e22308c..3bdb96eae558 100644
--- a/tools/testing/selftests/powerpc/mm/Makefile
+++ b/tools/testing/selftests/powerpc/mm/Makefile
@@ -1,13 +1,15 @@
1noarg: 1noarg:
2 $(MAKE) -C ../ 2 $(MAKE) -C ../
3 3
4TEST_PROGS := hugetlb_vs_thp_test subpage_prot 4TEST_PROGS := hugetlb_vs_thp_test subpage_prot prot_sao
5TEST_FILES := tempfile 5TEST_FILES := tempfile
6 6
7all: $(TEST_PROGS) $(TEST_FILES) 7all: $(TEST_PROGS) $(TEST_FILES)
8 8
9$(TEST_PROGS): ../harness.c 9$(TEST_PROGS): ../harness.c
10 10
11prot_sao: ../utils.c
12
11include ../../lib.mk 13include ../../lib.mk
12 14
13tempfile: 15tempfile:
diff --git a/tools/testing/selftests/powerpc/mm/prot_sao.c b/tools/testing/selftests/powerpc/mm/prot_sao.c
new file mode 100644
index 000000000000..611530d43fa9
--- /dev/null
+++ b/tools/testing/selftests/powerpc/mm/prot_sao.c
@@ -0,0 +1,42 @@
1/*
2 * Copyright 2016, Michael Ellerman, IBM Corp.
3 * Licensed under GPLv2.
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include <sys/mman.h>
10
11#include <asm/cputable.h>
12
13#include "utils.h"
14
15#define SIZE (64 * 1024)
16
17int test_prot_sao(void)
18{
19 char *p;
20
21 /* 2.06 or later should support SAO */
22 SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_06));
23
24 /*
25 * Ensure we can ask for PROT_SAO.
26 * We can't really verify that it does the right thing, but at least we
27 * confirm the kernel will accept it.
28 */
29 p = mmap(NULL, SIZE, PROT_READ | PROT_WRITE | PROT_SAO,
30 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
31 FAIL_IF(p == MAP_FAILED);
32
33 /* Write to the mapping, to at least cause a fault */
34 memset(p, 0xaa, SIZE);
35
36 return 0;
37}
38
39int main(void)
40{
41 return test_harness(test_prot_sao, "prot-sao");
42}
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/.gitignore b/tools/testing/selftests/powerpc/pmu/ebb/.gitignore
index 42bddbed8b64..44b7df14a936 100644
--- a/tools/testing/selftests/powerpc/pmu/ebb/.gitignore
+++ b/tools/testing/selftests/powerpc/pmu/ebb/.gitignore
@@ -20,3 +20,5 @@ back_to_back_ebbs_test
20lost_exception_test 20lost_exception_test
21no_handler_test 21no_handler_test
22cycles_with_mmcr2_test 22cycles_with_mmcr2_test
23ebb_lmr
24ebb_lmr_regs \ No newline at end of file
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/Makefile b/tools/testing/selftests/powerpc/pmu/ebb/Makefile
index 8d2279c4bb4b..6b0453e60d53 100644
--- a/tools/testing/selftests/powerpc/pmu/ebb/Makefile
+++ b/tools/testing/selftests/powerpc/pmu/ebb/Makefile
@@ -14,7 +14,7 @@ TEST_PROGS := reg_access_test event_attributes_test cycles_test \
14 fork_cleanup_test ebb_on_child_test \ 14 fork_cleanup_test ebb_on_child_test \
15 ebb_on_willing_child_test back_to_back_ebbs_test \ 15 ebb_on_willing_child_test back_to_back_ebbs_test \
16 lost_exception_test no_handler_test \ 16 lost_exception_test no_handler_test \
17 cycles_with_mmcr2_test 17 cycles_with_mmcr2_test ebb_lmr ebb_lmr_regs
18 18
19all: $(TEST_PROGS) 19all: $(TEST_PROGS)
20 20
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.c b/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.c
new file mode 100644
index 000000000000..c47ebd55ba4d
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.c
@@ -0,0 +1,143 @@
1/*
2 * Copyright 2016, Jack Miller, IBM Corp.
3 * Licensed under GPLv2.
4 */
5
6#include <stdlib.h>
7#include <stdio.h>
8
9#include "ebb.h"
10#include "ebb_lmr.h"
11
12#define SIZE (32 * 1024 * 1024) /* 32M */
13#define LM_SIZE 0 /* Smallest encoding, 32M */
14
15#define SECTIONS 64 /* 1 per bit in LMSER */
16#define SECTION_SIZE (SIZE / SECTIONS)
17#define SECTION_LONGS (SECTION_SIZE / sizeof(long))
18
19static unsigned long *test_mem;
20
21static int lmr_count = 0;
22
23void ebb_lmr_handler(void)
24{
25 lmr_count++;
26}
27
28void ldmx_full_section(unsigned long *mem, int section)
29{
30 unsigned long *ptr;
31 int i;
32
33 for (i = 0; i < SECTION_LONGS; i++) {
34 ptr = &mem[(SECTION_LONGS * section) + i];
35 ldmx((unsigned long) &ptr);
36 ebb_lmr_reset();
37 }
38}
39
40unsigned long section_masks[] = {
41 0x8000000000000000,
42 0xFF00000000000000,
43 0x0000000F70000000,
44 0x8000000000000001,
45 0xF0F0F0F0F0F0F0F0,
46 0x0F0F0F0F0F0F0F0F,
47 0x0
48};
49
50int ebb_lmr_section_test(unsigned long *mem)
51{
52 unsigned long *mask = section_masks;
53 int i;
54
55 for (; *mask; mask++) {
56 mtspr(SPRN_LMSER, *mask);
57 printf("Testing mask 0x%016lx\n", mfspr(SPRN_LMSER));
58
59 for (i = 0; i < 64; i++) {
60 lmr_count = 0;
61 ldmx_full_section(mem, i);
62 if (*mask & (1UL << (63 - i)))
63 FAIL_IF(lmr_count != SECTION_LONGS);
64 else
65 FAIL_IF(lmr_count);
66 }
67 }
68
69 return 0;
70}
71
72int ebb_lmr(void)
73{
74 int i;
75
76 SKIP_IF(!lmr_is_supported());
77
78 setup_ebb_handler(ebb_lmr_handler);
79
80 ebb_global_enable();
81
82 FAIL_IF(posix_memalign((void **)&test_mem, SIZE, SIZE) != 0);
83
84 mtspr(SPRN_LMSER, 0);
85
86 FAIL_IF(mfspr(SPRN_LMSER) != 0);
87
88 mtspr(SPRN_LMRR, ((unsigned long)test_mem | LM_SIZE));
89
90 FAIL_IF(mfspr(SPRN_LMRR) != ((unsigned long)test_mem | LM_SIZE));
91
92 /* Read every single byte to ensure we get no false positives */
93 for (i = 0; i < SECTIONS; i++)
94 ldmx_full_section(test_mem, i);
95
96 FAIL_IF(lmr_count != 0);
97
98 /* Turn on the first section */
99
100 mtspr(SPRN_LMSER, (1UL << 63));
101 FAIL_IF(mfspr(SPRN_LMSER) != (1UL << 63));
102
103 /* Enable LM (BESCR) */
104
105 mtspr(SPRN_BESCR, mfspr(SPRN_BESCR) | BESCR_LME);
106 FAIL_IF(!(mfspr(SPRN_BESCR) & BESCR_LME));
107
108 ldmx((unsigned long)&test_mem);
109
110 FAIL_IF(lmr_count != 1); // exactly one exception
111 FAIL_IF(mfspr(SPRN_BESCR) & BESCR_LME); // LM now disabled
112 FAIL_IF(!(mfspr(SPRN_BESCR) & BESCR_LMEO)); // occurred bit set
113
114 printf("Simple LMR EBB OK\n");
115
116 /* This shouldn't cause an EBB since it's been disabled */
117 ldmx((unsigned long)&test_mem);
118 FAIL_IF(lmr_count != 1);
119
120 printf("LMR disable on EBB OK\n");
121
122 ebb_lmr_reset();
123
124 /* This should cause an EBB or reset is broken */
125 ldmx((unsigned long)&test_mem);
126 FAIL_IF(lmr_count != 2);
127
128 printf("LMR reset EBB OK\n");
129
130 ebb_lmr_reset();
131
132 return ebb_lmr_section_test(test_mem);
133}
134
135int main(void)
136{
137 int ret = test_harness(ebb_lmr, "ebb_lmr");
138
139 if (test_mem)
140 free(test_mem);
141
142 return ret;
143}
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.h b/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.h
new file mode 100644
index 000000000000..ef50abd557cd
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.h
@@ -0,0 +1,39 @@
1#ifndef _SELFTESTS_POWERPC_PMU_EBB_LMR_H
2#define _SELFTESTS_POWERPC_PMU_EBB_LMR_H
3
4#include "reg.h"
5
6#ifndef PPC_FEATURE2_ARCH_3_00
7#define PPC_FEATURE2_ARCH_3_00 0x00800000
8#endif
9
10#define lmr_is_supported() have_hwcap2(PPC_FEATURE2_ARCH_3_00)
11
12static inline void ebb_lmr_reset(void)
13{
14 unsigned long bescr = mfspr(SPRN_BESCR);
15 bescr &= ~(BESCR_LMEO);
16 bescr |= BESCR_LME;
17 mtspr(SPRN_BESCR, bescr);
18}
19
20#define LDMX(t, a, b)\
21 (0x7c00026a | \
22 (((t) & 0x1f) << 21) | \
23 (((a) & 0x1f) << 16) | \
24 (((b) & 0x1f) << 11))
25
26static inline unsigned long ldmx(unsigned long address)
27{
28 unsigned long ret;
29
30 asm volatile ("mr 9, %1\r\n"
31 ".long " __stringify(LDMX(9, 0, 9)) "\r\n"
32 "mr %0, 9\r\n":"=r"(ret)
33 :"r"(address)
34 :"r9");
35
36 return ret;
37}
38
39#endif
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr_regs.c b/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr_regs.c
new file mode 100644
index 000000000000..aff4241fd88a
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr_regs.c
@@ -0,0 +1,37 @@
1/*
2 * Copyright 2016, Jack Miller, IBM Corp.
3 * Licensed under GPLv2.
4 */
5
6#include <stdlib.h>
7#include <stdio.h>
8#include <unistd.h>
9
10#include "ebb.h"
11#include "ebb_lmr.h"
12
13#define CHECKS 10000
14
15int ebb_lmr_regs(void)
16{
17 int i;
18
19 SKIP_IF(!lmr_is_supported());
20
21 ebb_global_enable();
22
23 for (i = 0; i < CHECKS; i++) {
24 mtspr(SPRN_LMRR, i << 25); // skip size and rsvd bits
25 mtspr(SPRN_LMSER, i);
26
27 FAIL_IF(mfspr(SPRN_LMRR) != (i << 25));
28 FAIL_IF(mfspr(SPRN_LMSER) != i);
29 }
30
31 return 0;
32}
33
34int main(void)
35{
36 return test_harness(ebb_lmr_regs, "ebb_lmr_regs");
37}
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/instruction_count_test.c b/tools/testing/selftests/powerpc/pmu/ebb/instruction_count_test.c
index 5da355135df2..ae9a79086111 100644
--- a/tools/testing/selftests/powerpc/pmu/ebb/instruction_count_test.c
+++ b/tools/testing/selftests/powerpc/pmu/ebb/instruction_count_test.c
@@ -51,7 +51,7 @@ static int do_count_loop(struct event *event, uint64_t instructions,
51 printf("Looped for %lu instructions, overhead %lu\n", instructions, overhead); 51 printf("Looped for %lu instructions, overhead %lu\n", instructions, overhead);
52 printf("Expected %lu\n", expected); 52 printf("Expected %lu\n", expected);
53 printf("Actual %llu\n", event->result.value); 53 printf("Actual %llu\n", event->result.value);
54 printf("Error %ld, %f%%\n", difference, percentage); 54 printf("Delta %ld, %f%%\n", difference, percentage);
55 printf("Took %d EBBs\n", ebb_state.stats.ebb_count); 55 printf("Took %d EBBs\n", ebb_state.stats.ebb_count);
56 } 56 }
57 57
diff --git a/tools/testing/selftests/powerpc/pmu/lib.c b/tools/testing/selftests/powerpc/pmu/lib.c
index a361ad3334ce..8b992fa5b478 100644
--- a/tools/testing/selftests/powerpc/pmu/lib.c
+++ b/tools/testing/selftests/powerpc/pmu/lib.c
@@ -190,7 +190,7 @@ int parse_proc_maps(void)
190 190
191bool require_paranoia_below(int level) 191bool require_paranoia_below(int level)
192{ 192{
193 unsigned long current; 193 long current;
194 char *end, buf[16]; 194 char *end, buf[16];
195 FILE *f; 195 FILE *f;
196 int rc; 196 int rc;
@@ -208,7 +208,7 @@ bool require_paranoia_below(int level)
208 goto out_close; 208 goto out_close;
209 } 209 }
210 210
211 current = strtoul(buf, &end, 10); 211 current = strtol(buf, &end, 10);
212 212
213 if (end == buf) { 213 if (end == buf) {
214 printf("Couldn't parse " PARANOID_PATH "?\n"); 214 printf("Couldn't parse " PARANOID_PATH "?\n");
@@ -216,7 +216,7 @@ bool require_paranoia_below(int level)
216 } 216 }
217 217
218 if (current >= level) 218 if (current >= level)
219 goto out; 219 goto out_close;
220 220
221 rc = 0; 221 rc = 0;
222out_close: 222out_close:
diff --git a/tools/testing/selftests/powerpc/reg.h b/tools/testing/selftests/powerpc/reg.h
index 65bfdeeebdee..fddf368ed82f 100644
--- a/tools/testing/selftests/powerpc/reg.h
+++ b/tools/testing/selftests/powerpc/reg.h
@@ -34,6 +34,11 @@
34 34
35#define BESCR_PMEO 0x1 /* PMU Event-based exception Occurred */ 35#define BESCR_PMEO 0x1 /* PMU Event-based exception Occurred */
36#define BESCR_PME (0x1ul << 32) /* PMU Event-based exception Enable */ 36#define BESCR_PME (0x1ul << 32) /* PMU Event-based exception Enable */
37#define BESCR_LME (0x1ul << 34) /* Load Monitor Enable */
38#define BESCR_LMEO (0x1ul << 2) /* Load Monitor Exception Occurred */
39
40#define SPRN_LMRR 813 /* Load Monitor Region Register */
41#define SPRN_LMSER 814 /* Load Monitor Section Enable Register */
37 42
38#define SPRN_PMC1 771 43#define SPRN_PMC1 771
39#define SPRN_PMC2 772 44#define SPRN_PMC2 772
diff --git a/tools/testing/selftests/powerpc/tm/.gitignore b/tools/testing/selftests/powerpc/tm/.gitignore
index bb942db845bf..82c0a9ce6e74 100644
--- a/tools/testing/selftests/powerpc/tm/.gitignore
+++ b/tools/testing/selftests/powerpc/tm/.gitignore
@@ -6,3 +6,4 @@ tm-vmxcopy
6tm-fork 6tm-fork
7tm-tar 7tm-tar
8tm-tmspr 8tm-tmspr
9tm-exec
diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile
index d0505dbd22d5..9d301d785d9e 100644
--- a/tools/testing/selftests/powerpc/tm/Makefile
+++ b/tools/testing/selftests/powerpc/tm/Makefile
@@ -1,11 +1,14 @@
1TEST_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack tm-vmxcopy tm-fork tm-tar tm-tmspr 1TEST_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack \
2 tm-vmxcopy tm-fork tm-tar tm-tmspr tm-exec tm-execed
2 3
3all: $(TEST_PROGS) 4all: $(TEST_PROGS)
4 5
5$(TEST_PROGS): ../harness.c ../utils.c 6$(TEST_PROGS): ../harness.c ../utils.c
6 7
8CFLAGS += -mhtm
9
7tm-syscall: tm-syscall-asm.S 10tm-syscall: tm-syscall-asm.S
8tm-syscall: CFLAGS += -mhtm -I../../../../../usr/include 11tm-syscall: CFLAGS += -I../../../../../usr/include
9tm-tmspr: CFLAGS += -pthread 12tm-tmspr: CFLAGS += -pthread
10 13
11include ../../lib.mk 14include ../../lib.mk
diff --git a/tools/testing/selftests/powerpc/tm/tm-exec.c b/tools/testing/selftests/powerpc/tm/tm-exec.c
new file mode 100644
index 000000000000..3d27fa0ece04
--- /dev/null
+++ b/tools/testing/selftests/powerpc/tm/tm-exec.c
@@ -0,0 +1,70 @@
1/*
2 * Copyright 2016, Cyril Bur, IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Syscalls can be performed provided the transactions are suspended.
10 * The exec() class of syscall is unique as a new process is loaded.
11 *
12 * It makes little sense for after an exec() call for the previously
13 * suspended transaction to still exist.
14 */
15
16#define _GNU_SOURCE
17#include <errno.h>
18#include <inttypes.h>
19#include <libgen.h>
20#include <pthread.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <unistd.h>
25
26#include "utils.h"
27#include "tm.h"
28
29static char *path;
30
31static int test_exec(void)
32{
33 SKIP_IF(!have_htm());
34
35 asm __volatile__(
36 "tbegin.;"
37 "blt 1f; "
38 "tsuspend.;"
39 "1: ;"
40 : : : "memory");
41
42 execl(path, "tm-exec", "--child", NULL);
43
44 /* Shouldn't get here */
45 perror("execl() failed");
46 return 1;
47}
48
49static int after_exec(void)
50{
51 asm __volatile__(
52 "tbegin.;"
53 "blt 1f;"
54 "tsuspend.;"
55 "1: ;"
56 : : : "memory");
57
58 FAIL_IF(failure_is_nesting());
59 return 0;
60}
61
62int main(int argc, char *argv[])
63{
64 path = argv[0];
65
66 if (argc > 1 && strcmp(argv[1], "--child") == 0)
67 return after_exec();
68
69 return test_harness(test_exec, "tm_exec");
70}
diff --git a/tools/testing/selftests/powerpc/tm/tm-syscall.c b/tools/testing/selftests/powerpc/tm/tm-syscall.c
index 60560cb20e38..454b965a2db3 100644
--- a/tools/testing/selftests/powerpc/tm/tm-syscall.c
+++ b/tools/testing/selftests/powerpc/tm/tm-syscall.c
@@ -27,21 +27,6 @@ unsigned retries = 0;
27#define TEST_DURATION 10 /* seconds */ 27#define TEST_DURATION 10 /* seconds */
28#define TM_RETRIES 100 28#define TM_RETRIES 100
29 29
30long failure_code(void)
31{
32 return __builtin_get_texasru() >> 24;
33}
34
35bool failure_is_persistent(void)
36{
37 return (failure_code() & TM_CAUSE_PERSISTENT) == TM_CAUSE_PERSISTENT;
38}
39
40bool failure_is_syscall(void)
41{
42 return (failure_code() & TM_CAUSE_SYSCALL) == TM_CAUSE_SYSCALL;
43}
44
45pid_t getppid_tm(bool suspend) 30pid_t getppid_tm(bool suspend)
46{ 31{
47 int i; 32 int i;
diff --git a/tools/testing/selftests/powerpc/tm/tm.h b/tools/testing/selftests/powerpc/tm/tm.h
index 24144b25772c..60318bad7d7a 100644
--- a/tools/testing/selftests/powerpc/tm/tm.h
+++ b/tools/testing/selftests/powerpc/tm/tm.h
@@ -6,8 +6,9 @@
6#ifndef _SELFTESTS_POWERPC_TM_TM_H 6#ifndef _SELFTESTS_POWERPC_TM_TM_H
7#define _SELFTESTS_POWERPC_TM_TM_H 7#define _SELFTESTS_POWERPC_TM_TM_H
8 8
9#include <stdbool.h> 9#include <asm/tm.h>
10#include <asm/cputable.h> 10#include <asm/cputable.h>
11#include <stdbool.h>
11 12
12#include "../utils.h" 13#include "../utils.h"
13 14
@@ -31,4 +32,24 @@ static inline bool have_htm_nosc(void)
31#endif 32#endif
32} 33}
33 34
35static inline long failure_code(void)
36{
37 return __builtin_get_texasru() >> 24;
38}
39
40static inline bool failure_is_persistent(void)
41{
42 return (failure_code() & TM_CAUSE_PERSISTENT) == TM_CAUSE_PERSISTENT;
43}
44
45static inline bool failure_is_syscall(void)
46{
47 return (failure_code() & TM_CAUSE_SYSCALL) == TM_CAUSE_SYSCALL;
48}
49
50static inline bool failure_is_nesting(void)
51{
52 return (__builtin_get_texasru() & 0x400000);
53}
54
34#endif /* _SELFTESTS_POWERPC_TM_TM_H */ 55#endif /* _SELFTESTS_POWERPC_TM_TM_H */
diff --git a/tools/testing/selftests/powerpc/utils.h b/tools/testing/selftests/powerpc/utils.h
index a985cfaa535e..fbd33e52ef8f 100644
--- a/tools/testing/selftests/powerpc/utils.h
+++ b/tools/testing/selftests/powerpc/utils.h
@@ -27,6 +27,11 @@ int test_harness(int (test_function)(void), char *name);
27extern void *get_auxv_entry(int type); 27extern void *get_auxv_entry(int type);
28int pick_online_cpu(void); 28int pick_online_cpu(void);
29 29
30static inline bool have_hwcap(unsigned long ftr)
31{
32 return ((unsigned long)get_auxv_entry(AT_HWCAP) & ftr) == ftr;
33}
34
30static inline bool have_hwcap2(unsigned long ftr2) 35static inline bool have_hwcap2(unsigned long ftr2)
31{ 36{
32 return ((unsigned long)get_auxv_entry(AT_HWCAP2) & ftr2) == ftr2; 37 return ((unsigned long)get_auxv_entry(AT_HWCAP2) & ftr2) == ftr2;
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index 2e58549b2f02..03f1fa495d74 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -1021,8 +1021,8 @@ void tracer_stop(int sig)
1021typedef void tracer_func_t(struct __test_metadata *_metadata, 1021typedef void tracer_func_t(struct __test_metadata *_metadata,
1022 pid_t tracee, int status, void *args); 1022 pid_t tracee, int status, void *args);
1023 1023
1024void tracer(struct __test_metadata *_metadata, int fd, pid_t tracee, 1024void start_tracer(struct __test_metadata *_metadata, int fd, pid_t tracee,
1025 tracer_func_t tracer_func, void *args) 1025 tracer_func_t tracer_func, void *args, bool ptrace_syscall)
1026{ 1026{
1027 int ret = -1; 1027 int ret = -1;
1028 struct sigaction action = { 1028 struct sigaction action = {
@@ -1042,12 +1042,16 @@ void tracer(struct __test_metadata *_metadata, int fd, pid_t tracee,
1042 /* Wait for attach stop */ 1042 /* Wait for attach stop */
1043 wait(NULL); 1043 wait(NULL);
1044 1044
1045 ret = ptrace(PTRACE_SETOPTIONS, tracee, NULL, PTRACE_O_TRACESECCOMP); 1045 ret = ptrace(PTRACE_SETOPTIONS, tracee, NULL, ptrace_syscall ?
1046 PTRACE_O_TRACESYSGOOD :
1047 PTRACE_O_TRACESECCOMP);
1046 ASSERT_EQ(0, ret) { 1048 ASSERT_EQ(0, ret) {
1047 TH_LOG("Failed to set PTRACE_O_TRACESECCOMP"); 1049 TH_LOG("Failed to set PTRACE_O_TRACESECCOMP");
1048 kill(tracee, SIGKILL); 1050 kill(tracee, SIGKILL);
1049 } 1051 }
1050 ptrace(PTRACE_CONT, tracee, NULL, 0); 1052 ret = ptrace(ptrace_syscall ? PTRACE_SYSCALL : PTRACE_CONT,
1053 tracee, NULL, 0);
1054 ASSERT_EQ(0, ret);
1051 1055
1052 /* Unblock the tracee */ 1056 /* Unblock the tracee */
1053 ASSERT_EQ(1, write(fd, "A", 1)); 1057 ASSERT_EQ(1, write(fd, "A", 1));
@@ -1063,12 +1067,13 @@ void tracer(struct __test_metadata *_metadata, int fd, pid_t tracee,
1063 /* Child is dead. Time to go. */ 1067 /* Child is dead. Time to go. */
1064 return; 1068 return;
1065 1069
1066 /* Make sure this is a seccomp event. */ 1070 /* Check if this is a seccomp event. */
1067 ASSERT_EQ(true, IS_SECCOMP_EVENT(status)); 1071 ASSERT_EQ(!ptrace_syscall, IS_SECCOMP_EVENT(status));
1068 1072
1069 tracer_func(_metadata, tracee, status, args); 1073 tracer_func(_metadata, tracee, status, args);
1070 1074
1071 ret = ptrace(PTRACE_CONT, tracee, NULL, NULL); 1075 ret = ptrace(ptrace_syscall ? PTRACE_SYSCALL : PTRACE_CONT,
1076 tracee, NULL, 0);
1072 ASSERT_EQ(0, ret); 1077 ASSERT_EQ(0, ret);
1073 } 1078 }
1074 /* Directly report the status of our test harness results. */ 1079 /* Directly report the status of our test harness results. */
@@ -1079,7 +1084,7 @@ void tracer(struct __test_metadata *_metadata, int fd, pid_t tracee,
1079void cont_handler(int num) 1084void cont_handler(int num)
1080{ } 1085{ }
1081pid_t setup_trace_fixture(struct __test_metadata *_metadata, 1086pid_t setup_trace_fixture(struct __test_metadata *_metadata,
1082 tracer_func_t func, void *args) 1087 tracer_func_t func, void *args, bool ptrace_syscall)
1083{ 1088{
1084 char sync; 1089 char sync;
1085 int pipefd[2]; 1090 int pipefd[2];
@@ -1095,7 +1100,8 @@ pid_t setup_trace_fixture(struct __test_metadata *_metadata,
1095 signal(SIGALRM, cont_handler); 1100 signal(SIGALRM, cont_handler);
1096 if (tracer_pid == 0) { 1101 if (tracer_pid == 0) {
1097 close(pipefd[0]); 1102 close(pipefd[0]);
1098 tracer(_metadata, pipefd[1], tracee, func, args); 1103 start_tracer(_metadata, pipefd[1], tracee, func, args,
1104 ptrace_syscall);
1099 syscall(__NR_exit, 0); 1105 syscall(__NR_exit, 0);
1100 } 1106 }
1101 close(pipefd[1]); 1107 close(pipefd[1]);
@@ -1177,7 +1183,7 @@ FIXTURE_SETUP(TRACE_poke)
1177 1183
1178 /* Launch tracer. */ 1184 /* Launch tracer. */
1179 self->tracer = setup_trace_fixture(_metadata, tracer_poke, 1185 self->tracer = setup_trace_fixture(_metadata, tracer_poke,
1180 &self->tracer_args); 1186 &self->tracer_args, false);
1181} 1187}
1182 1188
1183FIXTURE_TEARDOWN(TRACE_poke) 1189FIXTURE_TEARDOWN(TRACE_poke)
@@ -1399,6 +1405,29 @@ void tracer_syscall(struct __test_metadata *_metadata, pid_t tracee,
1399 1405
1400} 1406}
1401 1407
1408void tracer_ptrace(struct __test_metadata *_metadata, pid_t tracee,
1409 int status, void *args)
1410{
1411 int ret, nr;
1412 unsigned long msg;
1413 static bool entry;
1414
1415 /* Make sure we got an empty message. */
1416 ret = ptrace(PTRACE_GETEVENTMSG, tracee, NULL, &msg);
1417 EXPECT_EQ(0, ret);
1418 EXPECT_EQ(0, msg);
1419
1420 /* The only way to tell PTRACE_SYSCALL entry/exit is by counting. */
1421 entry = !entry;
1422 if (!entry)
1423 return;
1424
1425 nr = get_syscall(_metadata, tracee);
1426
1427 if (nr == __NR_getpid)
1428 change_syscall(_metadata, tracee, __NR_getppid);
1429}
1430
1402FIXTURE_DATA(TRACE_syscall) { 1431FIXTURE_DATA(TRACE_syscall) {
1403 struct sock_fprog prog; 1432 struct sock_fprog prog;
1404 pid_t tracer, mytid, mypid, parent; 1433 pid_t tracer, mytid, mypid, parent;
@@ -1440,7 +1469,8 @@ FIXTURE_SETUP(TRACE_syscall)
1440 ASSERT_NE(self->parent, self->mypid); 1469 ASSERT_NE(self->parent, self->mypid);
1441 1470
1442 /* Launch tracer. */ 1471 /* Launch tracer. */
1443 self->tracer = setup_trace_fixture(_metadata, tracer_syscall, NULL); 1472 self->tracer = setup_trace_fixture(_metadata, tracer_syscall, NULL,
1473 false);
1444} 1474}
1445 1475
1446FIXTURE_TEARDOWN(TRACE_syscall) 1476FIXTURE_TEARDOWN(TRACE_syscall)
@@ -1500,6 +1530,130 @@ TEST_F(TRACE_syscall, syscall_dropped)
1500 EXPECT_NE(self->mytid, syscall(__NR_gettid)); 1530 EXPECT_NE(self->mytid, syscall(__NR_gettid));
1501} 1531}
1502 1532
1533TEST_F(TRACE_syscall, skip_after_RET_TRACE)
1534{
1535 struct sock_filter filter[] = {
1536 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
1537 offsetof(struct seccomp_data, nr)),
1538 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getppid, 0, 1),
1539 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO | EPERM),
1540 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
1541 };
1542 struct sock_fprog prog = {
1543 .len = (unsigned short)ARRAY_SIZE(filter),
1544 .filter = filter,
1545 };
1546 long ret;
1547
1548 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1549 ASSERT_EQ(0, ret);
1550
1551 /* Install fixture filter. */
1552 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
1553 ASSERT_EQ(0, ret);
1554
1555 /* Install "errno on getppid" filter. */
1556 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
1557 ASSERT_EQ(0, ret);
1558
1559 /* Tracer will redirect getpid to getppid, and we should see EPERM. */
1560 EXPECT_EQ(-1, syscall(__NR_getpid));
1561 EXPECT_EQ(EPERM, errno);
1562}
1563
1564TEST_F_SIGNAL(TRACE_syscall, kill_after_RET_TRACE, SIGSYS)
1565{
1566 struct sock_filter filter[] = {
1567 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
1568 offsetof(struct seccomp_data, nr)),
1569 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getppid, 0, 1),
1570 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
1571 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
1572 };
1573 struct sock_fprog prog = {
1574 .len = (unsigned short)ARRAY_SIZE(filter),
1575 .filter = filter,
1576 };
1577 long ret;
1578
1579 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1580 ASSERT_EQ(0, ret);
1581
1582 /* Install fixture filter. */
1583 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
1584 ASSERT_EQ(0, ret);
1585
1586 /* Install "death on getppid" filter. */
1587 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
1588 ASSERT_EQ(0, ret);
1589
1590 /* Tracer will redirect getpid to getppid, and we should die. */
1591 EXPECT_NE(self->mypid, syscall(__NR_getpid));
1592}
1593
1594TEST_F(TRACE_syscall, skip_after_ptrace)
1595{
1596 struct sock_filter filter[] = {
1597 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
1598 offsetof(struct seccomp_data, nr)),
1599 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getppid, 0, 1),
1600 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO | EPERM),
1601 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
1602 };
1603 struct sock_fprog prog = {
1604 .len = (unsigned short)ARRAY_SIZE(filter),
1605 .filter = filter,
1606 };
1607 long ret;
1608
1609 /* Swap SECCOMP_RET_TRACE tracer for PTRACE_SYSCALL tracer. */
1610 teardown_trace_fixture(_metadata, self->tracer);
1611 self->tracer = setup_trace_fixture(_metadata, tracer_ptrace, NULL,
1612 true);
1613
1614 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1615 ASSERT_EQ(0, ret);
1616
1617 /* Install "errno on getppid" filter. */
1618 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
1619 ASSERT_EQ(0, ret);
1620
1621 /* Tracer will redirect getpid to getppid, and we should see EPERM. */
1622 EXPECT_EQ(-1, syscall(__NR_getpid));
1623 EXPECT_EQ(EPERM, errno);
1624}
1625
1626TEST_F_SIGNAL(TRACE_syscall, kill_after_ptrace, SIGSYS)
1627{
1628 struct sock_filter filter[] = {
1629 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
1630 offsetof(struct seccomp_data, nr)),
1631 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getppid, 0, 1),
1632 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
1633 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
1634 };
1635 struct sock_fprog prog = {
1636 .len = (unsigned short)ARRAY_SIZE(filter),
1637 .filter = filter,
1638 };
1639 long ret;
1640
1641 /* Swap SECCOMP_RET_TRACE tracer for PTRACE_SYSCALL tracer. */
1642 teardown_trace_fixture(_metadata, self->tracer);
1643 self->tracer = setup_trace_fixture(_metadata, tracer_ptrace, NULL,
1644 true);
1645
1646 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1647 ASSERT_EQ(0, ret);
1648
1649 /* Install "death on getppid" filter. */
1650 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
1651 ASSERT_EQ(0, ret);
1652
1653 /* Tracer will redirect getpid to getppid, and we should die. */
1654 EXPECT_NE(self->mypid, syscall(__NR_getpid));
1655}
1656
1503#ifndef __NR_seccomp 1657#ifndef __NR_seccomp
1504# if defined(__i386__) 1658# if defined(__i386__)
1505# define __NR_seccomp 354 1659# define __NR_seccomp 354
diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile
index 4a1be1b75a7f..1d5556869137 100644
--- a/tools/testing/selftests/timers/Makefile
+++ b/tools/testing/selftests/timers/Makefile
@@ -10,7 +10,7 @@ TEST_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \
10 10
11TEST_PROGS_EXTENDED = alarmtimer-suspend valid-adjtimex adjtick change_skew \ 11TEST_PROGS_EXTENDED = alarmtimer-suspend valid-adjtimex adjtick change_skew \
12 skew_consistency clocksource-switch leap-a-day \ 12 skew_consistency clocksource-switch leap-a-day \
13 leapcrash set-tai set-2038 13 leapcrash set-tai set-2038 set-tz
14 14
15bins = $(TEST_PROGS) $(TEST_PROGS_EXTENDED) 15bins = $(TEST_PROGS) $(TEST_PROGS_EXTENDED)
16 16
@@ -30,6 +30,7 @@ run_destructive_tests: run_tests
30 ./clocksource-switch 30 ./clocksource-switch
31 ./leap-a-day -s -i 10 31 ./leap-a-day -s -i 10
32 ./leapcrash 32 ./leapcrash
33 ./set-tz
33 ./set-tai 34 ./set-tai
34 ./set-2038 35 ./set-2038
35 36
diff --git a/tools/testing/selftests/timers/rtctest.c b/tools/testing/selftests/timers/rtctest.c
index 624bce51b27d..4230d3052e5d 100644
--- a/tools/testing/selftests/timers/rtctest.c
+++ b/tools/testing/selftests/timers/rtctest.c
@@ -144,11 +144,12 @@ test_READ:
144 144
145 retval = ioctl(fd, RTC_ALM_SET, &rtc_tm); 145 retval = ioctl(fd, RTC_ALM_SET, &rtc_tm);
146 if (retval == -1) { 146 if (retval == -1) {
147 if (errno == ENOTTY) { 147 if (errno == EINVAL) {
148 fprintf(stderr, 148 fprintf(stderr,
149 "\n...Alarm IRQs not supported.\n"); 149 "\n...Alarm IRQs not supported.\n");
150 goto test_PIE; 150 goto test_PIE;
151 } 151 }
152
152 perror("RTC_ALM_SET ioctl"); 153 perror("RTC_ALM_SET ioctl");
153 exit(errno); 154 exit(errno);
154 } 155 }
@@ -166,6 +167,12 @@ test_READ:
166 /* Enable alarm interrupts */ 167 /* Enable alarm interrupts */
167 retval = ioctl(fd, RTC_AIE_ON, 0); 168 retval = ioctl(fd, RTC_AIE_ON, 0);
168 if (retval == -1) { 169 if (retval == -1) {
170 if (errno == EINVAL) {
171 fprintf(stderr,
172 "\n...Alarm IRQs not supported.\n");
173 goto test_PIE;
174 }
175
169 perror("RTC_AIE_ON ioctl"); 176 perror("RTC_AIE_ON ioctl");
170 exit(errno); 177 exit(errno);
171 } 178 }
@@ -193,7 +200,7 @@ test_PIE:
193 retval = ioctl(fd, RTC_IRQP_READ, &tmp); 200 retval = ioctl(fd, RTC_IRQP_READ, &tmp);
194 if (retval == -1) { 201 if (retval == -1) {
195 /* not all RTCs support periodic IRQs */ 202 /* not all RTCs support periodic IRQs */
196 if (errno == ENOTTY) { 203 if (errno == EINVAL) {
197 fprintf(stderr, "\nNo periodic IRQ support\n"); 204 fprintf(stderr, "\nNo periodic IRQ support\n");
198 goto done; 205 goto done;
199 } 206 }
@@ -211,7 +218,7 @@ test_PIE:
211 retval = ioctl(fd, RTC_IRQP_SET, tmp); 218 retval = ioctl(fd, RTC_IRQP_SET, tmp);
212 if (retval == -1) { 219 if (retval == -1) {
213 /* not all RTCs can change their periodic IRQ rate */ 220 /* not all RTCs can change their periodic IRQ rate */
214 if (errno == ENOTTY) { 221 if (errno == EINVAL) {
215 fprintf(stderr, 222 fprintf(stderr,
216 "\n...Periodic IRQ rate is fixed\n"); 223 "\n...Periodic IRQ rate is fixed\n");
217 goto done; 224 goto done;
diff --git a/tools/testing/selftests/timers/set-tz.c b/tools/testing/selftests/timers/set-tz.c
new file mode 100644
index 000000000000..f4184928b16b
--- /dev/null
+++ b/tools/testing/selftests/timers/set-tz.c
@@ -0,0 +1,119 @@
1/* Set tz value
2 * by: John Stultz <john.stultz@linaro.org>
3 * (C) Copyright Linaro 2016
4 * Licensed under the GPLv2
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <time.h>
21#include <sys/time.h>
22#include <sys/timex.h>
23#include <string.h>
24#include <signal.h>
25#include <unistd.h>
26#ifdef KTEST
27#include "../kselftest.h"
28#else
29static inline int ksft_exit_pass(void)
30{
31 exit(0);
32}
33static inline int ksft_exit_fail(void)
34{
35 exit(1);
36}
37#endif
38
39int set_tz(int min, int dst)
40{
41 struct timezone tz;
42
43 tz.tz_minuteswest = min;
44 tz.tz_dsttime = dst;
45
46 return settimeofday(0, &tz);
47}
48
49int get_tz_min(void)
50{
51 struct timezone tz;
52 struct timeval tv;
53
54 memset(&tz, 0, sizeof(tz));
55 gettimeofday(&tv, &tz);
56 return tz.tz_minuteswest;
57}
58
59int get_tz_dst(void)
60{
61 struct timezone tz;
62 struct timeval tv;
63
64 memset(&tz, 0, sizeof(tz));
65 gettimeofday(&tv, &tz);
66 return tz.tz_dsttime;
67}
68
69int main(int argc, char **argv)
70{
71 int i, ret;
72 int min, dst;
73
74 min = get_tz_min();
75 dst = get_tz_dst();
76 printf("tz_minuteswest started at %i, dst at %i\n", min, dst);
77
78 printf("Checking tz_minuteswest can be properly set: ");
79 for (i = -15*60; i < 15*60; i += 30) {
80 ret = set_tz(i, dst);
81 ret = get_tz_min();
82 if (ret != i) {
83 printf("[FAILED] expected: %i got %i\n", i, ret);
84 goto err;
85 }
86 }
87 printf("[OK]\n");
88
89 printf("Checking invalid tz_minuteswest values are caught: ");
90
91 if (!set_tz(-15*60-1, dst)) {
92 printf("[FAILED] %i didn't return failure!\n", -15*60-1);
93 goto err;
94 }
95
96 if (!set_tz(15*60+1, dst)) {
97 printf("[FAILED] %i didn't return failure!\n", 15*60+1);
98 goto err;
99 }
100
101 if (!set_tz(-24*60, dst)) {
102 printf("[FAILED] %i didn't return failure!\n", -24*60);
103 goto err;
104 }
105
106 if (!set_tz(24*60, dst)) {
107 printf("[FAILED] %i didn't return failure!\n", 24*60);
108 goto err;
109 }
110
111 printf("[OK]\n");
112
113 set_tz(min, dst);
114 return ksft_exit_pass();
115
116err:
117 set_tz(min, dst);
118 return ksft_exit_fail();
119}
diff --git a/tools/testing/selftests/vm/compaction_test.c b/tools/testing/selftests/vm/compaction_test.c
index 00c4f65d12da..6d1437f895b8 100644
--- a/tools/testing/selftests/vm/compaction_test.c
+++ b/tools/testing/selftests/vm/compaction_test.c
@@ -101,7 +101,7 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size)
101 101
102 /* Start with the initial condition of 0 huge pages*/ 102 /* Start with the initial condition of 0 huge pages*/
103 if (write(fd, "0", sizeof(char)) != sizeof(char)) { 103 if (write(fd, "0", sizeof(char)) != sizeof(char)) {
104 perror("Failed to write to /proc/sys/vm/nr_hugepages\n"); 104 perror("Failed to write 0 to /proc/sys/vm/nr_hugepages\n");
105 goto close_fd; 105 goto close_fd;
106 } 106 }
107 107
@@ -110,14 +110,14 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size)
110 /* Request a large number of huge pages. The Kernel will allocate 110 /* Request a large number of huge pages. The Kernel will allocate
111 as much as it can */ 111 as much as it can */
112 if (write(fd, "100000", (6*sizeof(char))) != (6*sizeof(char))) { 112 if (write(fd, "100000", (6*sizeof(char))) != (6*sizeof(char))) {
113 perror("Failed to write to /proc/sys/vm/nr_hugepages\n"); 113 perror("Failed to write 100000 to /proc/sys/vm/nr_hugepages\n");
114 goto close_fd; 114 goto close_fd;
115 } 115 }
116 116
117 lseek(fd, 0, SEEK_SET); 117 lseek(fd, 0, SEEK_SET);
118 118
119 if (read(fd, nr_hugepages, sizeof(nr_hugepages)) <= 0) { 119 if (read(fd, nr_hugepages, sizeof(nr_hugepages)) <= 0) {
120 perror("Failed to read from /proc/sys/vm/nr_hugepages\n"); 120 perror("Failed to re-read from /proc/sys/vm/nr_hugepages\n");
121 goto close_fd; 121 goto close_fd;
122 } 122 }
123 123
@@ -138,7 +138,7 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size)
138 138
139 if (write(fd, initial_nr_hugepages, strlen(initial_nr_hugepages)) 139 if (write(fd, initial_nr_hugepages, strlen(initial_nr_hugepages))
140 != strlen(initial_nr_hugepages)) { 140 != strlen(initial_nr_hugepages)) {
141 perror("Failed to write to /proc/sys/vm/nr_hugepages\n"); 141 perror("Failed to write value to /proc/sys/vm/nr_hugepages\n");
142 goto close_fd; 142 goto close_fd;
143 } 143 }
144 144
diff --git a/tools/testing/selftests/vm/on-fault-limit.c b/tools/testing/selftests/vm/on-fault-limit.c
index 245acccce42d..0ae458f32fdb 100644
--- a/tools/testing/selftests/vm/on-fault-limit.c
+++ b/tools/testing/selftests/vm/on-fault-limit.c
@@ -20,7 +20,7 @@ static int test_limit(void)
20 return ret; 20 return ret;
21 } 21 }
22 22
23 if (mlockall(MCL_CURRENT | MCL_ONFAULT | MCL_FUTURE)) { 23 if (mlockall(MCL_ONFAULT | MCL_FUTURE)) {
24 perror("mlockall"); 24 perror("mlockall");
25 return ret; 25 return ret;
26 } 26 }
diff --git a/tools/virtio/ringtest/Makefile b/tools/virtio/ringtest/Makefile
index 6173adae9f08..877a8a4721b6 100644
--- a/tools/virtio/ringtest/Makefile
+++ b/tools/virtio/ringtest/Makefile
@@ -1,6 +1,6 @@
1all: 1all:
2 2
3all: ring virtio_ring_0_9 virtio_ring_poll virtio_ring_inorder noring 3all: ring virtio_ring_0_9 virtio_ring_poll virtio_ring_inorder ptr_ring noring
4 4
5CFLAGS += -Wall 5CFLAGS += -Wall
6CFLAGS += -pthread -O2 -ggdb 6CFLAGS += -pthread -O2 -ggdb
@@ -8,6 +8,7 @@ LDFLAGS += -pthread -O2 -ggdb
8 8
9main.o: main.c main.h 9main.o: main.c main.h
10ring.o: ring.c main.h 10ring.o: ring.c main.h
11ptr_ring.o: ptr_ring.c main.h ../../../include/linux/ptr_ring.h
11virtio_ring_0_9.o: virtio_ring_0_9.c main.h 12virtio_ring_0_9.o: virtio_ring_0_9.c main.h
12virtio_ring_poll.o: virtio_ring_poll.c virtio_ring_0_9.c main.h 13virtio_ring_poll.o: virtio_ring_poll.c virtio_ring_0_9.c main.h
13virtio_ring_inorder.o: virtio_ring_inorder.c virtio_ring_0_9.c main.h 14virtio_ring_inorder.o: virtio_ring_inorder.c virtio_ring_0_9.c main.h
@@ -15,6 +16,7 @@ ring: ring.o main.o
15virtio_ring_0_9: virtio_ring_0_9.o main.o 16virtio_ring_0_9: virtio_ring_0_9.o main.o
16virtio_ring_poll: virtio_ring_poll.o main.o 17virtio_ring_poll: virtio_ring_poll.o main.o
17virtio_ring_inorder: virtio_ring_inorder.o main.o 18virtio_ring_inorder: virtio_ring_inorder.o main.o
19ptr_ring: ptr_ring.o main.o
18noring: noring.o main.o 20noring: noring.o main.o
19clean: 21clean:
20 -rm main.o 22 -rm main.o
@@ -22,6 +24,7 @@ clean:
22 -rm virtio_ring_0_9.o virtio_ring_0_9 24 -rm virtio_ring_0_9.o virtio_ring_0_9
23 -rm virtio_ring_poll.o virtio_ring_poll 25 -rm virtio_ring_poll.o virtio_ring_poll
24 -rm virtio_ring_inorder.o virtio_ring_inorder 26 -rm virtio_ring_inorder.o virtio_ring_inorder
27 -rm ptr_ring.o ptr_ring
25 -rm noring.o noring 28 -rm noring.o noring
26 29
27.PHONY: all clean 30.PHONY: all clean
diff --git a/tools/virtio/ringtest/ptr_ring.c b/tools/virtio/ringtest/ptr_ring.c
new file mode 100644
index 000000000000..68e4f9f0da3a
--- /dev/null
+++ b/tools/virtio/ringtest/ptr_ring.c
@@ -0,0 +1,197 @@
1#define _GNU_SOURCE
2#include "main.h"
3#include <stdlib.h>
4#include <stdio.h>
5#include <string.h>
6#include <pthread.h>
7#include <malloc.h>
8#include <assert.h>
9#include <errno.h>
10#include <limits.h>
11
12#define SMP_CACHE_BYTES 64
13#define cache_line_size() SMP_CACHE_BYTES
14#define ____cacheline_aligned_in_smp __attribute__ ((aligned (SMP_CACHE_BYTES)))
15#define unlikely(x) (__builtin_expect(!!(x), 0))
16#define ALIGN(x, a) (((x) + (a) - 1) / (a) * (a))
17typedef pthread_spinlock_t spinlock_t;
18
19typedef int gfp_t;
20static void *kmalloc(unsigned size, gfp_t gfp)
21{
22 return memalign(64, size);
23}
24
25static void *kzalloc(unsigned size, gfp_t gfp)
26{
27 void *p = memalign(64, size);
28 if (!p)
29 return p;
30 memset(p, 0, size);
31
32 return p;
33}
34
35static void kfree(void *p)
36{
37 if (p)
38 free(p);
39}
40
41static void spin_lock_init(spinlock_t *lock)
42{
43 int r = pthread_spin_init(lock, 0);
44 assert(!r);
45}
46
47static void spin_lock(spinlock_t *lock)
48{
49 int ret = pthread_spin_lock(lock);
50 assert(!ret);
51}
52
53static void spin_unlock(spinlock_t *lock)
54{
55 int ret = pthread_spin_unlock(lock);
56 assert(!ret);
57}
58
59static void spin_lock_bh(spinlock_t *lock)
60{
61 spin_lock(lock);
62}
63
64static void spin_unlock_bh(spinlock_t *lock)
65{
66 spin_unlock(lock);
67}
68
69static void spin_lock_irq(spinlock_t *lock)
70{
71 spin_lock(lock);
72}
73
74static void spin_unlock_irq(spinlock_t *lock)
75{
76 spin_unlock(lock);
77}
78
79static void spin_lock_irqsave(spinlock_t *lock, unsigned long f)
80{
81 spin_lock(lock);
82}
83
84static void spin_unlock_irqrestore(spinlock_t *lock, unsigned long f)
85{
86 spin_unlock(lock);
87}
88
89#include "../../../include/linux/ptr_ring.h"
90
91static unsigned long long headcnt, tailcnt;
92static struct ptr_ring array ____cacheline_aligned_in_smp;
93
94/* implemented by ring */
95void alloc_ring(void)
96{
97 int ret = ptr_ring_init(&array, ring_size, 0);
98 assert(!ret);
99}
100
101/* guest side */
102int add_inbuf(unsigned len, void *buf, void *datap)
103{
104 int ret;
105
106 ret = __ptr_ring_produce(&array, buf);
107 if (ret >= 0) {
108 ret = 0;
109 headcnt++;
110 }
111
112 return ret;
113}
114
115/*
116 * ptr_ring API provides no way for producer to find out whether a given
117 * buffer was consumed. Our tests merely require that a successful get_buf
118 * implies that add_inbuf succeed in the past, and that add_inbuf will succeed,
119 * fake it accordingly.
120 */
121void *get_buf(unsigned *lenp, void **bufp)
122{
123 void *datap;
124
125 if (tailcnt == headcnt || __ptr_ring_full(&array))
126 datap = NULL;
127 else {
128 datap = "Buffer\n";
129 ++tailcnt;
130 }
131
132 return datap;
133}
134
135void poll_used(void)
136{
137 void *b;
138
139 do {
140 if (tailcnt == headcnt || __ptr_ring_full(&array)) {
141 b = NULL;
142 barrier();
143 } else {
144 b = "Buffer\n";
145 }
146 } while (!b);
147}
148
149void disable_call()
150{
151 assert(0);
152}
153
154bool enable_call()
155{
156 assert(0);
157}
158
159void kick_available(void)
160{
161 assert(0);
162}
163
164/* host side */
165void disable_kick()
166{
167 assert(0);
168}
169
170bool enable_kick()
171{
172 assert(0);
173}
174
175void poll_avail(void)
176{
177 void *b;
178
179 do {
180 barrier();
181 b = __ptr_ring_peek(&array);
182 } while (!b);
183}
184
185bool use_buf(unsigned *lenp, void **bufp)
186{
187 void *ptr;
188
189 ptr = __ptr_ring_consume(&array);
190
191 return ptr;
192}
193
194void call_used(void)
195{
196 assert(0);
197}
diff --git a/tools/vm/page_owner_sort.c b/tools/vm/page_owner_sort.c
index 77147b42d598..f1c055f3c243 100644
--- a/tools/vm/page_owner_sort.c
+++ b/tools/vm/page_owner_sort.c
@@ -79,12 +79,12 @@ static void add_list(char *buf, int len)
79 } 79 }
80} 80}
81 81
82#define BUF_SIZE 1024 82#define BUF_SIZE (128 * 1024)
83 83
84int main(int argc, char **argv) 84int main(int argc, char **argv)
85{ 85{
86 FILE *fin, *fout; 86 FILE *fin, *fout;
87 char buf[BUF_SIZE]; 87 char *buf;
88 int ret, i, count; 88 int ret, i, count;
89 struct block_list *list2; 89 struct block_list *list2;
90 struct stat st; 90 struct stat st;
@@ -107,6 +107,11 @@ int main(int argc, char **argv)
107 max_size = st.st_size / 100; /* hack ... */ 107 max_size = st.st_size / 100; /* hack ... */
108 108
109 list = malloc(max_size * sizeof(*list)); 109 list = malloc(max_size * sizeof(*list));
110 buf = malloc(BUF_SIZE);
111 if (!list || !buf) {
112 printf("Out of memory\n");
113 exit(1);
114 }
110 115
111 for ( ; ; ) { 116 for ( ; ; ) {
112 ret = read_block(buf, BUF_SIZE, fin); 117 ret = read_block(buf, BUF_SIZE, fin);