aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorJason Gunthorpe <jgg@mellanox.com>2018-08-16 16:13:03 -0400
committerJason Gunthorpe <jgg@mellanox.com>2018-08-16 16:21:29 -0400
commit0a3173a5f09bc58a3638ecfd0a80bdbae55e123c (patch)
treed6c0bc84863cca54dfbde3b7463e5d49c82af9f1 /tools
parent92f4e77c85918eab5e5803d7e28ab89a7e6bd3a2 (diff)
parent5c60a7389d795e001c8748b458eb76e3a5b6008c (diff)
Merge branch 'linus/master' into rdma.git for-next
rdma.git merge resolution for the 4.19 merge window Conflicts: drivers/infiniband/core/rdma_core.c - Use the rdma code and revise with the new spelling for atomic_fetch_add_unless drivers/nvme/host/rdma.c - Replace max_sge with max_send_sge in new blk code drivers/nvme/target/rdma.c - Use the blk code and revise to use NULL for ib_post_recv when appropriate - Replace max_sge with max_recv_sge in new blk code net/rds/ib_send.c - Use the net code and revise to use NULL for ib_post_recv when appropriate Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/arch/arm64/include/uapi/asm/unistd.h20
-rw-r--r--tools/arch/parisc/include/uapi/asm/errno.h1
-rw-r--r--tools/arch/x86/include/asm/cpufeatures.h3
-rw-r--r--tools/bpf/.gitignore5
-rw-r--r--tools/bpf/Makefile.helpers59
-rw-r--r--tools/bpf/bpftool/.gitignore2
-rw-r--r--tools/bpf/bpftool/Documentation/Makefile13
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool-cgroup.rst12
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool-prog.rst33
-rw-r--r--tools/bpf/bpftool/Makefile10
-rw-r--r--tools/bpf/bpftool/bash-completion/bpftool134
-rw-r--r--tools/bpf/bpftool/btf_dumper.c251
-rw-r--r--tools/bpf/bpftool/cgroup.c170
-rw-r--r--tools/bpf/bpftool/common.c2
-rw-r--r--tools/bpf/bpftool/main.c4
-rw-r--r--tools/bpf/bpftool/main.h36
-rw-r--r--tools/bpf/bpftool/map.c224
-rw-r--r--tools/bpf/bpftool/prog.c249
-rw-r--r--tools/bpf/bpftool/xlated_dumper.c6
-rw-r--r--tools/build/Build.include2
-rw-r--r--tools/build/Makefile2
-rw-r--r--tools/build/Makefile.feature1
-rw-r--r--tools/build/feature/Makefile4
-rw-r--r--tools/build/feature/test-reallocarray.c8
-rw-r--r--tools/include/linux/compiler-gcc.h4
-rw-r--r--tools/include/linux/overflow.h278
-rw-r--r--tools/include/tools/libc_compat.h20
-rw-r--r--tools/include/uapi/asm-generic/unistd.h783
-rw-r--r--tools/include/uapi/linux/bpf.h104
-rw-r--r--tools/include/uapi/linux/in.h301
-rw-r--r--tools/lib/bpf/Build2
-rw-r--r--tools/lib/bpf/Makefile6
-rw-r--r--tools/lib/bpf/bpf.c1
-rw-r--r--tools/lib/bpf/bpf.h1
-rw-r--r--tools/lib/bpf/btf.c43
-rw-r--r--tools/lib/bpf/btf.h2
-rw-r--r--tools/lib/bpf/libbpf.c295
-rw-r--r--tools/lib/bpf/libbpf.h16
-rw-r--r--tools/lib/bpf/libbpf_errno.c74
-rw-r--r--tools/memory-model/Documentation/explanation.txt2
-rw-r--r--tools/memory-model/Documentation/recipes.txt12
-rw-r--r--tools/memory-model/README20
-rw-r--r--tools/memory-model/linux-kernel.bell2
-rw-r--r--tools/memory-model/litmus-tests/IRIW+fencembonceonces+OnceOnce.litmus (renamed from tools/memory-model/litmus-tests/IRIW+mbonceonces+OnceOnce.litmus)2
-rw-r--r--tools/memory-model/litmus-tests/ISA2+pooncelock+pooncelock+pombonce.litmus2
-rw-r--r--tools/memory-model/litmus-tests/LB+fencembonceonce+ctrlonceonce.litmus (renamed from tools/memory-model/litmus-tests/LB+ctrlonceonce+mbonceonce.litmus)2
-rw-r--r--tools/memory-model/litmus-tests/MP+fencewmbonceonce+fencermbonceonce.litmus (renamed from tools/memory-model/litmus-tests/MP+wmbonceonce+rmbonceonce.litmus)2
-rw-r--r--tools/memory-model/litmus-tests/R+fencembonceonces.litmus (renamed from tools/memory-model/litmus-tests/R+mbonceonces.litmus)2
-rw-r--r--tools/memory-model/litmus-tests/README25
-rw-r--r--tools/memory-model/litmus-tests/S+fencewmbonceonce+poacquireonce.litmus (renamed from tools/memory-model/litmus-tests/S+wmbonceonce+poacquireonce.litmus)2
-rw-r--r--tools/memory-model/litmus-tests/SB+fencembonceonces.litmus (renamed from tools/memory-model/litmus-tests/SB+mbonceonces.litmus)2
-rw-r--r--tools/memory-model/litmus-tests/SB+rfionceonce-poonceonces.litmus32
-rw-r--r--tools/memory-model/litmus-tests/WRC+pooncerelease+fencermbonceonce+Once.litmus (renamed from tools/memory-model/litmus-tests/WRC+pooncerelease+rmbonceonce+Once.litmus)2
-rw-r--r--tools/memory-model/litmus-tests/Z6.0+pooncerelease+poacquirerelease+fencembonceonce.litmus (renamed from tools/memory-model/litmus-tests/Z6.0+pooncerelease+poacquirerelease+mbonceonce.litmus)2
-rwxr-xr-x[-rw-r--r--]tools/memory-model/scripts/checkalllitmus.sh2
-rwxr-xr-x[-rw-r--r--]tools/memory-model/scripts/checklitmus.sh2
-rw-r--r--tools/objtool/Makefile4
-rw-r--r--tools/objtool/arch/x86/include/asm/orc_types.h2
-rw-r--r--tools/objtool/check.c1
-rw-r--r--tools/objtool/check.h2
-rw-r--r--tools/objtool/orc_dump.c3
-rw-r--r--tools/objtool/orc_gen.c2
-rw-r--r--tools/pci/pcitest.c51
-rw-r--r--tools/pci/pcitest.sh15
-rw-r--r--tools/perf/Documentation/perf-list.txt10
-rw-r--r--tools/perf/Documentation/perf-record.txt4
-rw-r--r--tools/perf/Makefile.config6
-rw-r--r--tools/perf/Makefile.perf10
-rw-r--r--tools/perf/arch/arm64/Makefile21
-rwxr-xr-xtools/perf/arch/arm64/entry/syscalls/mksyscalltbl62
-rw-r--r--tools/perf/arch/powerpc/util/skip-callchain-idx.c10
-rw-r--r--tools/perf/arch/s390/util/kvm-stat.c2
-rw-r--r--tools/perf/builtin-c2c.c7
-rw-r--r--tools/perf/builtin-diff.c2
-rw-r--r--tools/perf/builtin-report.c4
-rw-r--r--tools/perf/builtin-stat.c60
-rw-r--r--tools/perf/builtin-top.c2
-rw-r--r--tools/perf/builtin-trace.c19
-rwxr-xr-xtools/perf/check-headers.sh3
-rw-r--r--tools/perf/include/bpf/bpf.h3
-rw-r--r--tools/perf/perf.h2
-rw-r--r--tools/perf/pmu-events/arch/arm64/cavium/thunderx2/core-imp-def.json87
-rw-r--r--tools/perf/pmu-events/arch/s390/cf_z10/basic.json12
-rw-r--r--tools/perf/pmu-events/arch/s390/cf_z10/crypto.json16
-rw-r--r--tools/perf/pmu-events/arch/s390/cf_z10/extended.json18
-rw-r--r--tools/perf/pmu-events/arch/s390/cf_z13/basic.json12
-rw-r--r--tools/perf/pmu-events/arch/s390/cf_z13/crypto.json16
-rw-r--r--tools/perf/pmu-events/arch/s390/cf_z13/extended.json56
-rw-r--r--tools/perf/pmu-events/arch/s390/cf_z13/transaction.json7
-rw-r--r--tools/perf/pmu-events/arch/s390/cf_z14/basic.json8
-rw-r--r--tools/perf/pmu-events/arch/s390/cf_z14/crypto.json16
-rw-r--r--tools/perf/pmu-events/arch/s390/cf_z14/extended.json53
-rw-r--r--tools/perf/pmu-events/arch/s390/cf_z14/transaction.json7
-rw-r--r--tools/perf/pmu-events/arch/s390/cf_z196/basic.json12
-rw-r--r--tools/perf/pmu-events/arch/s390/cf_z196/crypto.json16
-rw-r--r--tools/perf/pmu-events/arch/s390/cf_z196/extended.json24
-rw-r--r--tools/perf/pmu-events/arch/s390/cf_zec12/basic.json12
-rw-r--r--tools/perf/pmu-events/arch/s390/cf_zec12/crypto.json16
-rw-r--r--tools/perf/pmu-events/arch/s390/cf_zec12/extended.json35
-rw-r--r--tools/perf/pmu-events/arch/s390/cf_zec12/transaction.json7
-rw-r--r--tools/perf/pmu-events/jevents.c2
-rw-r--r--tools/perf/tests/builtin-test.c2
-rw-r--r--tools/perf/tests/parse-events.c18
-rwxr-xr-xtools/perf/tests/shell/record+probe_libc_inet_pton.sh36
-rw-r--r--tools/perf/trace/beauty/Build1
-rw-r--r--tools/perf/trace/beauty/beauty.h3
-rwxr-xr-xtools/perf/trace/beauty/drm_ioctl.sh9
-rwxr-xr-xtools/perf/trace/beauty/kcmp_type.sh2
-rwxr-xr-xtools/perf/trace/beauty/kvm_ioctl.sh4
-rwxr-xr-xtools/perf/trace/beauty/madvise_behavior.sh2
-rwxr-xr-xtools/perf/trace/beauty/perf_ioctl.sh2
-rwxr-xr-xtools/perf/trace/beauty/pkey_alloc_access_rights.sh2
-rwxr-xr-xtools/perf/trace/beauty/sndrv_ctl_ioctl.sh4
-rwxr-xr-xtools/perf/trace/beauty/sndrv_pcm_ioctl.sh4
-rw-r--r--tools/perf/trace/beauty/socket.c28
-rwxr-xr-xtools/perf/trace/beauty/socket_ipproto.sh11
-rwxr-xr-xtools/perf/trace/beauty/vhost_virtio_ioctl.sh6
-rw-r--r--tools/perf/ui/stdio/hist.c8
-rw-r--r--tools/perf/util/bpf-loader.c4
-rw-r--r--tools/perf/util/comm.c16
-rw-r--r--tools/perf/util/cs-etm-decoder/cs-etm-decoder.c10
-rw-r--r--tools/perf/util/cs-etm-decoder/cs-etm-decoder.h1
-rw-r--r--tools/perf/util/cs-etm.c71
-rw-r--r--tools/perf/util/evsel.c25
-rw-r--r--tools/perf/util/evsel.h9
-rw-r--r--tools/perf/util/header.c2
-rw-r--r--tools/perf/util/hist.h2
-rw-r--r--tools/perf/util/machine.c79
-rw-r--r--tools/perf/util/metricgroup.c26
-rw-r--r--tools/perf/util/metricgroup.h1
-rw-r--r--tools/perf/util/pmu.c6
-rw-r--r--tools/perf/util/stat-shadow.c5
-rw-r--r--tools/perf/util/syscalltbl.c4
-rw-r--r--tools/perf/util/unwind-libdw.c2
-rw-r--r--tools/perf/util/unwind-libunwind-local.c2
-rw-r--r--tools/testing/selftests/bpf/Makefile15
-rw-r--r--tools/testing/selftests/bpf/bpf_helpers.h12
-rw-r--r--tools/testing/selftests/bpf/bpf_util.h4
-rw-r--r--tools/testing/selftests/bpf/cgroup_helpers.c6
-rw-r--r--tools/testing/selftests/bpf/cgroup_helpers.h6
-rw-r--r--tools/testing/selftests/bpf/socket_cookie_prog.c60
-rwxr-xr-xtools/testing/selftests/bpf/tcp_client.py12
-rwxr-xr-xtools/testing/selftests/bpf/tcp_server.py16
-rw-r--r--tools/testing/selftests/bpf/test_align.c5
-rw-r--r--tools/testing/selftests/bpf/test_btf.c92
-rw-r--r--tools/testing/selftests/bpf/test_cgroup_storage.c130
-rw-r--r--tools/testing/selftests/bpf/test_maps.c262
-rwxr-xr-xtools/testing/selftests/bpf/test_offload.py232
-rw-r--r--tools/testing/selftests/bpf/test_select_reuseport.c688
-rw-r--r--tools/testing/selftests/bpf/test_select_reuseport_common.h36
-rw-r--r--tools/testing/selftests/bpf/test_select_reuseport_kern.c180
-rwxr-xr-xtools/testing/selftests/bpf/test_skb_cgroup_id.sh62
-rw-r--r--tools/testing/selftests/bpf/test_skb_cgroup_id_kern.c47
-rw-r--r--tools/testing/selftests/bpf/test_skb_cgroup_id_user.c187
-rw-r--r--tools/testing/selftests/bpf/test_sock.c5
-rw-r--r--tools/testing/selftests/bpf/test_sock_addr.c42
-rw-r--r--tools/testing/selftests/bpf/test_socket_cookie.c225
-rw-r--r--tools/testing/selftests/bpf/test_tcpbpf.h1
-rw-r--r--tools/testing/selftests/bpf/test_tcpbpf_kern.c17
-rw-r--r--tools/testing/selftests/bpf/test_tcpbpf_user.c119
-rw-r--r--tools/testing/selftests/bpf/test_verifier.c177
-rw-r--r--tools/testing/selftests/bpf/trace_helpers.c48
-rw-r--r--tools/testing/selftests/bpf/trace_helpers.h4
-rwxr-xr-xtools/testing/selftests/drivers/net/mlxsw/mirror_gre.sh217
-rw-r--r--tools/testing/selftests/drivers/net/mlxsw/mirror_gre_scale.sh197
-rwxr-xr-xtools/testing/selftests/drivers/net/mlxsw/qos_dscp_bridge.sh189
-rwxr-xr-xtools/testing/selftests/drivers/net/mlxsw/qos_dscp_router.sh233
-rw-r--r--tools/testing/selftests/drivers/net/mlxsw/router_scale.sh167
-rwxr-xr-xtools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh366
-rw-r--r--tools/testing/selftests/drivers/net/mlxsw/spectrum/devlink_lib_spectrum.sh119
-rwxr-xr-xtools/testing/selftests/drivers/net/mlxsw/spectrum/devlink_resources.sh117
-rw-r--r--tools/testing/selftests/drivers/net/mlxsw/spectrum/mirror_gre_scale.sh13
-rwxr-xr-xtools/testing/selftests/drivers/net/mlxsw/spectrum/resource_scale.sh55
-rw-r--r--tools/testing/selftests/drivers/net/mlxsw/spectrum/router_scale.sh18
-rw-r--r--tools/testing/selftests/drivers/net/mlxsw/spectrum/tc_flower_scale.sh19
-rw-r--r--tools/testing/selftests/drivers/net/mlxsw/tc_flower_scale.sh134
-rw-r--r--tools/testing/selftests/gpio/gpio-mockup-chardev.c6
-rw-r--r--tools/testing/selftests/net/.gitignore1
-rw-r--r--tools/testing/selftests/net/Makefile2
-rw-r--r--tools/testing/selftests/net/forwarding/README2
-rwxr-xr-xtools/testing/selftests/net/forwarding/bridge_port_isolation.sh151
-rw-r--r--tools/testing/selftests/net/forwarding/devlink_lib.sh108
-rwxr-xr-xtools/testing/selftests/net/forwarding/gre_multipath.sh253
-rw-r--r--tools/testing/selftests/net/forwarding/lib.sh291
-rwxr-xr-xtools/testing/selftests/net/forwarding/mirror_gre_bridge_1d.sh132
-rwxr-xr-xtools/testing/selftests/net/forwarding/mirror_gre_bridge_1d_vlan.sh6
-rwxr-xr-xtools/testing/selftests/net/forwarding/mirror_gre_bridge_1q.sh126
-rwxr-xr-xtools/testing/selftests/net/forwarding/mirror_gre_bridge_1q_lag.sh283
-rwxr-xr-xtools/testing/selftests/net/forwarding/mirror_gre_changes.sh11
-rwxr-xr-xtools/testing/selftests/net/forwarding/mirror_gre_lag_lacp.sh285
-rw-r--r--tools/testing/selftests/net/forwarding/mirror_gre_lib.sh4
-rwxr-xr-xtools/testing/selftests/net/forwarding/mirror_gre_nh.sh4
-rw-r--r--tools/testing/selftests/net/forwarding/mirror_gre_topo_lib.sh2
-rwxr-xr-xtools/testing/selftests/net/forwarding/mirror_gre_vlan_bridge_1q.sh21
-rw-r--r--tools/testing/selftests/net/forwarding/mirror_lib.sh2
-rwxr-xr-xtools/testing/selftests/net/forwarding/router_bridge.sh113
-rwxr-xr-xtools/testing/selftests/net/forwarding/router_bridge_vlan.sh132
-rwxr-xr-xtools/testing/selftests/net/forwarding/router_broadcast.sh233
-rwxr-xr-xtools/testing/selftests/net/forwarding/router_multipath.sh39
-rwxr-xr-xtools/testing/selftests/net/forwarding/tc_chains.sh86
-rwxr-xr-xtools/testing/selftests/net/forwarding/tc_shblocks.sh2
-rwxr-xr-xtools/testing/selftests/net/ip6_gre_headroom.sh65
-rwxr-xr-xtools/testing/selftests/net/rtnetlink.sh128
-rw-r--r--tools/testing/selftests/net/tls.c692
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/configinit.sh26
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/kvm-build.sh11
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh1
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/kvm-recheck.sh1
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh5
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/kvm.sh2
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/parse-console.sh7
-rw-r--r--tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot4
-rw-r--r--tools/testing/selftests/rcutorture/configs/rcu/TREE08-T.boot1
-rw-r--r--tools/testing/selftests/rcutorture/configs/rcu/ver_functions.sh2
-rw-r--r--tools/testing/selftests/rseq/param_test.c44
-rw-r--r--tools/testing/selftests/rseq/rseq-arm64.h594
-rw-r--r--tools/testing/selftests/rseq/rseq-s390.h513
-rw-r--r--tools/testing/selftests/rseq/rseq.h4
-rw-r--r--tools/testing/selftests/tc-testing/README16
-rw-r--r--tools/testing/selftests/tc-testing/config48
-rw-r--r--tools/testing/selftests/tc-testing/tc-tests/actions/connmark.json24
-rw-r--r--tools/testing/selftests/tc-testing/tc-tests/actions/csum.json24
-rw-r--r--tools/testing/selftests/tc-testing/tc-tests/actions/mirred.json3
-rw-r--r--tools/testing/selftests/tc-testing/tc-tests/actions/nat.json593
-rw-r--r--tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json26
-rw-r--r--tools/testing/selftests/tc-testing/tc-tests/actions/tunnel_key.json917
-rw-r--r--tools/testing/selftests/tc-testing/tc-tests/filters/fw.json1049
-rw-r--r--tools/testing/selftests/tc-testing/tc-tests/filters/tests.json4
-rw-r--r--tools/testing/selftests/timers/raw_skew.c5
229 files changed, 15362 insertions, 718 deletions
diff --git a/tools/arch/arm64/include/uapi/asm/unistd.h b/tools/arch/arm64/include/uapi/asm/unistd.h
new file mode 100644
index 000000000000..5072cbd15c82
--- /dev/null
+++ b/tools/arch/arm64/include/uapi/asm/unistd.h
@@ -0,0 +1,20 @@
1/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2/*
3 * Copyright (C) 2012 ARM Ltd.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#define __ARCH_WANT_RENAMEAT
19
20#include <asm-generic/unistd.h>
diff --git a/tools/arch/parisc/include/uapi/asm/errno.h b/tools/arch/parisc/include/uapi/asm/errno.h
index fc0df353ff0d..87245c584784 100644
--- a/tools/arch/parisc/include/uapi/asm/errno.h
+++ b/tools/arch/parisc/include/uapi/asm/errno.h
@@ -113,7 +113,6 @@
113#define ELOOP 249 /* Too many symbolic links encountered */ 113#define ELOOP 249 /* Too many symbolic links encountered */
114#define ENOSYS 251 /* Function not implemented */ 114#define ENOSYS 251 /* Function not implemented */
115 115
116#define ENOTSUP 252 /* Function not implemented (POSIX.4 / HPUX) */
117#define ECANCELLED 253 /* aio request was canceled before complete (POSIX.4 / HPUX) */ 116#define ECANCELLED 253 /* aio request was canceled before complete (POSIX.4 / HPUX) */
118#define ECANCELED ECANCELLED /* SuSv3 and Solaris wants one 'L' */ 117#define ECANCELED ECANCELLED /* SuSv3 and Solaris wants one 'L' */
119 118
diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h
index 5701f5cecd31..64aaa3f5f36c 100644
--- a/tools/arch/x86/include/asm/cpufeatures.h
+++ b/tools/arch/x86/include/asm/cpufeatures.h
@@ -219,6 +219,7 @@
219#define X86_FEATURE_IBPB ( 7*32+26) /* Indirect Branch Prediction Barrier */ 219#define X86_FEATURE_IBPB ( 7*32+26) /* Indirect Branch Prediction Barrier */
220#define X86_FEATURE_STIBP ( 7*32+27) /* Single Thread Indirect Branch Predictors */ 220#define X86_FEATURE_STIBP ( 7*32+27) /* Single Thread Indirect Branch Predictors */
221#define X86_FEATURE_ZEN ( 7*32+28) /* "" CPU is AMD family 0x17 (Zen) */ 221#define X86_FEATURE_ZEN ( 7*32+28) /* "" CPU is AMD family 0x17 (Zen) */
222#define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* "" L1TF workaround PTE inversion */
222 223
223/* Virtualization flags: Linux defined, word 8 */ 224/* Virtualization flags: Linux defined, word 8 */
224#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */ 225#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */
@@ -341,6 +342,7 @@
341#define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */ 342#define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */
342#define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */ 343#define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */
343#define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */ 344#define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */
345#define X86_FEATURE_FLUSH_L1D (18*32+28) /* Flush L1D cache */
344#define X86_FEATURE_ARCH_CAPABILITIES (18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */ 346#define X86_FEATURE_ARCH_CAPABILITIES (18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */
345#define X86_FEATURE_SPEC_CTRL_SSBD (18*32+31) /* "" Speculative Store Bypass Disable */ 347#define X86_FEATURE_SPEC_CTRL_SSBD (18*32+31) /* "" Speculative Store Bypass Disable */
346 348
@@ -373,5 +375,6 @@
373#define X86_BUG_SPECTRE_V1 X86_BUG(15) /* CPU is affected by Spectre variant 1 attack with conditional branches */ 375#define X86_BUG_SPECTRE_V1 X86_BUG(15) /* CPU is affected by Spectre variant 1 attack with conditional branches */
374#define X86_BUG_SPECTRE_V2 X86_BUG(16) /* CPU is affected by Spectre variant 2 attack with indirect branches */ 376#define X86_BUG_SPECTRE_V2 X86_BUG(16) /* CPU is affected by Spectre variant 2 attack with indirect branches */
375#define X86_BUG_SPEC_STORE_BYPASS X86_BUG(17) /* CPU is affected by speculative store bypass attack */ 377#define X86_BUG_SPEC_STORE_BYPASS X86_BUG(17) /* CPU is affected by speculative store bypass attack */
378#define X86_BUG_L1TF X86_BUG(18) /* CPU is affected by L1 Terminal Fault */
376 379
377#endif /* _ASM_X86_CPUFEATURES_H */ 380#endif /* _ASM_X86_CPUFEATURES_H */
diff --git a/tools/bpf/.gitignore b/tools/bpf/.gitignore
new file mode 100644
index 000000000000..dfe2bd5a4b95
--- /dev/null
+++ b/tools/bpf/.gitignore
@@ -0,0 +1,5 @@
1FEATURE-DUMP.bpf
2bpf_asm
3bpf_dbg
4bpf_exp.yacc.*
5bpf_jit_disasm
diff --git a/tools/bpf/Makefile.helpers b/tools/bpf/Makefile.helpers
new file mode 100644
index 000000000000..c34fea77f39f
--- /dev/null
+++ b/tools/bpf/Makefile.helpers
@@ -0,0 +1,59 @@
1ifndef allow-override
2 include ../scripts/Makefile.include
3 include ../scripts/utilities.mak
4else
5 # Assume Makefile.helpers is being run from bpftool/Documentation
6 # subdirectory. Go up two more directories to fetch bpf.h header and
7 # associated script.
8 UP2DIR := ../../
9endif
10
11INSTALL ?= install
12RM ?= rm -f
13RMDIR ?= rmdir --ignore-fail-on-non-empty
14
15ifeq ($(V),1)
16 Q =
17else
18 Q = @
19endif
20
21prefix ?= /usr/local
22mandir ?= $(prefix)/man
23man7dir = $(mandir)/man7
24
25HELPERS_RST = bpf-helpers.rst
26MAN7_RST = $(HELPERS_RST)
27
28_DOC_MAN7 = $(patsubst %.rst,%.7,$(MAN7_RST))
29DOC_MAN7 = $(addprefix $(OUTPUT),$(_DOC_MAN7))
30
31helpers: man7
32man7: $(DOC_MAN7)
33
34RST2MAN_DEP := $(shell command -v rst2man 2>/dev/null)
35
36$(OUTPUT)$(HELPERS_RST): $(UP2DIR)../../include/uapi/linux/bpf.h
37 $(QUIET_GEN)$(UP2DIR)../../scripts/bpf_helpers_doc.py --filename $< > $@
38
39$(OUTPUT)%.7: $(OUTPUT)%.rst
40ifndef RST2MAN_DEP
41 $(error "rst2man not found, but required to generate man pages")
42endif
43 $(QUIET_GEN)rst2man $< > $@
44
45helpers-clean:
46 $(call QUIET_CLEAN, eBPF_helpers-manpage)
47 $(Q)$(RM) $(DOC_MAN7) $(OUTPUT)$(HELPERS_RST)
48
49helpers-install: helpers
50 $(call QUIET_INSTALL, eBPF_helpers-manpage)
51 $(Q)$(INSTALL) -d -m 755 $(DESTDIR)$(man7dir)
52 $(Q)$(INSTALL) -m 644 $(DOC_MAN7) $(DESTDIR)$(man7dir)
53
54helpers-uninstall:
55 $(call QUIET_UNINST, eBPF_helpers-manpage)
56 $(Q)$(RM) $(addprefix $(DESTDIR)$(man7dir)/,$(_DOC_MAN7))
57 $(Q)$(RMDIR) $(DESTDIR)$(man7dir)
58
59.PHONY: helpers helpers-clean helpers-install helpers-uninstall
diff --git a/tools/bpf/bpftool/.gitignore b/tools/bpf/bpftool/.gitignore
index d7e678c2d396..67167e44b726 100644
--- a/tools/bpf/bpftool/.gitignore
+++ b/tools/bpf/bpftool/.gitignore
@@ -1,3 +1,5 @@
1*.d 1*.d
2bpftool 2bpftool
3bpftool*.8
4bpf-helpers.*
3FEATURE-DUMP.bpftool 5FEATURE-DUMP.bpftool
diff --git a/tools/bpf/bpftool/Documentation/Makefile b/tools/bpf/bpftool/Documentation/Makefile
index a9d47c1558bb..f7663a3e60c9 100644
--- a/tools/bpf/bpftool/Documentation/Makefile
+++ b/tools/bpf/bpftool/Documentation/Makefile
@@ -15,12 +15,15 @@ prefix ?= /usr/local
15mandir ?= $(prefix)/man 15mandir ?= $(prefix)/man
16man8dir = $(mandir)/man8 16man8dir = $(mandir)/man8
17 17
18MAN8_RST = $(wildcard *.rst) 18# Load targets for building eBPF helpers man page.
19include ../../Makefile.helpers
20
21MAN8_RST = $(filter-out $(HELPERS_RST),$(wildcard *.rst))
19 22
20_DOC_MAN8 = $(patsubst %.rst,%.8,$(MAN8_RST)) 23_DOC_MAN8 = $(patsubst %.rst,%.8,$(MAN8_RST))
21DOC_MAN8 = $(addprefix $(OUTPUT),$(_DOC_MAN8)) 24DOC_MAN8 = $(addprefix $(OUTPUT),$(_DOC_MAN8))
22 25
23man: man8 26man: man8 helpers
24man8: $(DOC_MAN8) 27man8: $(DOC_MAN8)
25 28
26RST2MAN_DEP := $(shell command -v rst2man 2>/dev/null) 29RST2MAN_DEP := $(shell command -v rst2man 2>/dev/null)
@@ -31,16 +34,16 @@ ifndef RST2MAN_DEP
31endif 34endif
32 $(QUIET_GEN)rst2man $< > $@ 35 $(QUIET_GEN)rst2man $< > $@
33 36
34clean: 37clean: helpers-clean
35 $(call QUIET_CLEAN, Documentation) 38 $(call QUIET_CLEAN, Documentation)
36 $(Q)$(RM) $(DOC_MAN8) 39 $(Q)$(RM) $(DOC_MAN8)
37 40
38install: man 41install: man helpers-install
39 $(call QUIET_INSTALL, Documentation-man) 42 $(call QUIET_INSTALL, Documentation-man)
40 $(Q)$(INSTALL) -d -m 755 $(DESTDIR)$(man8dir) 43 $(Q)$(INSTALL) -d -m 755 $(DESTDIR)$(man8dir)
41 $(Q)$(INSTALL) -m 644 $(DOC_MAN8) $(DESTDIR)$(man8dir) 44 $(Q)$(INSTALL) -m 644 $(DOC_MAN8) $(DESTDIR)$(man8dir)
42 45
43uninstall: 46uninstall: helpers-uninstall
44 $(call QUIET_UNINST, Documentation-man) 47 $(call QUIET_UNINST, Documentation-man)
45 $(Q)$(RM) $(addprefix $(DESTDIR)$(man8dir)/,$(_DOC_MAN8)) 48 $(Q)$(RM) $(addprefix $(DESTDIR)$(man8dir)/,$(_DOC_MAN8))
46 $(Q)$(RMDIR) $(DESTDIR)$(man8dir) 49 $(Q)$(RMDIR) $(DESTDIR)$(man8dir)
diff --git a/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst b/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst
index 7b0e6d453e92..edbe81534c6d 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst
@@ -15,12 +15,13 @@ SYNOPSIS
15 *OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } } 15 *OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } }
16 16
17 *COMMANDS* := 17 *COMMANDS* :=
18 { **show** | **list** | **attach** | **detach** | **help** } 18 { **show** | **list** | **tree** | **attach** | **detach** | **help** }
19 19
20MAP COMMANDS 20MAP COMMANDS
21============= 21=============
22 22
23| **bpftool** **cgroup { show | list }** *CGROUP* 23| **bpftool** **cgroup { show | list }** *CGROUP*
24| **bpftool** **cgroup tree** [*CGROUP_ROOT*]
24| **bpftool** **cgroup attach** *CGROUP* *ATTACH_TYPE* *PROG* [*ATTACH_FLAGS*] 25| **bpftool** **cgroup attach** *CGROUP* *ATTACH_TYPE* *PROG* [*ATTACH_FLAGS*]
25| **bpftool** **cgroup detach** *CGROUP* *ATTACH_TYPE* *PROG* 26| **bpftool** **cgroup detach** *CGROUP* *ATTACH_TYPE* *PROG*
26| **bpftool** **cgroup help** 27| **bpftool** **cgroup help**
@@ -39,6 +40,15 @@ DESCRIPTION
39 Output will start with program ID followed by attach type, 40 Output will start with program ID followed by attach type,
40 attach flags and program name. 41 attach flags and program name.
41 42
43 **bpftool cgroup tree** [*CGROUP_ROOT*]
44 Iterate over all cgroups in *CGROUP_ROOT* and list all
45 attached programs. If *CGROUP_ROOT* is not specified,
46 bpftool uses cgroup v2 mountpoint.
47
48 The output is similar to the output of cgroup show/list
49 commands: it starts with absolute cgroup path, followed by
50 program ID, attach type, attach flags and program name.
51
42 **bpftool cgroup attach** *CGROUP* *ATTACH_TYPE* *PROG* [*ATTACH_FLAGS*] 52 **bpftool cgroup attach** *CGROUP* *ATTACH_TYPE* *PROG* [*ATTACH_FLAGS*]
43 Attach program *PROG* to the cgroup *CGROUP* with attach type 53 Attach program *PROG* to the cgroup *CGROUP* with attach type
44 *ATTACH_TYPE* and optional *ATTACH_FLAGS*. 54 *ATTACH_TYPE* and optional *ATTACH_FLAGS*.
diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst
index 43d34a5c3ec5..64156a16d530 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-prog.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-prog.rst
@@ -24,10 +24,20 @@ MAP COMMANDS
24| **bpftool** **prog dump xlated** *PROG* [{**file** *FILE* | **opcodes** | **visual**}] 24| **bpftool** **prog dump xlated** *PROG* [{**file** *FILE* | **opcodes** | **visual**}]
25| **bpftool** **prog dump jited** *PROG* [{**file** *FILE* | **opcodes**}] 25| **bpftool** **prog dump jited** *PROG* [{**file** *FILE* | **opcodes**}]
26| **bpftool** **prog pin** *PROG* *FILE* 26| **bpftool** **prog pin** *PROG* *FILE*
27| **bpftool** **prog load** *OBJ* *FILE* 27| **bpftool** **prog load** *OBJ* *FILE* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*]
28| **bpftool** **prog help** 28| **bpftool** **prog help**
29| 29|
30| *MAP* := { **id** *MAP_ID* | **pinned** *FILE* }
30| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* } 31| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* }
32| *TYPE* := {
33| **socket** | **kprobe** | **kretprobe** | **classifier** | **action** |
34| **tracepoint** | **raw_tracepoint** | **xdp** | **perf_event** | **cgroup/skb** |
35| **cgroup/sock** | **cgroup/dev** | **lwt_in** | **lwt_out** | **lwt_xmit** |
36| **lwt_seg6local** | **sockops** | **sk_skb** | **sk_msg** | **lirc_mode2** |
37| **cgroup/bind4** | **cgroup/bind6** | **cgroup/post_bind4** | **cgroup/post_bind6** |
38| **cgroup/connect4** | **cgroup/connect6** | **cgroup/sendmsg4** | **cgroup/sendmsg6**
39| }
40
31 41
32DESCRIPTION 42DESCRIPTION
33=========== 43===========
@@ -64,8 +74,19 @@ DESCRIPTION
64 74
65 Note: *FILE* must be located in *bpffs* mount. 75 Note: *FILE* must be located in *bpffs* mount.
66 76
67 **bpftool prog load** *OBJ* *FILE* 77 **bpftool prog load** *OBJ* *FILE* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*]
68 Load bpf program from binary *OBJ* and pin as *FILE*. 78 Load bpf program from binary *OBJ* and pin as *FILE*.
79 **type** is optional, if not specified program type will be
80 inferred from section names.
81 By default bpftool will create new maps as declared in the ELF
82 object being loaded. **map** parameter allows for the reuse
83 of existing maps. It can be specified multiple times, each
84 time for a different map. *IDX* refers to index of the map
85 to be replaced in the ELF file counting from 0, while *NAME*
86 allows to replace a map by name. *MAP* specifies the map to
87 use, referring to it by **id** or through a **pinned** file.
88 If **dev** *NAME* is specified program will be loaded onto
89 given networking device (offload).
69 90
70 Note: *FILE* must be located in *bpffs* mount. 91 Note: *FILE* must be located in *bpffs* mount.
71 92
@@ -159,6 +180,14 @@ EXAMPLES
159 mov %rbx,0x0(%rbp) 180 mov %rbx,0x0(%rbp)
160 48 89 5d 00 181 48 89 5d 00
161 182
183|
184| **# bpftool prog load xdp1_kern.o /sys/fs/bpf/xdp1 type xdp map name rxcnt id 7**
185| **# bpftool prog show pinned /sys/fs/bpf/xdp1**
186| 9: xdp name xdp_prog1 tag 539ec6ce11b52f98 gpl
187| loaded_at 2018-06-25T16:17:31-0700 uid 0
188| xlated 488B jited 336B memlock 4096B map_ids 7
189| **# rm /sys/fs/bpf/xdp1**
190|
162 191
163SEE ALSO 192SEE ALSO
164======== 193========
diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile
index 892dbf095bff..74288a2197ab 100644
--- a/tools/bpf/bpftool/Makefile
+++ b/tools/bpf/bpftool/Makefile
@@ -23,10 +23,10 @@ endif
23 23
24LIBBPF = $(BPF_PATH)libbpf.a 24LIBBPF = $(BPF_PATH)libbpf.a
25 25
26BPFTOOL_VERSION=$(shell make --no-print-directory -sC ../../.. kernelversion) 26BPFTOOL_VERSION := $(shell make --no-print-directory -sC ../../.. kernelversion)
27 27
28$(LIBBPF): FORCE 28$(LIBBPF): FORCE
29 $(Q)$(MAKE) -C $(BPF_DIR) OUTPUT=$(OUTPUT) $(OUTPUT)libbpf.a FEATURES_DUMP=$(FEATURE_DUMP_EXPORT) 29 $(Q)$(MAKE) -C $(BPF_DIR) OUTPUT=$(OUTPUT) $(OUTPUT)libbpf.a
30 30
31$(LIBBPF)-clean: 31$(LIBBPF)-clean:
32 $(call QUIET_CLEAN, libbpf) 32 $(call QUIET_CLEAN, libbpf)
@@ -52,7 +52,7 @@ INSTALL ?= install
52RM ?= rm -f 52RM ?= rm -f
53 53
54FEATURE_USER = .bpftool 54FEATURE_USER = .bpftool
55FEATURE_TESTS = libbfd disassembler-four-args 55FEATURE_TESTS = libbfd disassembler-four-args reallocarray
56FEATURE_DISPLAY = libbfd disassembler-four-args 56FEATURE_DISPLAY = libbfd disassembler-four-args
57 57
58check_feat := 1 58check_feat := 1
@@ -75,6 +75,10 @@ ifeq ($(feature-disassembler-four-args), 1)
75CFLAGS += -DDISASM_FOUR_ARGS_SIGNATURE 75CFLAGS += -DDISASM_FOUR_ARGS_SIGNATURE
76endif 76endif
77 77
78ifeq ($(feature-reallocarray), 0)
79CFLAGS += -DCOMPAT_NEED_REALLOCARRAY
80endif
81
78include $(wildcard $(OUTPUT)*.d) 82include $(wildcard $(OUTPUT)*.d)
79 83
80all: $(OUTPUT)bpftool 84all: $(OUTPUT)bpftool
diff --git a/tools/bpf/bpftool/bash-completion/bpftool b/tools/bpf/bpftool/bash-completion/bpftool
index 1e1083321643..598066c40191 100644
--- a/tools/bpf/bpftool/bash-completion/bpftool
+++ b/tools/bpf/bpftool/bash-completion/bpftool
@@ -99,6 +99,35 @@ _bpftool_get_prog_tags()
99 command sed -n 's/.*"tag": "\(.*\)",$/\1/p' )" -- "$cur" ) ) 99 command sed -n 's/.*"tag": "\(.*\)",$/\1/p' )" -- "$cur" ) )
100} 100}
101 101
102_bpftool_get_obj_map_names()
103{
104 local obj
105
106 obj=$1
107
108 maps=$(objdump -j maps -t $obj 2>/dev/null | \
109 command awk '/g . maps/ {print $NF}')
110
111 COMPREPLY+=( $( compgen -W "$maps" -- "$cur" ) )
112}
113
114_bpftool_get_obj_map_idxs()
115{
116 local obj
117
118 obj=$1
119
120 nmaps=$(objdump -j maps -t $obj 2>/dev/null | grep -c 'g . maps')
121
122 COMPREPLY+=( $( compgen -W "$(seq 0 $((nmaps - 1)))" -- "$cur" ) )
123}
124
125_sysfs_get_netdevs()
126{
127 COMPREPLY+=( $( compgen -W "$( ls /sys/class/net 2>/dev/null )" -- \
128 "$cur" ) )
129}
130
102# For bpftool map update: retrieve type of the map to update. 131# For bpftool map update: retrieve type of the map to update.
103_bpftool_map_update_map_type() 132_bpftool_map_update_map_type()
104{ 133{
@@ -153,6 +182,13 @@ _bpftool()
153 local cur prev words objword 182 local cur prev words objword
154 _init_completion || return 183 _init_completion || return
155 184
185 # Deal with options
186 if [[ ${words[cword]} == -* ]]; then
187 local c='--version --json --pretty --bpffs'
188 COMPREPLY=( $( compgen -W "$c" -- "$cur" ) )
189 return 0
190 fi
191
156 # Deal with simplest keywords 192 # Deal with simplest keywords
157 case $prev in 193 case $prev in
158 help|hex|opcodes|visual) 194 help|hex|opcodes|visual)
@@ -172,20 +208,23 @@ _bpftool()
172 ;; 208 ;;
173 esac 209 esac
174 210
175 # Search for object and command 211 # Remove all options so completions don't have to deal with them.
176 local object command cmdword 212 local i
177 for (( cmdword=1; cmdword < ${#words[@]}-1; cmdword++ )); do 213 for (( i=1; i < ${#words[@]}; )); do
178 [[ -n $object ]] && command=${words[cmdword]} && break 214 if [[ ${words[i]::1} == - ]]; then
179 [[ ${words[cmdword]} != -* ]] && object=${words[cmdword]} 215 words=( "${words[@]:0:i}" "${words[@]:i+1}" )
216 [[ $i -le $cword ]] && cword=$(( cword - 1 ))
217 else
218 i=$(( ++i ))
219 fi
180 done 220 done
221 cur=${words[cword]}
222 prev=${words[cword - 1]}
223
224 local object=${words[1]} command=${words[2]}
181 225
182 if [[ -z $object ]]; then 226 if [[ -z $object || $cword -eq 1 ]]; then
183 case $cur in 227 case $cur in
184 -*)
185 local c='--version --json --pretty'
186 COMPREPLY=( $( compgen -W "$c" -- "$cur" ) )
187 return 0
188 ;;
189 *) 228 *)
190 COMPREPLY=( $( compgen -W "$( bpftool help 2>&1 | \ 229 COMPREPLY=( $( compgen -W "$( bpftool help 2>&1 | \
191 command sed \ 230 command sed \
@@ -204,12 +243,14 @@ _bpftool()
204 # Completion depends on object and command in use 243 # Completion depends on object and command in use
205 case $object in 244 case $object in
206 prog) 245 prog)
207 case $prev in 246 if [[ $command != "load" ]]; then
208 id) 247 case $prev in
209 _bpftool_get_prog_ids 248 id)
210 return 0 249 _bpftool_get_prog_ids
211 ;; 250 return 0
212 esac 251 ;;
252 esac
253 fi
213 254
214 local PROG_TYPE='id pinned tag' 255 local PROG_TYPE='id pinned tag'
215 case $command in 256 case $command in
@@ -252,8 +293,57 @@ _bpftool()
252 return 0 293 return 0
253 ;; 294 ;;
254 load) 295 load)
255 _filedir 296 local obj
256 return 0 297
298 if [[ ${#words[@]} -lt 6 ]]; then
299 _filedir
300 return 0
301 fi
302
303 obj=${words[3]}
304
305 if [[ ${words[-4]} == "map" ]]; then
306 COMPREPLY=( $( compgen -W "id pinned" -- "$cur" ) )
307 return 0
308 fi
309 if [[ ${words[-3]} == "map" ]]; then
310 if [[ ${words[-2]} == "idx" ]]; then
311 _bpftool_get_obj_map_idxs $obj
312 elif [[ ${words[-2]} == "name" ]]; then
313 _bpftool_get_obj_map_names $obj
314 fi
315 return 0
316 fi
317 if [[ ${words[-2]} == "map" ]]; then
318 COMPREPLY=( $( compgen -W "idx name" -- "$cur" ) )
319 return 0
320 fi
321
322 case $prev in
323 type)
324 COMPREPLY=( $( compgen -W "socket kprobe kretprobe classifier action tracepoint raw_tracepoint xdp perf_event cgroup/skb cgroup/sock cgroup/dev lwt_in lwt_out lwt_xmit lwt_seg6local sockops sk_skb sk_msg lirc_mode2 cgroup/bind4 cgroup/bind6 cgroup/connect4 cgroup/connect6 cgroup/sendmsg4 cgroup/sendmsg6 cgroup/post_bind4 cgroup/post_bind6" -- \
325 "$cur" ) )
326 return 0
327 ;;
328 id)
329 _bpftool_get_map_ids
330 return 0
331 ;;
332 pinned)
333 _filedir
334 return 0
335 ;;
336 dev)
337 _sysfs_get_netdevs
338 return 0
339 ;;
340 *)
341 COMPREPLY=( $( compgen -W "map" -- "$cur" ) )
342 _bpftool_once_attr 'type'
343 _bpftool_once_attr 'dev'
344 return 0
345 ;;
346 esac
257 ;; 347 ;;
258 *) 348 *)
259 [[ $prev == $object ]] && \ 349 [[ $prev == $object ]] && \
@@ -404,6 +494,10 @@ _bpftool()
404 _filedir 494 _filedir
405 return 0 495 return 0
406 ;; 496 ;;
497 tree)
498 _filedir
499 return 0
500 ;;
407 attach|detach) 501 attach|detach)
408 local ATTACH_TYPES='ingress egress sock_create sock_ops \ 502 local ATTACH_TYPES='ingress egress sock_create sock_ops \
409 device bind4 bind6 post_bind4 post_bind6 connect4 \ 503 device bind4 bind6 post_bind4 post_bind6 connect4 \
@@ -445,7 +539,7 @@ _bpftool()
445 *) 539 *)
446 [[ $prev == $object ]] && \ 540 [[ $prev == $object ]] && \
447 COMPREPLY=( $( compgen -W 'help attach detach \ 541 COMPREPLY=( $( compgen -W 'help attach detach \
448 show list' -- "$cur" ) ) 542 show list tree' -- "$cur" ) )
449 ;; 543 ;;
450 esac 544 esac
451 ;; 545 ;;
diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c
new file mode 100644
index 000000000000..55bc512a1831
--- /dev/null
+++ b/tools/bpf/bpftool/btf_dumper.c
@@ -0,0 +1,251 @@
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2018 Facebook */
3
4#include <ctype.h>
5#include <stdio.h> /* for (FILE *) used by json_writer */
6#include <string.h>
7#include <asm/byteorder.h>
8#include <linux/bitops.h>
9#include <linux/btf.h>
10#include <linux/err.h>
11
12#include "btf.h"
13#include "json_writer.h"
14#include "main.h"
15
16#define BITS_PER_BYTE_MASK (BITS_PER_BYTE - 1)
17#define BITS_PER_BYTE_MASKED(bits) ((bits) & BITS_PER_BYTE_MASK)
18#define BITS_ROUNDDOWN_BYTES(bits) ((bits) >> 3)
19#define BITS_ROUNDUP_BYTES(bits) \
20 (BITS_ROUNDDOWN_BYTES(bits) + !!BITS_PER_BYTE_MASKED(bits))
21
22static int btf_dumper_do_type(const struct btf_dumper *d, __u32 type_id,
23 __u8 bit_offset, const void *data);
24
25static void btf_dumper_ptr(const void *data, json_writer_t *jw,
26 bool is_plain_text)
27{
28 if (is_plain_text)
29 jsonw_printf(jw, "%p", *(unsigned long *)data);
30 else
31 jsonw_printf(jw, "%u", *(unsigned long *)data);
32}
33
34static int btf_dumper_modifier(const struct btf_dumper *d, __u32 type_id,
35 const void *data)
36{
37 int actual_type_id;
38
39 actual_type_id = btf__resolve_type(d->btf, type_id);
40 if (actual_type_id < 0)
41 return actual_type_id;
42
43 return btf_dumper_do_type(d, actual_type_id, 0, data);
44}
45
46static void btf_dumper_enum(const void *data, json_writer_t *jw)
47{
48 jsonw_printf(jw, "%d", *(int *)data);
49}
50
51static int btf_dumper_array(const struct btf_dumper *d, __u32 type_id,
52 const void *data)
53{
54 const struct btf_type *t = btf__type_by_id(d->btf, type_id);
55 struct btf_array *arr = (struct btf_array *)(t + 1);
56 long long elem_size;
57 int ret = 0;
58 __u32 i;
59
60 elem_size = btf__resolve_size(d->btf, arr->type);
61 if (elem_size < 0)
62 return elem_size;
63
64 jsonw_start_array(d->jw);
65 for (i = 0; i < arr->nelems; i++) {
66 ret = btf_dumper_do_type(d, arr->type, 0,
67 data + i * elem_size);
68 if (ret)
69 break;
70 }
71
72 jsonw_end_array(d->jw);
73 return ret;
74}
75
76static void btf_dumper_int_bits(__u32 int_type, __u8 bit_offset,
77 const void *data, json_writer_t *jw,
78 bool is_plain_text)
79{
80 int left_shift_bits, right_shift_bits;
81 int nr_bits = BTF_INT_BITS(int_type);
82 int total_bits_offset;
83 int bytes_to_copy;
84 int bits_to_copy;
85 __u64 print_num;
86
87 total_bits_offset = bit_offset + BTF_INT_OFFSET(int_type);
88 data += BITS_ROUNDDOWN_BYTES(total_bits_offset);
89 bit_offset = BITS_PER_BYTE_MASKED(total_bits_offset);
90 bits_to_copy = bit_offset + nr_bits;
91 bytes_to_copy = BITS_ROUNDUP_BYTES(bits_to_copy);
92
93 print_num = 0;
94 memcpy(&print_num, data, bytes_to_copy);
95#if defined(__BIG_ENDIAN_BITFIELD)
96 left_shift_bits = bit_offset;
97#elif defined(__LITTLE_ENDIAN_BITFIELD)
98 left_shift_bits = 64 - bits_to_copy;
99#else
100#error neither big nor little endian
101#endif
102 right_shift_bits = 64 - nr_bits;
103
104 print_num <<= left_shift_bits;
105 print_num >>= right_shift_bits;
106 if (is_plain_text)
107 jsonw_printf(jw, "0x%llx", print_num);
108 else
109 jsonw_printf(jw, "%llu", print_num);
110}
111
112static int btf_dumper_int(const struct btf_type *t, __u8 bit_offset,
113 const void *data, json_writer_t *jw,
114 bool is_plain_text)
115{
116 __u32 *int_type;
117 __u32 nr_bits;
118
119 int_type = (__u32 *)(t + 1);
120 nr_bits = BTF_INT_BITS(*int_type);
121 /* if this is bit field */
122 if (bit_offset || BTF_INT_OFFSET(*int_type) ||
123 BITS_PER_BYTE_MASKED(nr_bits)) {
124 btf_dumper_int_bits(*int_type, bit_offset, data, jw,
125 is_plain_text);
126 return 0;
127 }
128
129 switch (BTF_INT_ENCODING(*int_type)) {
130 case 0:
131 if (BTF_INT_BITS(*int_type) == 64)
132 jsonw_printf(jw, "%lu", *(__u64 *)data);
133 else if (BTF_INT_BITS(*int_type) == 32)
134 jsonw_printf(jw, "%u", *(__u32 *)data);
135 else if (BTF_INT_BITS(*int_type) == 16)
136 jsonw_printf(jw, "%hu", *(__u16 *)data);
137 else if (BTF_INT_BITS(*int_type) == 8)
138 jsonw_printf(jw, "%hhu", *(__u8 *)data);
139 else
140 btf_dumper_int_bits(*int_type, bit_offset, data, jw,
141 is_plain_text);
142 break;
143 case BTF_INT_SIGNED:
144 if (BTF_INT_BITS(*int_type) == 64)
145 jsonw_printf(jw, "%ld", *(long long *)data);
146 else if (BTF_INT_BITS(*int_type) == 32)
147 jsonw_printf(jw, "%d", *(int *)data);
148 else if (BTF_INT_BITS(*int_type) == 16)
149 jsonw_printf(jw, "%hd", *(short *)data);
150 else if (BTF_INT_BITS(*int_type) == 8)
151 jsonw_printf(jw, "%hhd", *(char *)data);
152 else
153 btf_dumper_int_bits(*int_type, bit_offset, data, jw,
154 is_plain_text);
155 break;
156 case BTF_INT_CHAR:
157 if (isprint(*(char *)data))
158 jsonw_printf(jw, "\"%c\"", *(char *)data);
159 else
160 if (is_plain_text)
161 jsonw_printf(jw, "0x%hhx", *(char *)data);
162 else
163 jsonw_printf(jw, "\"\\u00%02hhx\"",
164 *(char *)data);
165 break;
166 case BTF_INT_BOOL:
167 jsonw_bool(jw, *(int *)data);
168 break;
169 default:
170 /* shouldn't happen */
171 return -EINVAL;
172 }
173
174 return 0;
175}
176
177static int btf_dumper_struct(const struct btf_dumper *d, __u32 type_id,
178 const void *data)
179{
180 const struct btf_type *t;
181 struct btf_member *m;
182 const void *data_off;
183 int ret = 0;
184 int i, vlen;
185
186 t = btf__type_by_id(d->btf, type_id);
187 if (!t)
188 return -EINVAL;
189
190 vlen = BTF_INFO_VLEN(t->info);
191 jsonw_start_object(d->jw);
192 m = (struct btf_member *)(t + 1);
193
194 for (i = 0; i < vlen; i++) {
195 data_off = data + BITS_ROUNDDOWN_BYTES(m[i].offset);
196 jsonw_name(d->jw, btf__name_by_offset(d->btf, m[i].name_off));
197 ret = btf_dumper_do_type(d, m[i].type,
198 BITS_PER_BYTE_MASKED(m[i].offset),
199 data_off);
200 if (ret)
201 break;
202 }
203
204 jsonw_end_object(d->jw);
205
206 return ret;
207}
208
209static int btf_dumper_do_type(const struct btf_dumper *d, __u32 type_id,
210 __u8 bit_offset, const void *data)
211{
212 const struct btf_type *t = btf__type_by_id(d->btf, type_id);
213
214 switch (BTF_INFO_KIND(t->info)) {
215 case BTF_KIND_INT:
216 return btf_dumper_int(t, bit_offset, data, d->jw,
217 d->is_plain_text);
218 case BTF_KIND_STRUCT:
219 case BTF_KIND_UNION:
220 return btf_dumper_struct(d, type_id, data);
221 case BTF_KIND_ARRAY:
222 return btf_dumper_array(d, type_id, data);
223 case BTF_KIND_ENUM:
224 btf_dumper_enum(data, d->jw);
225 return 0;
226 case BTF_KIND_PTR:
227 btf_dumper_ptr(data, d->jw, d->is_plain_text);
228 return 0;
229 case BTF_KIND_UNKN:
230 jsonw_printf(d->jw, "(unknown)");
231 return 0;
232 case BTF_KIND_FWD:
233 /* map key or value can't be forward */
234 jsonw_printf(d->jw, "(fwd-kind-invalid)");
235 return -EINVAL;
236 case BTF_KIND_TYPEDEF:
237 case BTF_KIND_VOLATILE:
238 case BTF_KIND_CONST:
239 case BTF_KIND_RESTRICT:
240 return btf_dumper_modifier(d, type_id, data);
241 default:
242 jsonw_printf(d->jw, "(unsupported-kind");
243 return -EINVAL;
244 }
245}
246
247int btf_dumper_type(const struct btf_dumper *d, __u32 type_id,
248 const void *data)
249{
250 return btf_dumper_do_type(d, type_id, 0, data);
251}
diff --git a/tools/bpf/bpftool/cgroup.c b/tools/bpf/bpftool/cgroup.c
index 16bee011e16c..ee7a9765c6b3 100644
--- a/tools/bpf/bpftool/cgroup.c
+++ b/tools/bpf/bpftool/cgroup.c
@@ -2,7 +2,12 @@
2// Copyright (C) 2017 Facebook 2// Copyright (C) 2017 Facebook
3// Author: Roman Gushchin <guro@fb.com> 3// Author: Roman Gushchin <guro@fb.com>
4 4
5#define _XOPEN_SOURCE 500
6#include <errno.h>
5#include <fcntl.h> 7#include <fcntl.h>
8#include <ftw.h>
9#include <mntent.h>
10#include <stdio.h>
6#include <stdlib.h> 11#include <stdlib.h>
7#include <string.h> 12#include <string.h>
8#include <sys/stat.h> 13#include <sys/stat.h>
@@ -53,7 +58,8 @@ static enum bpf_attach_type parse_attach_type(const char *str)
53} 58}
54 59
55static int show_bpf_prog(int id, const char *attach_type_str, 60static int show_bpf_prog(int id, const char *attach_type_str,
56 const char *attach_flags_str) 61 const char *attach_flags_str,
62 int level)
57{ 63{
58 struct bpf_prog_info info = {}; 64 struct bpf_prog_info info = {};
59 __u32 info_len = sizeof(info); 65 __u32 info_len = sizeof(info);
@@ -78,7 +84,8 @@ static int show_bpf_prog(int id, const char *attach_type_str,
78 jsonw_string_field(json_wtr, "name", info.name); 84 jsonw_string_field(json_wtr, "name", info.name);
79 jsonw_end_object(json_wtr); 85 jsonw_end_object(json_wtr);
80 } else { 86 } else {
81 printf("%-8u %-15s %-15s %-15s\n", info.id, 87 printf("%s%-8u %-15s %-15s %-15s\n", level ? " " : "",
88 info.id,
82 attach_type_str, 89 attach_type_str,
83 attach_flags_str, 90 attach_flags_str,
84 info.name); 91 info.name);
@@ -88,7 +95,20 @@ static int show_bpf_prog(int id, const char *attach_type_str,
88 return 0; 95 return 0;
89} 96}
90 97
91static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type) 98static int count_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type)
99{
100 __u32 prog_cnt = 0;
101 int ret;
102
103 ret = bpf_prog_query(cgroup_fd, type, 0, NULL, NULL, &prog_cnt);
104 if (ret)
105 return -1;
106
107 return prog_cnt;
108}
109
110static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type,
111 int level)
92{ 112{
93 __u32 prog_ids[1024] = {0}; 113 __u32 prog_ids[1024] = {0};
94 char *attach_flags_str; 114 char *attach_flags_str;
@@ -123,7 +143,7 @@ static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type)
123 143
124 for (iter = 0; iter < prog_cnt; iter++) 144 for (iter = 0; iter < prog_cnt; iter++)
125 show_bpf_prog(prog_ids[iter], attach_type_strings[type], 145 show_bpf_prog(prog_ids[iter], attach_type_strings[type],
126 attach_flags_str); 146 attach_flags_str, level);
127 147
128 return 0; 148 return 0;
129} 149}
@@ -161,7 +181,7 @@ static int do_show(int argc, char **argv)
161 * If we were able to get the show for at least one 181 * If we were able to get the show for at least one
162 * attach type, let's return 0. 182 * attach type, let's return 0.
163 */ 183 */
164 if (show_attached_bpf_progs(cgroup_fd, type) == 0) 184 if (show_attached_bpf_progs(cgroup_fd, type, 0) == 0)
165 ret = 0; 185 ret = 0;
166 } 186 }
167 187
@@ -173,6 +193,143 @@ exit:
173 return ret; 193 return ret;
174} 194}
175 195
196/*
197 * To distinguish nftw() errors and do_show_tree_fn() errors
198 * and avoid duplicating error messages, let's return -2
199 * from do_show_tree_fn() in case of error.
200 */
201#define NFTW_ERR -1
202#define SHOW_TREE_FN_ERR -2
203static int do_show_tree_fn(const char *fpath, const struct stat *sb,
204 int typeflag, struct FTW *ftw)
205{
206 enum bpf_attach_type type;
207 bool skip = true;
208 int cgroup_fd;
209
210 if (typeflag != FTW_D)
211 return 0;
212
213 cgroup_fd = open(fpath, O_RDONLY);
214 if (cgroup_fd < 0) {
215 p_err("can't open cgroup %s: %s", fpath, strerror(errno));
216 return SHOW_TREE_FN_ERR;
217 }
218
219 for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++) {
220 int count = count_attached_bpf_progs(cgroup_fd, type);
221
222 if (count < 0 && errno != EINVAL) {
223 p_err("can't query bpf programs attached to %s: %s",
224 fpath, strerror(errno));
225 close(cgroup_fd);
226 return SHOW_TREE_FN_ERR;
227 }
228 if (count > 0) {
229 skip = false;
230 break;
231 }
232 }
233
234 if (skip) {
235 close(cgroup_fd);
236 return 0;
237 }
238
239 if (json_output) {
240 jsonw_start_object(json_wtr);
241 jsonw_string_field(json_wtr, "cgroup", fpath);
242 jsonw_name(json_wtr, "programs");
243 jsonw_start_array(json_wtr);
244 } else {
245 printf("%s\n", fpath);
246 }
247
248 for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++)
249 show_attached_bpf_progs(cgroup_fd, type, ftw->level);
250
251 if (json_output) {
252 jsonw_end_array(json_wtr);
253 jsonw_end_object(json_wtr);
254 }
255
256 close(cgroup_fd);
257
258 return 0;
259}
260
261static char *find_cgroup_root(void)
262{
263 struct mntent *mnt;
264 FILE *f;
265
266 f = fopen("/proc/mounts", "r");
267 if (f == NULL)
268 return NULL;
269
270 while ((mnt = getmntent(f))) {
271 if (strcmp(mnt->mnt_type, "cgroup2") == 0) {
272 fclose(f);
273 return strdup(mnt->mnt_dir);
274 }
275 }
276
277 fclose(f);
278 return NULL;
279}
280
281static int do_show_tree(int argc, char **argv)
282{
283 char *cgroup_root;
284 int ret;
285
286 switch (argc) {
287 case 0:
288 cgroup_root = find_cgroup_root();
289 if (!cgroup_root) {
290 p_err("cgroup v2 isn't mounted");
291 return -1;
292 }
293 break;
294 case 1:
295 cgroup_root = argv[0];
296 break;
297 default:
298 p_err("too many parameters for cgroup tree");
299 return -1;
300 }
301
302
303 if (json_output)
304 jsonw_start_array(json_wtr);
305 else
306 printf("%s\n"
307 "%-8s %-15s %-15s %-15s\n",
308 "CgroupPath",
309 "ID", "AttachType", "AttachFlags", "Name");
310
311 switch (nftw(cgroup_root, do_show_tree_fn, 1024, FTW_MOUNT)) {
312 case NFTW_ERR:
313 p_err("can't iterate over %s: %s", cgroup_root,
314 strerror(errno));
315 ret = -1;
316 break;
317 case SHOW_TREE_FN_ERR:
318 ret = -1;
319 break;
320 default:
321 ret = 0;
322 }
323
324 if (json_output)
325 jsonw_end_array(json_wtr);
326
327 if (argc == 0)
328 free(cgroup_root);
329
330 return ret;
331}
332
176static int do_attach(int argc, char **argv) 333static int do_attach(int argc, char **argv)
177{ 334{
178 enum bpf_attach_type attach_type; 335 enum bpf_attach_type attach_type;
@@ -289,6 +446,7 @@ static int do_help(int argc, char **argv)
289 446
290 fprintf(stderr, 447 fprintf(stderr,
291 "Usage: %s %s { show | list } CGROUP\n" 448 "Usage: %s %s { show | list } CGROUP\n"
449 " %s %s tree [CGROUP_ROOT]\n"
292 " %s %s attach CGROUP ATTACH_TYPE PROG [ATTACH_FLAGS]\n" 450 " %s %s attach CGROUP ATTACH_TYPE PROG [ATTACH_FLAGS]\n"
293 " %s %s detach CGROUP ATTACH_TYPE PROG\n" 451 " %s %s detach CGROUP ATTACH_TYPE PROG\n"
294 " %s %s help\n" 452 " %s %s help\n"
@@ -298,6 +456,7 @@ static int do_help(int argc, char **argv)
298 " " HELP_SPEC_PROGRAM "\n" 456 " " HELP_SPEC_PROGRAM "\n"
299 " " HELP_SPEC_OPTIONS "\n" 457 " " HELP_SPEC_OPTIONS "\n"
300 "", 458 "",
459 bin_name, argv[-2],
301 bin_name, argv[-2], bin_name, argv[-2], 460 bin_name, argv[-2], bin_name, argv[-2],
302 bin_name, argv[-2], bin_name, argv[-2]); 461 bin_name, argv[-2], bin_name, argv[-2]);
303 462
@@ -307,6 +466,7 @@ static int do_help(int argc, char **argv)
307static const struct cmd cmds[] = { 466static const struct cmd cmds[] = {
308 { "show", do_show }, 467 { "show", do_show },
309 { "list", do_show }, 468 { "list", do_show },
469 { "tree", do_show_tree },
310 { "attach", do_attach }, 470 { "attach", do_attach },
311 { "detach", do_detach }, 471 { "detach", do_detach },
312 { "help", do_help }, 472 { "help", do_help },
diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c
index 3f140eff039f..b3a0709ea7ed 100644
--- a/tools/bpf/bpftool/common.c
+++ b/tools/bpf/bpftool/common.c
@@ -31,8 +31,6 @@
31 * SOFTWARE. 31 * SOFTWARE.
32 */ 32 */
33 33
34/* Author: Jakub Kicinski <kubakici@wp.pl> */
35
36#include <ctype.h> 34#include <ctype.h>
37#include <errno.h> 35#include <errno.h>
38#include <fcntl.h> 36#include <fcntl.h>
diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c
index eea7f14355f3..d15a62be6cf0 100644
--- a/tools/bpf/bpftool/main.c
+++ b/tools/bpf/bpftool/main.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2017 Netronome Systems, Inc. 2 * Copyright (C) 2017-2018 Netronome Systems, Inc.
3 * 3 *
4 * This software is dual licensed under the GNU General License Version 2, 4 * This software is dual licensed under the GNU General License Version 2,
5 * June 1991 as shown in the file COPYING in the top-level directory of this 5 * June 1991 as shown in the file COPYING in the top-level directory of this
@@ -31,8 +31,6 @@
31 * SOFTWARE. 31 * SOFTWARE.
32 */ 32 */
33 33
34/* Author: Jakub Kicinski <kubakici@wp.pl> */
35
36#include <bfd.h> 34#include <bfd.h>
37#include <ctype.h> 35#include <ctype.h>
38#include <errno.h> 36#include <errno.h>
diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h
index 63fdb310b9a4..238e734d75b3 100644
--- a/tools/bpf/bpftool/main.h
+++ b/tools/bpf/bpftool/main.h
@@ -31,8 +31,6 @@
31 * SOFTWARE. 31 * SOFTWARE.
32 */ 32 */
33 33
34/* Author: Jakub Kicinski <kubakici@wp.pl> */
35
36#ifndef __BPF_TOOL_H 34#ifndef __BPF_TOOL_H
37#define __BPF_TOOL_H 35#define __BPF_TOOL_H
38 36
@@ -44,6 +42,7 @@
44#include <linux/compiler.h> 42#include <linux/compiler.h>
45#include <linux/kernel.h> 43#include <linux/kernel.h>
46#include <linux/hashtable.h> 44#include <linux/hashtable.h>
45#include <tools/libc_compat.h>
47 46
48#include "json_writer.h" 47#include "json_writer.h"
49 48
@@ -52,6 +51,21 @@
52#define NEXT_ARG() ({ argc--; argv++; if (argc < 0) usage(); }) 51#define NEXT_ARG() ({ argc--; argv++; if (argc < 0) usage(); })
53#define NEXT_ARGP() ({ (*argc)--; (*argv)++; if (*argc < 0) usage(); }) 52#define NEXT_ARGP() ({ (*argc)--; (*argv)++; if (*argc < 0) usage(); })
54#define BAD_ARG() ({ p_err("what is '%s'?", *argv); -1; }) 53#define BAD_ARG() ({ p_err("what is '%s'?", *argv); -1; })
54#define GET_ARG() ({ argc--; *argv++; })
55#define REQ_ARGS(cnt) \
56 ({ \
57 int _cnt = (cnt); \
58 bool _res; \
59 \
60 if (argc < _cnt) { \
61 p_err("'%s' needs at least %d arguments, %d found", \
62 argv[-1], _cnt, argc); \
63 _res = false; \
64 } else { \
65 _res = true; \
66 } \
67 _res; \
68 })
55 69
56#define ERR_MAX_LEN 1024 70#define ERR_MAX_LEN 1024
57 71
@@ -61,6 +75,8 @@
61 "PROG := { id PROG_ID | pinned FILE | tag PROG_TAG }" 75 "PROG := { id PROG_ID | pinned FILE | tag PROG_TAG }"
62#define HELP_SPEC_OPTIONS \ 76#define HELP_SPEC_OPTIONS \
63 "OPTIONS := { {-j|--json} [{-p|--pretty}] | {-f|--bpffs} }" 77 "OPTIONS := { {-j|--json} [{-p|--pretty}] | {-f|--bpffs} }"
78#define HELP_SPEC_MAP \
79 "MAP := { id MAP_ID | pinned FILE }"
64 80
65enum bpf_obj_type { 81enum bpf_obj_type {
66 BPF_OBJ_UNKNOWN, 82 BPF_OBJ_UNKNOWN,
@@ -122,6 +138,7 @@ int do_cgroup(int argc, char **arg);
122int do_perf(int argc, char **arg); 138int do_perf(int argc, char **arg);
123 139
124int prog_parse_fd(int *argc, char ***argv); 140int prog_parse_fd(int *argc, char ***argv);
141int map_parse_fd(int *argc, char ***argv);
125int map_parse_fd_and_info(int *argc, char ***argv, void *info, __u32 *info_len); 142int map_parse_fd_and_info(int *argc, char ***argv, void *info, __u32 *info_len);
126 143
127void disasm_print_insn(unsigned char *image, ssize_t len, int opcodes, 144void disasm_print_insn(unsigned char *image, ssize_t len, int opcodes,
@@ -133,4 +150,19 @@ unsigned int get_page_size(void);
133unsigned int get_possible_cpus(void); 150unsigned int get_possible_cpus(void);
134const char *ifindex_to_bfd_name_ns(__u32 ifindex, __u64 ns_dev, __u64 ns_ino); 151const char *ifindex_to_bfd_name_ns(__u32 ifindex, __u64 ns_dev, __u64 ns_ino);
135 152
153struct btf_dumper {
154 const struct btf *btf;
155 json_writer_t *jw;
156 bool is_plain_text;
157};
158
159/* btf_dumper_type - print data along with type information
160 * @d: an instance containing context for dumping types
161 * @type_id: index in btf->types array. this points to the type to be dumped
162 * @data: pointer the actual data, i.e. the values to be printed
163 *
164 * Returns zero on success and negative error code otherwise
165 */
166int btf_dumper_type(const struct btf_dumper *d, __u32 type_id,
167 const void *data);
136#endif 168#endif
diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c
index f74a8bcbda87..b2ec20e562bd 100644
--- a/tools/bpf/bpftool/map.c
+++ b/tools/bpf/bpftool/map.c
@@ -31,11 +31,10 @@
31 * SOFTWARE. 31 * SOFTWARE.
32 */ 32 */
33 33
34/* Author: Jakub Kicinski <kubakici@wp.pl> */
35
36#include <assert.h> 34#include <assert.h>
37#include <errno.h> 35#include <errno.h>
38#include <fcntl.h> 36#include <fcntl.h>
37#include <linux/err.h>
39#include <linux/kernel.h> 38#include <linux/kernel.h>
40#include <stdbool.h> 39#include <stdbool.h>
41#include <stdio.h> 40#include <stdio.h>
@@ -47,6 +46,8 @@
47 46
48#include <bpf.h> 47#include <bpf.h>
49 48
49#include "btf.h"
50#include "json_writer.h"
50#include "main.h" 51#include "main.h"
51 52
52static const char * const map_type_name[] = { 53static const char * const map_type_name[] = {
@@ -68,6 +69,7 @@ static const char * const map_type_name[] = {
68 [BPF_MAP_TYPE_SOCKMAP] = "sockmap", 69 [BPF_MAP_TYPE_SOCKMAP] = "sockmap",
69 [BPF_MAP_TYPE_CPUMAP] = "cpumap", 70 [BPF_MAP_TYPE_CPUMAP] = "cpumap",
70 [BPF_MAP_TYPE_SOCKHASH] = "sockhash", 71 [BPF_MAP_TYPE_SOCKHASH] = "sockhash",
72 [BPF_MAP_TYPE_CGROUP_STORAGE] = "cgroup_storage",
71}; 73};
72 74
73static bool map_is_per_cpu(__u32 type) 75static bool map_is_per_cpu(__u32 type)
@@ -97,7 +99,7 @@ static void *alloc_value(struct bpf_map_info *info)
97 return malloc(info->value_size); 99 return malloc(info->value_size);
98} 100}
99 101
100static int map_parse_fd(int *argc, char ***argv) 102int map_parse_fd(int *argc, char ***argv)
101{ 103{
102 int fd; 104 int fd;
103 105
@@ -152,8 +154,109 @@ int map_parse_fd_and_info(int *argc, char ***argv, void *info, __u32 *info_len)
152 return fd; 154 return fd;
153} 155}
154 156
157static int do_dump_btf(const struct btf_dumper *d,
158 struct bpf_map_info *map_info, void *key,
159 void *value)
160{
161 int ret;
162
163 /* start of key-value pair */
164 jsonw_start_object(d->jw);
165
166 jsonw_name(d->jw, "key");
167
168 ret = btf_dumper_type(d, map_info->btf_key_type_id, key);
169 if (ret)
170 goto err_end_obj;
171
172 jsonw_name(d->jw, "value");
173
174 ret = btf_dumper_type(d, map_info->btf_value_type_id, value);
175
176err_end_obj:
177 /* end of key-value pair */
178 jsonw_end_object(d->jw);
179
180 return ret;
181}
182
183static int get_btf(struct bpf_map_info *map_info, struct btf **btf)
184{
185 struct bpf_btf_info btf_info = { 0 };
186 __u32 len = sizeof(btf_info);
187 __u32 last_size;
188 int btf_fd;
189 void *ptr;
190 int err;
191
192 err = 0;
193 *btf = NULL;
194 btf_fd = bpf_btf_get_fd_by_id(map_info->btf_id);
195 if (btf_fd < 0)
196 return 0;
197
198 /* we won't know btf_size until we call bpf_obj_get_info_by_fd(). so
199 * let's start with a sane default - 4KiB here - and resize it only if
200 * bpf_obj_get_info_by_fd() needs a bigger buffer.
201 */
202 btf_info.btf_size = 4096;
203 last_size = btf_info.btf_size;
204 ptr = malloc(last_size);
205 if (!ptr) {
206 err = -ENOMEM;
207 goto exit_free;
208 }
209
210 bzero(ptr, last_size);
211 btf_info.btf = ptr_to_u64(ptr);
212 err = bpf_obj_get_info_by_fd(btf_fd, &btf_info, &len);
213
214 if (!err && btf_info.btf_size > last_size) {
215 void *temp_ptr;
216
217 last_size = btf_info.btf_size;
218 temp_ptr = realloc(ptr, last_size);
219 if (!temp_ptr) {
220 err = -ENOMEM;
221 goto exit_free;
222 }
223 ptr = temp_ptr;
224 bzero(ptr, last_size);
225 btf_info.btf = ptr_to_u64(ptr);
226 err = bpf_obj_get_info_by_fd(btf_fd, &btf_info, &len);
227 }
228
229 if (err || btf_info.btf_size > last_size) {
230 err = errno;
231 goto exit_free;
232 }
233
234 *btf = btf__new((__u8 *)btf_info.btf, btf_info.btf_size, NULL);
235 if (IS_ERR(*btf)) {
236 err = PTR_ERR(*btf);
237 *btf = NULL;
238 }
239
240exit_free:
241 close(btf_fd);
242 free(ptr);
243
244 return err;
245}
246
247static json_writer_t *get_btf_writer(void)
248{
249 json_writer_t *jw = jsonw_new(stdout);
250
251 if (!jw)
252 return NULL;
253 jsonw_pretty(jw, true);
254
255 return jw;
256}
257
155static void print_entry_json(struct bpf_map_info *info, unsigned char *key, 258static void print_entry_json(struct bpf_map_info *info, unsigned char *key,
156 unsigned char *value) 259 unsigned char *value, struct btf *btf)
157{ 260{
158 jsonw_start_object(json_wtr); 261 jsonw_start_object(json_wtr);
159 262
@@ -162,6 +265,16 @@ static void print_entry_json(struct bpf_map_info *info, unsigned char *key,
162 print_hex_data_json(key, info->key_size); 265 print_hex_data_json(key, info->key_size);
163 jsonw_name(json_wtr, "value"); 266 jsonw_name(json_wtr, "value");
164 print_hex_data_json(value, info->value_size); 267 print_hex_data_json(value, info->value_size);
268 if (btf) {
269 struct btf_dumper d = {
270 .btf = btf,
271 .jw = json_wtr,
272 .is_plain_text = false,
273 };
274
275 jsonw_name(json_wtr, "formatted");
276 do_dump_btf(&d, info, key, value);
277 }
165 } else { 278 } else {
166 unsigned int i, n, step; 279 unsigned int i, n, step;
167 280
@@ -514,10 +627,12 @@ static int do_show(int argc, char **argv)
514 627
515static int do_dump(int argc, char **argv) 628static int do_dump(int argc, char **argv)
516{ 629{
630 struct bpf_map_info info = {};
517 void *key, *value, *prev_key; 631 void *key, *value, *prev_key;
518 unsigned int num_elems = 0; 632 unsigned int num_elems = 0;
519 struct bpf_map_info info = {};
520 __u32 len = sizeof(info); 633 __u32 len = sizeof(info);
634 json_writer_t *btf_wtr;
635 struct btf *btf = NULL;
521 int err; 636 int err;
522 int fd; 637 int fd;
523 638
@@ -543,8 +658,27 @@ static int do_dump(int argc, char **argv)
543 } 658 }
544 659
545 prev_key = NULL; 660 prev_key = NULL;
661
662 err = get_btf(&info, &btf);
663 if (err) {
664 p_err("failed to get btf");
665 goto exit_free;
666 }
667
546 if (json_output) 668 if (json_output)
547 jsonw_start_array(json_wtr); 669 jsonw_start_array(json_wtr);
670 else
671 if (btf) {
672 btf_wtr = get_btf_writer();
673 if (!btf_wtr) {
674 p_info("failed to create json writer for btf. falling back to plain output");
675 btf__free(btf);
676 btf = NULL;
677 } else {
678 jsonw_start_array(btf_wtr);
679 }
680 }
681
548 while (true) { 682 while (true) {
549 err = bpf_map_get_next_key(fd, prev_key, key); 683 err = bpf_map_get_next_key(fd, prev_key, key);
550 if (err) { 684 if (err) {
@@ -555,9 +689,19 @@ static int do_dump(int argc, char **argv)
555 689
556 if (!bpf_map_lookup_elem(fd, key, value)) { 690 if (!bpf_map_lookup_elem(fd, key, value)) {
557 if (json_output) 691 if (json_output)
558 print_entry_json(&info, key, value); 692 print_entry_json(&info, key, value, btf);
559 else 693 else
560 print_entry_plain(&info, key, value); 694 if (btf) {
695 struct btf_dumper d = {
696 .btf = btf,
697 .jw = btf_wtr,
698 .is_plain_text = true,
699 };
700
701 do_dump_btf(&d, &info, key, value);
702 } else {
703 print_entry_plain(&info, key, value);
704 }
561 } else { 705 } else {
562 if (json_output) { 706 if (json_output) {
563 jsonw_name(json_wtr, "key"); 707 jsonw_name(json_wtr, "key");
@@ -580,14 +724,19 @@ static int do_dump(int argc, char **argv)
580 724
581 if (json_output) 725 if (json_output)
582 jsonw_end_array(json_wtr); 726 jsonw_end_array(json_wtr);
583 else 727 else if (btf) {
728 jsonw_end_array(btf_wtr);
729 jsonw_destroy(&btf_wtr);
730 } else {
584 printf("Found %u element%s\n", num_elems, 731 printf("Found %u element%s\n", num_elems,
585 num_elems != 1 ? "s" : ""); 732 num_elems != 1 ? "s" : "");
733 }
586 734
587exit_free: 735exit_free:
588 free(key); 736 free(key);
589 free(value); 737 free(value);
590 close(fd); 738 close(fd);
739 btf__free(btf);
591 740
592 return err; 741 return err;
593} 742}
@@ -643,6 +792,8 @@ static int do_lookup(int argc, char **argv)
643{ 792{
644 struct bpf_map_info info = {}; 793 struct bpf_map_info info = {};
645 __u32 len = sizeof(info); 794 __u32 len = sizeof(info);
795 json_writer_t *btf_wtr;
796 struct btf *btf = NULL;
646 void *key, *value; 797 void *key, *value;
647 int err; 798 int err;
648 int fd; 799 int fd;
@@ -667,27 +818,60 @@ static int do_lookup(int argc, char **argv)
667 goto exit_free; 818 goto exit_free;
668 819
669 err = bpf_map_lookup_elem(fd, key, value); 820 err = bpf_map_lookup_elem(fd, key, value);
670 if (!err) { 821 if (err) {
671 if (json_output) 822 if (errno == ENOENT) {
672 print_entry_json(&info, key, value); 823 if (json_output) {
673 else 824 jsonw_null(json_wtr);
825 } else {
826 printf("key:\n");
827 fprint_hex(stdout, key, info.key_size, " ");
828 printf("\n\nNot found\n");
829 }
830 } else {
831 p_err("lookup failed: %s", strerror(errno));
832 }
833
834 goto exit_free;
835 }
836
837 /* here means bpf_map_lookup_elem() succeeded */
838 err = get_btf(&info, &btf);
839 if (err) {
840 p_err("failed to get btf");
841 goto exit_free;
842 }
843
844 if (json_output) {
845 print_entry_json(&info, key, value, btf);
846 } else if (btf) {
847 /* if here json_wtr wouldn't have been initialised,
848 * so let's create separate writer for btf
849 */
850 btf_wtr = get_btf_writer();
851 if (!btf_wtr) {
852 p_info("failed to create json writer for btf. falling back to plain output");
853 btf__free(btf);
854 btf = NULL;
674 print_entry_plain(&info, key, value); 855 print_entry_plain(&info, key, value);
675 } else if (errno == ENOENT) {
676 if (json_output) {
677 jsonw_null(json_wtr);
678 } else { 856 } else {
679 printf("key:\n"); 857 struct btf_dumper d = {
680 fprint_hex(stdout, key, info.key_size, " "); 858 .btf = btf,
681 printf("\n\nNot found\n"); 859 .jw = btf_wtr,
860 .is_plain_text = true,
861 };
862
863 do_dump_btf(&d, &info, key, value);
864 jsonw_destroy(&btf_wtr);
682 } 865 }
683 } else { 866 } else {
684 p_err("lookup failed: %s", strerror(errno)); 867 print_entry_plain(&info, key, value);
685 } 868 }
686 869
687exit_free: 870exit_free:
688 free(key); 871 free(key);
689 free(value); 872 free(value);
690 close(fd); 873 close(fd);
874 btf__free(btf);
691 875
692 return err; 876 return err;
693} 877}
@@ -830,7 +1014,7 @@ static int do_help(int argc, char **argv)
830 " %s %s event_pipe MAP [cpu N index M]\n" 1014 " %s %s event_pipe MAP [cpu N index M]\n"
831 " %s %s help\n" 1015 " %s %s help\n"
832 "\n" 1016 "\n"
833 " MAP := { id MAP_ID | pinned FILE }\n" 1017 " " HELP_SPEC_MAP "\n"
834 " DATA := { [hex] BYTES }\n" 1018 " DATA := { [hex] BYTES }\n"
835 " " HELP_SPEC_PROGRAM "\n" 1019 " " HELP_SPEC_PROGRAM "\n"
836 " VALUE := { DATA | MAP | PROG }\n" 1020 " VALUE := { DATA | MAP | PROG }\n"
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index 959aa53ab678..dce960d22106 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2017 Netronome Systems, Inc. 2 * Copyright (C) 2017-2018 Netronome Systems, Inc.
3 * 3 *
4 * This software is dual licensed under the GNU General License Version 2, 4 * This software is dual licensed under the GNU General License Version 2,
5 * June 1991 as shown in the file COPYING in the top-level directory of this 5 * June 1991 as shown in the file COPYING in the top-level directory of this
@@ -31,8 +31,7 @@
31 * SOFTWARE. 31 * SOFTWARE.
32 */ 32 */
33 33
34/* Author: Jakub Kicinski <kubakici@wp.pl> */ 34#define _GNU_SOURCE
35
36#include <errno.h> 35#include <errno.h>
37#include <fcntl.h> 36#include <fcntl.h>
38#include <stdarg.h> 37#include <stdarg.h>
@@ -41,9 +40,12 @@
41#include <string.h> 40#include <string.h>
42#include <time.h> 41#include <time.h>
43#include <unistd.h> 42#include <unistd.h>
43#include <net/if.h>
44#include <sys/types.h> 44#include <sys/types.h>
45#include <sys/stat.h> 45#include <sys/stat.h>
46 46
47#include <linux/err.h>
48
47#include <bpf.h> 49#include <bpf.h>
48#include <libbpf.h> 50#include <libbpf.h>
49 51
@@ -681,31 +683,247 @@ static int do_pin(int argc, char **argv)
681 return err; 683 return err;
682} 684}
683 685
686struct map_replace {
687 int idx;
688 int fd;
689 char *name;
690};
691
692int map_replace_compar(const void *p1, const void *p2)
693{
694 const struct map_replace *a = p1, *b = p2;
695
696 return a->idx - b->idx;
697}
698
684static int do_load(int argc, char **argv) 699static int do_load(int argc, char **argv)
685{ 700{
701 enum bpf_attach_type expected_attach_type;
702 struct bpf_object_open_attr attr = {
703 .prog_type = BPF_PROG_TYPE_UNSPEC,
704 };
705 struct map_replace *map_replace = NULL;
706 unsigned int old_map_fds = 0;
707 struct bpf_program *prog;
686 struct bpf_object *obj; 708 struct bpf_object *obj;
687 int prog_fd; 709 struct bpf_map *map;
688 710 const char *pinfile;
689 if (argc != 2) 711 unsigned int i, j;
690 usage(); 712 __u32 ifindex = 0;
713 int idx, err;
691 714
692 if (bpf_prog_load(argv[0], BPF_PROG_TYPE_UNSPEC, &obj, &prog_fd)) { 715 if (!REQ_ARGS(2))
693 p_err("failed to load program");
694 return -1; 716 return -1;
717 attr.file = GET_ARG();
718 pinfile = GET_ARG();
719
720 while (argc) {
721 if (is_prefix(*argv, "type")) {
722 char *type;
723
724 NEXT_ARG();
725
726 if (attr.prog_type != BPF_PROG_TYPE_UNSPEC) {
727 p_err("program type already specified");
728 goto err_free_reuse_maps;
729 }
730 if (!REQ_ARGS(1))
731 goto err_free_reuse_maps;
732
733 /* Put a '/' at the end of type to appease libbpf */
734 type = malloc(strlen(*argv) + 2);
735 if (!type) {
736 p_err("mem alloc failed");
737 goto err_free_reuse_maps;
738 }
739 *type = 0;
740 strcat(type, *argv);
741 strcat(type, "/");
742
743 err = libbpf_prog_type_by_name(type, &attr.prog_type,
744 &expected_attach_type);
745 free(type);
746 if (err < 0) {
747 p_err("unknown program type '%s'", *argv);
748 goto err_free_reuse_maps;
749 }
750 NEXT_ARG();
751 } else if (is_prefix(*argv, "map")) {
752 char *endptr, *name;
753 int fd;
754
755 NEXT_ARG();
756
757 if (!REQ_ARGS(4))
758 goto err_free_reuse_maps;
759
760 if (is_prefix(*argv, "idx")) {
761 NEXT_ARG();
762
763 idx = strtoul(*argv, &endptr, 0);
764 if (*endptr) {
765 p_err("can't parse %s as IDX", *argv);
766 goto err_free_reuse_maps;
767 }
768 name = NULL;
769 } else if (is_prefix(*argv, "name")) {
770 NEXT_ARG();
771
772 name = *argv;
773 idx = -1;
774 } else {
775 p_err("expected 'idx' or 'name', got: '%s'?",
776 *argv);
777 goto err_free_reuse_maps;
778 }
779 NEXT_ARG();
780
781 fd = map_parse_fd(&argc, &argv);
782 if (fd < 0)
783 goto err_free_reuse_maps;
784
785 map_replace = reallocarray(map_replace, old_map_fds + 1,
786 sizeof(*map_replace));
787 if (!map_replace) {
788 p_err("mem alloc failed");
789 goto err_free_reuse_maps;
790 }
791 map_replace[old_map_fds].idx = idx;
792 map_replace[old_map_fds].name = name;
793 map_replace[old_map_fds].fd = fd;
794 old_map_fds++;
795 } else if (is_prefix(*argv, "dev")) {
796 NEXT_ARG();
797
798 if (ifindex) {
799 p_err("offload device already specified");
800 goto err_free_reuse_maps;
801 }
802 if (!REQ_ARGS(1))
803 goto err_free_reuse_maps;
804
805 ifindex = if_nametoindex(*argv);
806 if (!ifindex) {
807 p_err("unrecognized netdevice '%s': %s",
808 *argv, strerror(errno));
809 goto err_free_reuse_maps;
810 }
811 NEXT_ARG();
812 } else {
813 p_err("expected no more arguments, 'type', 'map' or 'dev', got: '%s'?",
814 *argv);
815 goto err_free_reuse_maps;
816 }
817 }
818
819 obj = bpf_object__open_xattr(&attr);
820 if (IS_ERR_OR_NULL(obj)) {
821 p_err("failed to open object file");
822 goto err_free_reuse_maps;
823 }
824
825 prog = bpf_program__next(NULL, obj);
826 if (!prog) {
827 p_err("object file doesn't contain any bpf program");
828 goto err_close_obj;
829 }
830
831 bpf_program__set_ifindex(prog, ifindex);
832 if (attr.prog_type == BPF_PROG_TYPE_UNSPEC) {
833 const char *sec_name = bpf_program__title(prog, false);
834
835 err = libbpf_prog_type_by_name(sec_name, &attr.prog_type,
836 &expected_attach_type);
837 if (err < 0) {
838 p_err("failed to guess program type based on section name %s\n",
839 sec_name);
840 goto err_close_obj;
841 }
842 }
843 bpf_program__set_type(prog, attr.prog_type);
844 bpf_program__set_expected_attach_type(prog, expected_attach_type);
845
846 qsort(map_replace, old_map_fds, sizeof(*map_replace),
847 map_replace_compar);
848
849 /* After the sort maps by name will be first on the list, because they
850 * have idx == -1. Resolve them.
851 */
852 j = 0;
853 while (j < old_map_fds && map_replace[j].name) {
854 i = 0;
855 bpf_map__for_each(map, obj) {
856 if (!strcmp(bpf_map__name(map), map_replace[j].name)) {
857 map_replace[j].idx = i;
858 break;
859 }
860 i++;
861 }
862 if (map_replace[j].idx == -1) {
863 p_err("unable to find map '%s'", map_replace[j].name);
864 goto err_close_obj;
865 }
866 j++;
867 }
868 /* Resort if any names were resolved */
869 if (j)
870 qsort(map_replace, old_map_fds, sizeof(*map_replace),
871 map_replace_compar);
872
873 /* Set ifindex and name reuse */
874 j = 0;
875 idx = 0;
876 bpf_map__for_each(map, obj) {
877 if (!bpf_map__is_offload_neutral(map))
878 bpf_map__set_ifindex(map, ifindex);
879
880 if (j < old_map_fds && idx == map_replace[j].idx) {
881 err = bpf_map__reuse_fd(map, map_replace[j++].fd);
882 if (err) {
883 p_err("unable to set up map reuse: %d", err);
884 goto err_close_obj;
885 }
886
887 /* Next reuse wants to apply to the same map */
888 if (j < old_map_fds && map_replace[j].idx == idx) {
889 p_err("replacement for map idx %d specified more than once",
890 idx);
891 goto err_close_obj;
892 }
893 }
894
895 idx++;
896 }
897 if (j < old_map_fds) {
898 p_err("map idx '%d' not used", map_replace[j].idx);
899 goto err_close_obj;
900 }
901
902 err = bpf_object__load(obj);
903 if (err) {
904 p_err("failed to load object file");
905 goto err_close_obj;
695 } 906 }
696 907
697 if (do_pin_fd(prog_fd, argv[1])) 908 if (do_pin_fd(bpf_program__fd(prog), pinfile))
698 goto err_close_obj; 909 goto err_close_obj;
699 910
700 if (json_output) 911 if (json_output)
701 jsonw_null(json_wtr); 912 jsonw_null(json_wtr);
702 913
703 bpf_object__close(obj); 914 bpf_object__close(obj);
915 for (i = 0; i < old_map_fds; i++)
916 close(map_replace[i].fd);
917 free(map_replace);
704 918
705 return 0; 919 return 0;
706 920
707err_close_obj: 921err_close_obj:
708 bpf_object__close(obj); 922 bpf_object__close(obj);
923err_free_reuse_maps:
924 for (i = 0; i < old_map_fds; i++)
925 close(map_replace[i].fd);
926 free(map_replace);
709 return -1; 927 return -1;
710} 928}
711 929
@@ -721,10 +939,19 @@ static int do_help(int argc, char **argv)
721 " %s %s dump xlated PROG [{ file FILE | opcodes | visual }]\n" 939 " %s %s dump xlated PROG [{ file FILE | opcodes | visual }]\n"
722 " %s %s dump jited PROG [{ file FILE | opcodes }]\n" 940 " %s %s dump jited PROG [{ file FILE | opcodes }]\n"
723 " %s %s pin PROG FILE\n" 941 " %s %s pin PROG FILE\n"
724 " %s %s load OBJ FILE\n" 942 " %s %s load OBJ FILE [type TYPE] [dev NAME] \\\n"
943 " [map { idx IDX | name NAME } MAP]\n"
725 " %s %s help\n" 944 " %s %s help\n"
726 "\n" 945 "\n"
946 " " HELP_SPEC_MAP "\n"
727 " " HELP_SPEC_PROGRAM "\n" 947 " " HELP_SPEC_PROGRAM "\n"
948 " TYPE := { socket | kprobe | kretprobe | classifier | action |\n"
949 " tracepoint | raw_tracepoint | xdp | perf_event | cgroup/skb |\n"
950 " cgroup/sock | cgroup/dev | lwt_in | lwt_out | lwt_xmit |\n"
951 " lwt_seg6local | sockops | sk_skb | sk_msg | lirc_mode2 |\n"
952 " cgroup/bind4 | cgroup/bind6 | cgroup/post_bind4 |\n"
953 " cgroup/post_bind6 | cgroup/connect4 | cgroup/connect6 |\n"
954 " cgroup/sendmsg4 | cgroup/sendmsg6 }\n"
728 " " HELP_SPEC_OPTIONS "\n" 955 " " HELP_SPEC_OPTIONS "\n"
729 "", 956 "",
730 bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], 957 bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],
diff --git a/tools/bpf/bpftool/xlated_dumper.c b/tools/bpf/bpftool/xlated_dumper.c
index b97f1da60dd1..3284759df98a 100644
--- a/tools/bpf/bpftool/xlated_dumper.c
+++ b/tools/bpf/bpftool/xlated_dumper.c
@@ -35,6 +35,7 @@
35 * POSSIBILITY OF SUCH DAMAGE. 35 * POSSIBILITY OF SUCH DAMAGE.
36 */ 36 */
37 37
38#define _GNU_SOURCE
38#include <stdarg.h> 39#include <stdarg.h>
39#include <stdio.h> 40#include <stdio.h>
40#include <stdlib.h> 41#include <stdlib.h>
@@ -66,9 +67,8 @@ void kernel_syms_load(struct dump_data *dd)
66 while (!feof(fp)) { 67 while (!feof(fp)) {
67 if (!fgets(buff, sizeof(buff), fp)) 68 if (!fgets(buff, sizeof(buff), fp))
68 break; 69 break;
69 tmp = realloc(dd->sym_mapping, 70 tmp = reallocarray(dd->sym_mapping, dd->sym_count + 1,
70 (dd->sym_count + 1) * 71 sizeof(*dd->sym_mapping));
71 sizeof(*dd->sym_mapping));
72 if (!tmp) { 72 if (!tmp) {
73out: 73out:
74 free(dd->sym_mapping); 74 free(dd->sym_mapping);
diff --git a/tools/build/Build.include b/tools/build/Build.include
index 950c1504ca37..9ec01f4454f9 100644
--- a/tools/build/Build.include
+++ b/tools/build/Build.include
@@ -98,4 +98,4 @@ cxx_flags = -Wp,-MD,$(depfile) -Wp,-MT,$@ $(CXXFLAGS) -D"BUILD_STR(s)=\#s" $(CXX
98### 98###
99## HOSTCC C flags 99## HOSTCC C flags
100 100
101host_c_flags = -Wp,-MD,$(depfile) -Wp,-MT,$@ $(HOSTCFLAGS) -D"BUILD_STR(s)=\#s" $(HOSTCFLAGS_$(basetarget).o) $(HOSTCFLAGS_$(obj)) 101host_c_flags = -Wp,-MD,$(depfile) -Wp,-MT,$@ $(KBUILD_HOSTCFLAGS) -D"BUILD_STR(s)=\#s" $(HOSTCFLAGS_$(basetarget).o) $(HOSTCFLAGS_$(obj))
diff --git a/tools/build/Makefile b/tools/build/Makefile
index 5edf65e684ab..727050c40f09 100644
--- a/tools/build/Makefile
+++ b/tools/build/Makefile
@@ -43,7 +43,7 @@ $(OUTPUT)fixdep-in.o: FORCE
43 $(Q)$(MAKE) $(build)=fixdep 43 $(Q)$(MAKE) $(build)=fixdep
44 44
45$(OUTPUT)fixdep: $(OUTPUT)fixdep-in.o 45$(OUTPUT)fixdep: $(OUTPUT)fixdep-in.o
46 $(QUIET_LINK)$(HOSTCC) $(HOSTLDFLAGS) -o $@ $< 46 $(QUIET_LINK)$(HOSTCC) $(KBUILD_HOSTLDFLAGS) -o $@ $<
47 47
48FORCE: 48FORCE:
49 49
diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
index 5b6dda3b1ca8..f216b2f5c3d7 100644
--- a/tools/build/Makefile.feature
+++ b/tools/build/Makefile.feature
@@ -57,6 +57,7 @@ FEATURE_TESTS_BASIC := \
57 libunwind-aarch64 \ 57 libunwind-aarch64 \
58 pthread-attr-setaffinity-np \ 58 pthread-attr-setaffinity-np \
59 pthread-barrier \ 59 pthread-barrier \
60 reallocarray \
60 stackprotector-all \ 61 stackprotector-all \
61 timerfd \ 62 timerfd \
62 libdw-dwarf-unwind \ 63 libdw-dwarf-unwind \
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index dac9563b5470..0516259be70f 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -14,6 +14,7 @@ FILES= \
14 test-libaudit.bin \ 14 test-libaudit.bin \
15 test-libbfd.bin \ 15 test-libbfd.bin \
16 test-disassembler-four-args.bin \ 16 test-disassembler-four-args.bin \
17 test-reallocarray.bin \
17 test-liberty.bin \ 18 test-liberty.bin \
18 test-liberty-z.bin \ 19 test-liberty-z.bin \
19 test-cplus-demangle.bin \ 20 test-cplus-demangle.bin \
@@ -204,6 +205,9 @@ $(OUTPUT)test-libbfd.bin:
204$(OUTPUT)test-disassembler-four-args.bin: 205$(OUTPUT)test-disassembler-four-args.bin:
205 $(BUILD) -DPACKAGE='"perf"' -lbfd -lopcodes 206 $(BUILD) -DPACKAGE='"perf"' -lbfd -lopcodes
206 207
208$(OUTPUT)test-reallocarray.bin:
209 $(BUILD)
210
207$(OUTPUT)test-liberty.bin: 211$(OUTPUT)test-liberty.bin:
208 $(CC) $(CFLAGS) -Wall -Werror -o $@ test-libbfd.c -DPACKAGE='"perf"' $(LDFLAGS) -lbfd -ldl -liberty 212 $(CC) $(CFLAGS) -Wall -Werror -o $@ test-libbfd.c -DPACKAGE='"perf"' $(LDFLAGS) -lbfd -ldl -liberty
209 213
diff --git a/tools/build/feature/test-reallocarray.c b/tools/build/feature/test-reallocarray.c
new file mode 100644
index 000000000000..8170de35150d
--- /dev/null
+++ b/tools/build/feature/test-reallocarray.c
@@ -0,0 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
2#define _GNU_SOURCE
3#include <stdlib.h>
4
5int main(void)
6{
7 return !!reallocarray(NULL, 1, 1);
8}
diff --git a/tools/include/linux/compiler-gcc.h b/tools/include/linux/compiler-gcc.h
index 70fe61295733..0d35f18006a1 100644
--- a/tools/include/linux/compiler-gcc.h
+++ b/tools/include/linux/compiler-gcc.h
@@ -36,3 +36,7 @@
36#endif 36#endif
37#define __printf(a, b) __attribute__((format(printf, a, b))) 37#define __printf(a, b) __attribute__((format(printf, a, b)))
38#define __scanf(a, b) __attribute__((format(scanf, a, b))) 38#define __scanf(a, b) __attribute__((format(scanf, a, b)))
39
40#if GCC_VERSION >= 50100
41#define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1
42#endif
diff --git a/tools/include/linux/overflow.h b/tools/include/linux/overflow.h
new file mode 100644
index 000000000000..8712ff70995f
--- /dev/null
+++ b/tools/include/linux/overflow.h
@@ -0,0 +1,278 @@
1/* SPDX-License-Identifier: GPL-2.0 OR MIT */
2#ifndef __LINUX_OVERFLOW_H
3#define __LINUX_OVERFLOW_H
4
5#include <linux/compiler.h>
6
7/*
8 * In the fallback code below, we need to compute the minimum and
9 * maximum values representable in a given type. These macros may also
10 * be useful elsewhere, so we provide them outside the
11 * COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW block.
12 *
13 * It would seem more obvious to do something like
14 *
15 * #define type_min(T) (T)(is_signed_type(T) ? (T)1 << (8*sizeof(T)-1) : 0)
16 * #define type_max(T) (T)(is_signed_type(T) ? ((T)1 << (8*sizeof(T)-1)) - 1 : ~(T)0)
17 *
18 * Unfortunately, the middle expressions, strictly speaking, have
19 * undefined behaviour, and at least some versions of gcc warn about
20 * the type_max expression (but not if -fsanitize=undefined is in
21 * effect; in that case, the warning is deferred to runtime...).
22 *
23 * The slightly excessive casting in type_min is to make sure the
24 * macros also produce sensible values for the exotic type _Bool. [The
25 * overflow checkers only almost work for _Bool, but that's
26 * a-feature-not-a-bug, since people shouldn't be doing arithmetic on
27 * _Bools. Besides, the gcc builtins don't allow _Bool* as third
28 * argument.]
29 *
30 * Idea stolen from
31 * https://mail-index.netbsd.org/tech-misc/2007/02/05/0000.html -
32 * credit to Christian Biere.
33 */
34#define is_signed_type(type) (((type)(-1)) < (type)1)
35#define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - is_signed_type(type)))
36#define type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T)))
37#define type_min(T) ((T)((T)-type_max(T)-(T)1))
38
39
40#ifdef COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW
41/*
42 * For simplicity and code hygiene, the fallback code below insists on
43 * a, b and *d having the same type (similar to the min() and max()
44 * macros), whereas gcc's type-generic overflow checkers accept
45 * different types. Hence we don't just make check_add_overflow an
46 * alias for __builtin_add_overflow, but add type checks similar to
47 * below.
48 */
49#define check_add_overflow(a, b, d) ({ \
50 typeof(a) __a = (a); \
51 typeof(b) __b = (b); \
52 typeof(d) __d = (d); \
53 (void) (&__a == &__b); \
54 (void) (&__a == __d); \
55 __builtin_add_overflow(__a, __b, __d); \
56})
57
58#define check_sub_overflow(a, b, d) ({ \
59 typeof(a) __a = (a); \
60 typeof(b) __b = (b); \
61 typeof(d) __d = (d); \
62 (void) (&__a == &__b); \
63 (void) (&__a == __d); \
64 __builtin_sub_overflow(__a, __b, __d); \
65})
66
67#define check_mul_overflow(a, b, d) ({ \
68 typeof(a) __a = (a); \
69 typeof(b) __b = (b); \
70 typeof(d) __d = (d); \
71 (void) (&__a == &__b); \
72 (void) (&__a == __d); \
73 __builtin_mul_overflow(__a, __b, __d); \
74})
75
76#else
77
78
79/* Checking for unsigned overflow is relatively easy without causing UB. */
80#define __unsigned_add_overflow(a, b, d) ({ \
81 typeof(a) __a = (a); \
82 typeof(b) __b = (b); \
83 typeof(d) __d = (d); \
84 (void) (&__a == &__b); \
85 (void) (&__a == __d); \
86 *__d = __a + __b; \
87 *__d < __a; \
88})
89#define __unsigned_sub_overflow(a, b, d) ({ \
90 typeof(a) __a = (a); \
91 typeof(b) __b = (b); \
92 typeof(d) __d = (d); \
93 (void) (&__a == &__b); \
94 (void) (&__a == __d); \
95 *__d = __a - __b; \
96 __a < __b; \
97})
98/*
99 * If one of a or b is a compile-time constant, this avoids a division.
100 */
101#define __unsigned_mul_overflow(a, b, d) ({ \
102 typeof(a) __a = (a); \
103 typeof(b) __b = (b); \
104 typeof(d) __d = (d); \
105 (void) (&__a == &__b); \
106 (void) (&__a == __d); \
107 *__d = __a * __b; \
108 __builtin_constant_p(__b) ? \
109 __b > 0 && __a > type_max(typeof(__a)) / __b : \
110 __a > 0 && __b > type_max(typeof(__b)) / __a; \
111})
112
113/*
114 * For signed types, detecting overflow is much harder, especially if
115 * we want to avoid UB. But the interface of these macros is such that
116 * we must provide a result in *d, and in fact we must produce the
117 * result promised by gcc's builtins, which is simply the possibly
118 * wrapped-around value. Fortunately, we can just formally do the
119 * operations in the widest relevant unsigned type (u64) and then
120 * truncate the result - gcc is smart enough to generate the same code
121 * with and without the (u64) casts.
122 */
123
124/*
125 * Adding two signed integers can overflow only if they have the same
126 * sign, and overflow has happened iff the result has the opposite
127 * sign.
128 */
129#define __signed_add_overflow(a, b, d) ({ \
130 typeof(a) __a = (a); \
131 typeof(b) __b = (b); \
132 typeof(d) __d = (d); \
133 (void) (&__a == &__b); \
134 (void) (&__a == __d); \
135 *__d = (u64)__a + (u64)__b; \
136 (((~(__a ^ __b)) & (*__d ^ __a)) \
137 & type_min(typeof(__a))) != 0; \
138})
139
140/*
141 * Subtraction is similar, except that overflow can now happen only
142 * when the signs are opposite. In this case, overflow has happened if
143 * the result has the opposite sign of a.
144 */
145#define __signed_sub_overflow(a, b, d) ({ \
146 typeof(a) __a = (a); \
147 typeof(b) __b = (b); \
148 typeof(d) __d = (d); \
149 (void) (&__a == &__b); \
150 (void) (&__a == __d); \
151 *__d = (u64)__a - (u64)__b; \
152 ((((__a ^ __b)) & (*__d ^ __a)) \
153 & type_min(typeof(__a))) != 0; \
154})
155
156/*
157 * Signed multiplication is rather hard. gcc always follows C99, so
158 * division is truncated towards 0. This means that we can write the
159 * overflow check like this:
160 *
161 * (a > 0 && (b > MAX/a || b < MIN/a)) ||
162 * (a < -1 && (b > MIN/a || b < MAX/a) ||
163 * (a == -1 && b == MIN)
164 *
165 * The redundant casts of -1 are to silence an annoying -Wtype-limits
166 * (included in -Wextra) warning: When the type is u8 or u16, the
167 * __b_c_e in check_mul_overflow obviously selects
168 * __unsigned_mul_overflow, but unfortunately gcc still parses this
169 * code and warns about the limited range of __b.
170 */
171
172#define __signed_mul_overflow(a, b, d) ({ \
173 typeof(a) __a = (a); \
174 typeof(b) __b = (b); \
175 typeof(d) __d = (d); \
176 typeof(a) __tmax = type_max(typeof(a)); \
177 typeof(a) __tmin = type_min(typeof(a)); \
178 (void) (&__a == &__b); \
179 (void) (&__a == __d); \
180 *__d = (u64)__a * (u64)__b; \
181 (__b > 0 && (__a > __tmax/__b || __a < __tmin/__b)) || \
182 (__b < (typeof(__b))-1 && (__a > __tmin/__b || __a < __tmax/__b)) || \
183 (__b == (typeof(__b))-1 && __a == __tmin); \
184})
185
186
187#define check_add_overflow(a, b, d) \
188 __builtin_choose_expr(is_signed_type(typeof(a)), \
189 __signed_add_overflow(a, b, d), \
190 __unsigned_add_overflow(a, b, d))
191
192#define check_sub_overflow(a, b, d) \
193 __builtin_choose_expr(is_signed_type(typeof(a)), \
194 __signed_sub_overflow(a, b, d), \
195 __unsigned_sub_overflow(a, b, d))
196
197#define check_mul_overflow(a, b, d) \
198 __builtin_choose_expr(is_signed_type(typeof(a)), \
199 __signed_mul_overflow(a, b, d), \
200 __unsigned_mul_overflow(a, b, d))
201
202
203#endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */
204
205/**
206 * array_size() - Calculate size of 2-dimensional array.
207 *
208 * @a: dimension one
209 * @b: dimension two
210 *
211 * Calculates size of 2-dimensional array: @a * @b.
212 *
213 * Returns: number of bytes needed to represent the array or SIZE_MAX on
214 * overflow.
215 */
216static inline __must_check size_t array_size(size_t a, size_t b)
217{
218 size_t bytes;
219
220 if (check_mul_overflow(a, b, &bytes))
221 return SIZE_MAX;
222
223 return bytes;
224}
225
226/**
227 * array3_size() - Calculate size of 3-dimensional array.
228 *
229 * @a: dimension one
230 * @b: dimension two
231 * @c: dimension three
232 *
233 * Calculates size of 3-dimensional array: @a * @b * @c.
234 *
235 * Returns: number of bytes needed to represent the array or SIZE_MAX on
236 * overflow.
237 */
238static inline __must_check size_t array3_size(size_t a, size_t b, size_t c)
239{
240 size_t bytes;
241
242 if (check_mul_overflow(a, b, &bytes))
243 return SIZE_MAX;
244 if (check_mul_overflow(bytes, c, &bytes))
245 return SIZE_MAX;
246
247 return bytes;
248}
249
250static inline __must_check size_t __ab_c_size(size_t n, size_t size, size_t c)
251{
252 size_t bytes;
253
254 if (check_mul_overflow(n, size, &bytes))
255 return SIZE_MAX;
256 if (check_add_overflow(bytes, c, &bytes))
257 return SIZE_MAX;
258
259 return bytes;
260}
261
262/**
263 * struct_size() - Calculate size of structure with trailing array.
264 * @p: Pointer to the structure.
265 * @member: Name of the array member.
266 * @n: Number of elements in the array.
267 *
268 * Calculates size of memory needed for structure @p followed by an
269 * array of @n @member elements.
270 *
271 * Return: number of bytes needed or SIZE_MAX on overflow.
272 */
273#define struct_size(p, member, n) \
274 __ab_c_size(n, \
275 sizeof(*(p)->member) + __must_be_array((p)->member),\
276 sizeof(*(p)))
277
278#endif /* __LINUX_OVERFLOW_H */
diff --git a/tools/include/tools/libc_compat.h b/tools/include/tools/libc_compat.h
new file mode 100644
index 000000000000..664ced8cb1b0
--- /dev/null
+++ b/tools/include/tools/libc_compat.h
@@ -0,0 +1,20 @@
1// SPDX-License-Identifier: GPL-2.0+
2/* Copyright (C) 2018 Netronome Systems, Inc. */
3
4#ifndef __TOOLS_LIBC_COMPAT_H
5#define __TOOLS_LIBC_COMPAT_H
6
7#include <stdlib.h>
8#include <linux/overflow.h>
9
10#ifdef COMPAT_NEED_REALLOCARRAY
11static inline void *reallocarray(void *ptr, size_t nmemb, size_t size)
12{
13 size_t bytes;
14
15 if (unlikely(check_mul_overflow(nmemb, size, &bytes)))
16 return NULL;
17 return realloc(ptr, bytes);
18}
19#endif
20#endif
diff --git a/tools/include/uapi/asm-generic/unistd.h b/tools/include/uapi/asm-generic/unistd.h
new file mode 100644
index 000000000000..42990676a55e
--- /dev/null
+++ b/tools/include/uapi/asm-generic/unistd.h
@@ -0,0 +1,783 @@
1/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2#include <asm/bitsperlong.h>
3
4/*
5 * This file contains the system call numbers, based on the
6 * layout of the x86-64 architecture, which embeds the
7 * pointer to the syscall in the table.
8 *
9 * As a basic principle, no duplication of functionality
10 * should be added, e.g. we don't use lseek when llseek
11 * is present. New architectures should use this file
12 * and implement the less feature-full calls in user space.
13 */
14
15#ifndef __SYSCALL
16#define __SYSCALL(x, y)
17#endif
18
19#if __BITS_PER_LONG == 32 || defined(__SYSCALL_COMPAT)
20#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _32)
21#else
22#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _64)
23#endif
24
25#ifdef __SYSCALL_COMPAT
26#define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _comp)
27#define __SC_COMP_3264(_nr, _32, _64, _comp) __SYSCALL(_nr, _comp)
28#else
29#define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _sys)
30#define __SC_COMP_3264(_nr, _32, _64, _comp) __SC_3264(_nr, _32, _64)
31#endif
32
33#define __NR_io_setup 0
34__SC_COMP(__NR_io_setup, sys_io_setup, compat_sys_io_setup)
35#define __NR_io_destroy 1
36__SYSCALL(__NR_io_destroy, sys_io_destroy)
37#define __NR_io_submit 2
38__SC_COMP(__NR_io_submit, sys_io_submit, compat_sys_io_submit)
39#define __NR_io_cancel 3
40__SYSCALL(__NR_io_cancel, sys_io_cancel)
41#define __NR_io_getevents 4
42__SC_COMP(__NR_io_getevents, sys_io_getevents, compat_sys_io_getevents)
43
44/* fs/xattr.c */
45#define __NR_setxattr 5
46__SYSCALL(__NR_setxattr, sys_setxattr)
47#define __NR_lsetxattr 6
48__SYSCALL(__NR_lsetxattr, sys_lsetxattr)
49#define __NR_fsetxattr 7
50__SYSCALL(__NR_fsetxattr, sys_fsetxattr)
51#define __NR_getxattr 8
52__SYSCALL(__NR_getxattr, sys_getxattr)
53#define __NR_lgetxattr 9
54__SYSCALL(__NR_lgetxattr, sys_lgetxattr)
55#define __NR_fgetxattr 10
56__SYSCALL(__NR_fgetxattr, sys_fgetxattr)
57#define __NR_listxattr 11
58__SYSCALL(__NR_listxattr, sys_listxattr)
59#define __NR_llistxattr 12
60__SYSCALL(__NR_llistxattr, sys_llistxattr)
61#define __NR_flistxattr 13
62__SYSCALL(__NR_flistxattr, sys_flistxattr)
63#define __NR_removexattr 14
64__SYSCALL(__NR_removexattr, sys_removexattr)
65#define __NR_lremovexattr 15
66__SYSCALL(__NR_lremovexattr, sys_lremovexattr)
67#define __NR_fremovexattr 16
68__SYSCALL(__NR_fremovexattr, sys_fremovexattr)
69
70/* fs/dcache.c */
71#define __NR_getcwd 17
72__SYSCALL(__NR_getcwd, sys_getcwd)
73
74/* fs/cookies.c */
75#define __NR_lookup_dcookie 18
76__SC_COMP(__NR_lookup_dcookie, sys_lookup_dcookie, compat_sys_lookup_dcookie)
77
78/* fs/eventfd.c */
79#define __NR_eventfd2 19
80__SYSCALL(__NR_eventfd2, sys_eventfd2)
81
82/* fs/eventpoll.c */
83#define __NR_epoll_create1 20
84__SYSCALL(__NR_epoll_create1, sys_epoll_create1)
85#define __NR_epoll_ctl 21
86__SYSCALL(__NR_epoll_ctl, sys_epoll_ctl)
87#define __NR_epoll_pwait 22
88__SC_COMP(__NR_epoll_pwait, sys_epoll_pwait, compat_sys_epoll_pwait)
89
90/* fs/fcntl.c */
91#define __NR_dup 23
92__SYSCALL(__NR_dup, sys_dup)
93#define __NR_dup3 24
94__SYSCALL(__NR_dup3, sys_dup3)
95#define __NR3264_fcntl 25
96__SC_COMP_3264(__NR3264_fcntl, sys_fcntl64, sys_fcntl, compat_sys_fcntl64)
97
98/* fs/inotify_user.c */
99#define __NR_inotify_init1 26
100__SYSCALL(__NR_inotify_init1, sys_inotify_init1)
101#define __NR_inotify_add_watch 27
102__SYSCALL(__NR_inotify_add_watch, sys_inotify_add_watch)
103#define __NR_inotify_rm_watch 28
104__SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch)
105
106/* fs/ioctl.c */
107#define __NR_ioctl 29
108__SC_COMP(__NR_ioctl, sys_ioctl, compat_sys_ioctl)
109
110/* fs/ioprio.c */
111#define __NR_ioprio_set 30
112__SYSCALL(__NR_ioprio_set, sys_ioprio_set)
113#define __NR_ioprio_get 31
114__SYSCALL(__NR_ioprio_get, sys_ioprio_get)
115
116/* fs/locks.c */
117#define __NR_flock 32
118__SYSCALL(__NR_flock, sys_flock)
119
120/* fs/namei.c */
121#define __NR_mknodat 33
122__SYSCALL(__NR_mknodat, sys_mknodat)
123#define __NR_mkdirat 34
124__SYSCALL(__NR_mkdirat, sys_mkdirat)
125#define __NR_unlinkat 35
126__SYSCALL(__NR_unlinkat, sys_unlinkat)
127#define __NR_symlinkat 36
128__SYSCALL(__NR_symlinkat, sys_symlinkat)
129#define __NR_linkat 37
130__SYSCALL(__NR_linkat, sys_linkat)
131#ifdef __ARCH_WANT_RENAMEAT
132/* renameat is superseded with flags by renameat2 */
133#define __NR_renameat 38
134__SYSCALL(__NR_renameat, sys_renameat)
135#endif /* __ARCH_WANT_RENAMEAT */
136
137/* fs/namespace.c */
138#define __NR_umount2 39
139__SYSCALL(__NR_umount2, sys_umount)
140#define __NR_mount 40
141__SC_COMP(__NR_mount, sys_mount, compat_sys_mount)
142#define __NR_pivot_root 41
143__SYSCALL(__NR_pivot_root, sys_pivot_root)
144
145/* fs/nfsctl.c */
146#define __NR_nfsservctl 42
147__SYSCALL(__NR_nfsservctl, sys_ni_syscall)
148
149/* fs/open.c */
150#define __NR3264_statfs 43
151__SC_COMP_3264(__NR3264_statfs, sys_statfs64, sys_statfs, \
152 compat_sys_statfs64)
153#define __NR3264_fstatfs 44
154__SC_COMP_3264(__NR3264_fstatfs, sys_fstatfs64, sys_fstatfs, \
155 compat_sys_fstatfs64)
156#define __NR3264_truncate 45
157__SC_COMP_3264(__NR3264_truncate, sys_truncate64, sys_truncate, \
158 compat_sys_truncate64)
159#define __NR3264_ftruncate 46
160__SC_COMP_3264(__NR3264_ftruncate, sys_ftruncate64, sys_ftruncate, \
161 compat_sys_ftruncate64)
162
163#define __NR_fallocate 47
164__SC_COMP(__NR_fallocate, sys_fallocate, compat_sys_fallocate)
165#define __NR_faccessat 48
166__SYSCALL(__NR_faccessat, sys_faccessat)
167#define __NR_chdir 49
168__SYSCALL(__NR_chdir, sys_chdir)
169#define __NR_fchdir 50
170__SYSCALL(__NR_fchdir, sys_fchdir)
171#define __NR_chroot 51
172__SYSCALL(__NR_chroot, sys_chroot)
173#define __NR_fchmod 52
174__SYSCALL(__NR_fchmod, sys_fchmod)
175#define __NR_fchmodat 53
176__SYSCALL(__NR_fchmodat, sys_fchmodat)
177#define __NR_fchownat 54
178__SYSCALL(__NR_fchownat, sys_fchownat)
179#define __NR_fchown 55
180__SYSCALL(__NR_fchown, sys_fchown)
181#define __NR_openat 56
182__SC_COMP(__NR_openat, sys_openat, compat_sys_openat)
183#define __NR_close 57
184__SYSCALL(__NR_close, sys_close)
185#define __NR_vhangup 58
186__SYSCALL(__NR_vhangup, sys_vhangup)
187
188/* fs/pipe.c */
189#define __NR_pipe2 59
190__SYSCALL(__NR_pipe2, sys_pipe2)
191
192/* fs/quota.c */
193#define __NR_quotactl 60
194__SYSCALL(__NR_quotactl, sys_quotactl)
195
196/* fs/readdir.c */
197#define __NR_getdents64 61
198__SYSCALL(__NR_getdents64, sys_getdents64)
199
200/* fs/read_write.c */
201#define __NR3264_lseek 62
202__SC_3264(__NR3264_lseek, sys_llseek, sys_lseek)
203#define __NR_read 63
204__SYSCALL(__NR_read, sys_read)
205#define __NR_write 64
206__SYSCALL(__NR_write, sys_write)
207#define __NR_readv 65
208__SC_COMP(__NR_readv, sys_readv, compat_sys_readv)
209#define __NR_writev 66
210__SC_COMP(__NR_writev, sys_writev, compat_sys_writev)
211#define __NR_pread64 67
212__SC_COMP(__NR_pread64, sys_pread64, compat_sys_pread64)
213#define __NR_pwrite64 68
214__SC_COMP(__NR_pwrite64, sys_pwrite64, compat_sys_pwrite64)
215#define __NR_preadv 69
216__SC_COMP(__NR_preadv, sys_preadv, compat_sys_preadv)
217#define __NR_pwritev 70
218__SC_COMP(__NR_pwritev, sys_pwritev, compat_sys_pwritev)
219
220/* fs/sendfile.c */
221#define __NR3264_sendfile 71
222__SYSCALL(__NR3264_sendfile, sys_sendfile64)
223
224/* fs/select.c */
225#define __NR_pselect6 72
226__SC_COMP(__NR_pselect6, sys_pselect6, compat_sys_pselect6)
227#define __NR_ppoll 73
228__SC_COMP(__NR_ppoll, sys_ppoll, compat_sys_ppoll)
229
230/* fs/signalfd.c */
231#define __NR_signalfd4 74
232__SC_COMP(__NR_signalfd4, sys_signalfd4, compat_sys_signalfd4)
233
234/* fs/splice.c */
235#define __NR_vmsplice 75
236__SC_COMP(__NR_vmsplice, sys_vmsplice, compat_sys_vmsplice)
237#define __NR_splice 76
238__SYSCALL(__NR_splice, sys_splice)
239#define __NR_tee 77
240__SYSCALL(__NR_tee, sys_tee)
241
242/* fs/stat.c */
243#define __NR_readlinkat 78
244__SYSCALL(__NR_readlinkat, sys_readlinkat)
245#define __NR3264_fstatat 79
246__SC_3264(__NR3264_fstatat, sys_fstatat64, sys_newfstatat)
247#define __NR3264_fstat 80
248__SC_3264(__NR3264_fstat, sys_fstat64, sys_newfstat)
249
250/* fs/sync.c */
251#define __NR_sync 81
252__SYSCALL(__NR_sync, sys_sync)
253#define __NR_fsync 82
254__SYSCALL(__NR_fsync, sys_fsync)
255#define __NR_fdatasync 83
256__SYSCALL(__NR_fdatasync, sys_fdatasync)
257#ifdef __ARCH_WANT_SYNC_FILE_RANGE2
258#define __NR_sync_file_range2 84
259__SC_COMP(__NR_sync_file_range2, sys_sync_file_range2, \
260 compat_sys_sync_file_range2)
261#else
262#define __NR_sync_file_range 84
263__SC_COMP(__NR_sync_file_range, sys_sync_file_range, \
264 compat_sys_sync_file_range)
265#endif
266
267/* fs/timerfd.c */
268#define __NR_timerfd_create 85
269__SYSCALL(__NR_timerfd_create, sys_timerfd_create)
270#define __NR_timerfd_settime 86
271__SC_COMP(__NR_timerfd_settime, sys_timerfd_settime, \
272 compat_sys_timerfd_settime)
273#define __NR_timerfd_gettime 87
274__SC_COMP(__NR_timerfd_gettime, sys_timerfd_gettime, \
275 compat_sys_timerfd_gettime)
276
277/* fs/utimes.c */
278#define __NR_utimensat 88
279__SC_COMP(__NR_utimensat, sys_utimensat, compat_sys_utimensat)
280
281/* kernel/acct.c */
282#define __NR_acct 89
283__SYSCALL(__NR_acct, sys_acct)
284
285/* kernel/capability.c */
286#define __NR_capget 90
287__SYSCALL(__NR_capget, sys_capget)
288#define __NR_capset 91
289__SYSCALL(__NR_capset, sys_capset)
290
291/* kernel/exec_domain.c */
292#define __NR_personality 92
293__SYSCALL(__NR_personality, sys_personality)
294
295/* kernel/exit.c */
296#define __NR_exit 93
297__SYSCALL(__NR_exit, sys_exit)
298#define __NR_exit_group 94
299__SYSCALL(__NR_exit_group, sys_exit_group)
300#define __NR_waitid 95
301__SC_COMP(__NR_waitid, sys_waitid, compat_sys_waitid)
302
303/* kernel/fork.c */
304#define __NR_set_tid_address 96
305__SYSCALL(__NR_set_tid_address, sys_set_tid_address)
306#define __NR_unshare 97
307__SYSCALL(__NR_unshare, sys_unshare)
308
309/* kernel/futex.c */
310#define __NR_futex 98
311__SC_COMP(__NR_futex, sys_futex, compat_sys_futex)
312#define __NR_set_robust_list 99
313__SC_COMP(__NR_set_robust_list, sys_set_robust_list, \
314 compat_sys_set_robust_list)
315#define __NR_get_robust_list 100
316__SC_COMP(__NR_get_robust_list, sys_get_robust_list, \
317 compat_sys_get_robust_list)
318
319/* kernel/hrtimer.c */
320#define __NR_nanosleep 101
321__SC_COMP(__NR_nanosleep, sys_nanosleep, compat_sys_nanosleep)
322
323/* kernel/itimer.c */
324#define __NR_getitimer 102
325__SC_COMP(__NR_getitimer, sys_getitimer, compat_sys_getitimer)
326#define __NR_setitimer 103
327__SC_COMP(__NR_setitimer, sys_setitimer, compat_sys_setitimer)
328
329/* kernel/kexec.c */
330#define __NR_kexec_load 104
331__SC_COMP(__NR_kexec_load, sys_kexec_load, compat_sys_kexec_load)
332
333/* kernel/module.c */
334#define __NR_init_module 105
335__SYSCALL(__NR_init_module, sys_init_module)
336#define __NR_delete_module 106
337__SYSCALL(__NR_delete_module, sys_delete_module)
338
339/* kernel/posix-timers.c */
340#define __NR_timer_create 107
341__SC_COMP(__NR_timer_create, sys_timer_create, compat_sys_timer_create)
342#define __NR_timer_gettime 108
343__SC_COMP(__NR_timer_gettime, sys_timer_gettime, compat_sys_timer_gettime)
344#define __NR_timer_getoverrun 109
345__SYSCALL(__NR_timer_getoverrun, sys_timer_getoverrun)
346#define __NR_timer_settime 110
347__SC_COMP(__NR_timer_settime, sys_timer_settime, compat_sys_timer_settime)
348#define __NR_timer_delete 111
349__SYSCALL(__NR_timer_delete, sys_timer_delete)
350#define __NR_clock_settime 112
351__SC_COMP(__NR_clock_settime, sys_clock_settime, compat_sys_clock_settime)
352#define __NR_clock_gettime 113
353__SC_COMP(__NR_clock_gettime, sys_clock_gettime, compat_sys_clock_gettime)
354#define __NR_clock_getres 114
355__SC_COMP(__NR_clock_getres, sys_clock_getres, compat_sys_clock_getres)
356#define __NR_clock_nanosleep 115
357__SC_COMP(__NR_clock_nanosleep, sys_clock_nanosleep, \
358 compat_sys_clock_nanosleep)
359
360/* kernel/printk.c */
361#define __NR_syslog 116
362__SYSCALL(__NR_syslog, sys_syslog)
363
364/* kernel/ptrace.c */
365#define __NR_ptrace 117
366__SYSCALL(__NR_ptrace, sys_ptrace)
367
368/* kernel/sched/core.c */
369#define __NR_sched_setparam 118
370__SYSCALL(__NR_sched_setparam, sys_sched_setparam)
371#define __NR_sched_setscheduler 119
372__SYSCALL(__NR_sched_setscheduler, sys_sched_setscheduler)
373#define __NR_sched_getscheduler 120
374__SYSCALL(__NR_sched_getscheduler, sys_sched_getscheduler)
375#define __NR_sched_getparam 121
376__SYSCALL(__NR_sched_getparam, sys_sched_getparam)
377#define __NR_sched_setaffinity 122
378__SC_COMP(__NR_sched_setaffinity, sys_sched_setaffinity, \
379 compat_sys_sched_setaffinity)
380#define __NR_sched_getaffinity 123
381__SC_COMP(__NR_sched_getaffinity, sys_sched_getaffinity, \
382 compat_sys_sched_getaffinity)
383#define __NR_sched_yield 124
384__SYSCALL(__NR_sched_yield, sys_sched_yield)
385#define __NR_sched_get_priority_max 125
386__SYSCALL(__NR_sched_get_priority_max, sys_sched_get_priority_max)
387#define __NR_sched_get_priority_min 126
388__SYSCALL(__NR_sched_get_priority_min, sys_sched_get_priority_min)
389#define __NR_sched_rr_get_interval 127
390__SC_COMP(__NR_sched_rr_get_interval, sys_sched_rr_get_interval, \
391 compat_sys_sched_rr_get_interval)
392
393/* kernel/signal.c */
394#define __NR_restart_syscall 128
395__SYSCALL(__NR_restart_syscall, sys_restart_syscall)
396#define __NR_kill 129
397__SYSCALL(__NR_kill, sys_kill)
398#define __NR_tkill 130
399__SYSCALL(__NR_tkill, sys_tkill)
400#define __NR_tgkill 131
401__SYSCALL(__NR_tgkill, sys_tgkill)
402#define __NR_sigaltstack 132
403__SC_COMP(__NR_sigaltstack, sys_sigaltstack, compat_sys_sigaltstack)
404#define __NR_rt_sigsuspend 133
405__SC_COMP(__NR_rt_sigsuspend, sys_rt_sigsuspend, compat_sys_rt_sigsuspend)
406#define __NR_rt_sigaction 134
407__SC_COMP(__NR_rt_sigaction, sys_rt_sigaction, compat_sys_rt_sigaction)
408#define __NR_rt_sigprocmask 135
409__SC_COMP(__NR_rt_sigprocmask, sys_rt_sigprocmask, compat_sys_rt_sigprocmask)
410#define __NR_rt_sigpending 136
411__SC_COMP(__NR_rt_sigpending, sys_rt_sigpending, compat_sys_rt_sigpending)
412#define __NR_rt_sigtimedwait 137
413__SC_COMP(__NR_rt_sigtimedwait, sys_rt_sigtimedwait, \
414 compat_sys_rt_sigtimedwait)
415#define __NR_rt_sigqueueinfo 138
416__SC_COMP(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo, \
417 compat_sys_rt_sigqueueinfo)
418#define __NR_rt_sigreturn 139
419__SC_COMP(__NR_rt_sigreturn, sys_rt_sigreturn, compat_sys_rt_sigreturn)
420
421/* kernel/sys.c */
422#define __NR_setpriority 140
423__SYSCALL(__NR_setpriority, sys_setpriority)
424#define __NR_getpriority 141
425__SYSCALL(__NR_getpriority, sys_getpriority)
426#define __NR_reboot 142
427__SYSCALL(__NR_reboot, sys_reboot)
428#define __NR_setregid 143
429__SYSCALL(__NR_setregid, sys_setregid)
430#define __NR_setgid 144
431__SYSCALL(__NR_setgid, sys_setgid)
432#define __NR_setreuid 145
433__SYSCALL(__NR_setreuid, sys_setreuid)
434#define __NR_setuid 146
435__SYSCALL(__NR_setuid, sys_setuid)
436#define __NR_setresuid 147
437__SYSCALL(__NR_setresuid, sys_setresuid)
438#define __NR_getresuid 148
439__SYSCALL(__NR_getresuid, sys_getresuid)
440#define __NR_setresgid 149
441__SYSCALL(__NR_setresgid, sys_setresgid)
442#define __NR_getresgid 150
443__SYSCALL(__NR_getresgid, sys_getresgid)
444#define __NR_setfsuid 151
445__SYSCALL(__NR_setfsuid, sys_setfsuid)
446#define __NR_setfsgid 152
447__SYSCALL(__NR_setfsgid, sys_setfsgid)
448#define __NR_times 153
449__SC_COMP(__NR_times, sys_times, compat_sys_times)
450#define __NR_setpgid 154
451__SYSCALL(__NR_setpgid, sys_setpgid)
452#define __NR_getpgid 155
453__SYSCALL(__NR_getpgid, sys_getpgid)
454#define __NR_getsid 156
455__SYSCALL(__NR_getsid, sys_getsid)
456#define __NR_setsid 157
457__SYSCALL(__NR_setsid, sys_setsid)
458#define __NR_getgroups 158
459__SYSCALL(__NR_getgroups, sys_getgroups)
460#define __NR_setgroups 159
461__SYSCALL(__NR_setgroups, sys_setgroups)
462#define __NR_uname 160
463__SYSCALL(__NR_uname, sys_newuname)
464#define __NR_sethostname 161
465__SYSCALL(__NR_sethostname, sys_sethostname)
466#define __NR_setdomainname 162
467__SYSCALL(__NR_setdomainname, sys_setdomainname)
468#define __NR_getrlimit 163
469__SC_COMP(__NR_getrlimit, sys_getrlimit, compat_sys_getrlimit)
470#define __NR_setrlimit 164
471__SC_COMP(__NR_setrlimit, sys_setrlimit, compat_sys_setrlimit)
472#define __NR_getrusage 165
473__SC_COMP(__NR_getrusage, sys_getrusage, compat_sys_getrusage)
474#define __NR_umask 166
475__SYSCALL(__NR_umask, sys_umask)
476#define __NR_prctl 167
477__SYSCALL(__NR_prctl, sys_prctl)
478#define __NR_getcpu 168
479__SYSCALL(__NR_getcpu, sys_getcpu)
480
481/* kernel/time.c */
482#define __NR_gettimeofday 169
483__SC_COMP(__NR_gettimeofday, sys_gettimeofday, compat_sys_gettimeofday)
484#define __NR_settimeofday 170
485__SC_COMP(__NR_settimeofday, sys_settimeofday, compat_sys_settimeofday)
486#define __NR_adjtimex 171
487__SC_COMP(__NR_adjtimex, sys_adjtimex, compat_sys_adjtimex)
488
489/* kernel/timer.c */
490#define __NR_getpid 172
491__SYSCALL(__NR_getpid, sys_getpid)
492#define __NR_getppid 173
493__SYSCALL(__NR_getppid, sys_getppid)
494#define __NR_getuid 174
495__SYSCALL(__NR_getuid, sys_getuid)
496#define __NR_geteuid 175
497__SYSCALL(__NR_geteuid, sys_geteuid)
498#define __NR_getgid 176
499__SYSCALL(__NR_getgid, sys_getgid)
500#define __NR_getegid 177
501__SYSCALL(__NR_getegid, sys_getegid)
502#define __NR_gettid 178
503__SYSCALL(__NR_gettid, sys_gettid)
504#define __NR_sysinfo 179
505__SC_COMP(__NR_sysinfo, sys_sysinfo, compat_sys_sysinfo)
506
507/* ipc/mqueue.c */
508#define __NR_mq_open 180
509__SC_COMP(__NR_mq_open, sys_mq_open, compat_sys_mq_open)
510#define __NR_mq_unlink 181
511__SYSCALL(__NR_mq_unlink, sys_mq_unlink)
512#define __NR_mq_timedsend 182
513__SC_COMP(__NR_mq_timedsend, sys_mq_timedsend, compat_sys_mq_timedsend)
514#define __NR_mq_timedreceive 183
515__SC_COMP(__NR_mq_timedreceive, sys_mq_timedreceive, \
516 compat_sys_mq_timedreceive)
517#define __NR_mq_notify 184
518__SC_COMP(__NR_mq_notify, sys_mq_notify, compat_sys_mq_notify)
519#define __NR_mq_getsetattr 185
520__SC_COMP(__NR_mq_getsetattr, sys_mq_getsetattr, compat_sys_mq_getsetattr)
521
522/* ipc/msg.c */
523#define __NR_msgget 186
524__SYSCALL(__NR_msgget, sys_msgget)
525#define __NR_msgctl 187
526__SC_COMP(__NR_msgctl, sys_msgctl, compat_sys_msgctl)
527#define __NR_msgrcv 188
528__SC_COMP(__NR_msgrcv, sys_msgrcv, compat_sys_msgrcv)
529#define __NR_msgsnd 189
530__SC_COMP(__NR_msgsnd, sys_msgsnd, compat_sys_msgsnd)
531
532/* ipc/sem.c */
533#define __NR_semget 190
534__SYSCALL(__NR_semget, sys_semget)
535#define __NR_semctl 191
536__SC_COMP(__NR_semctl, sys_semctl, compat_sys_semctl)
537#define __NR_semtimedop 192
538__SC_COMP(__NR_semtimedop, sys_semtimedop, compat_sys_semtimedop)
539#define __NR_semop 193
540__SYSCALL(__NR_semop, sys_semop)
541
542/* ipc/shm.c */
543#define __NR_shmget 194
544__SYSCALL(__NR_shmget, sys_shmget)
545#define __NR_shmctl 195
546__SC_COMP(__NR_shmctl, sys_shmctl, compat_sys_shmctl)
547#define __NR_shmat 196
548__SC_COMP(__NR_shmat, sys_shmat, compat_sys_shmat)
549#define __NR_shmdt 197
550__SYSCALL(__NR_shmdt, sys_shmdt)
551
552/* net/socket.c */
553#define __NR_socket 198
554__SYSCALL(__NR_socket, sys_socket)
555#define __NR_socketpair 199
556__SYSCALL(__NR_socketpair, sys_socketpair)
557#define __NR_bind 200
558__SYSCALL(__NR_bind, sys_bind)
559#define __NR_listen 201
560__SYSCALL(__NR_listen, sys_listen)
561#define __NR_accept 202
562__SYSCALL(__NR_accept, sys_accept)
563#define __NR_connect 203
564__SYSCALL(__NR_connect, sys_connect)
565#define __NR_getsockname 204
566__SYSCALL(__NR_getsockname, sys_getsockname)
567#define __NR_getpeername 205
568__SYSCALL(__NR_getpeername, sys_getpeername)
569#define __NR_sendto 206
570__SYSCALL(__NR_sendto, sys_sendto)
571#define __NR_recvfrom 207
572__SC_COMP(__NR_recvfrom, sys_recvfrom, compat_sys_recvfrom)
573#define __NR_setsockopt 208
574__SC_COMP(__NR_setsockopt, sys_setsockopt, compat_sys_setsockopt)
575#define __NR_getsockopt 209
576__SC_COMP(__NR_getsockopt, sys_getsockopt, compat_sys_getsockopt)
577#define __NR_shutdown 210
578__SYSCALL(__NR_shutdown, sys_shutdown)
579#define __NR_sendmsg 211
580__SC_COMP(__NR_sendmsg, sys_sendmsg, compat_sys_sendmsg)
581#define __NR_recvmsg 212
582__SC_COMP(__NR_recvmsg, sys_recvmsg, compat_sys_recvmsg)
583
584/* mm/filemap.c */
585#define __NR_readahead 213
586__SC_COMP(__NR_readahead, sys_readahead, compat_sys_readahead)
587
588/* mm/nommu.c, also with MMU */
589#define __NR_brk 214
590__SYSCALL(__NR_brk, sys_brk)
591#define __NR_munmap 215
592__SYSCALL(__NR_munmap, sys_munmap)
593#define __NR_mremap 216
594__SYSCALL(__NR_mremap, sys_mremap)
595
596/* security/keys/keyctl.c */
597#define __NR_add_key 217
598__SYSCALL(__NR_add_key, sys_add_key)
599#define __NR_request_key 218
600__SYSCALL(__NR_request_key, sys_request_key)
601#define __NR_keyctl 219
602__SC_COMP(__NR_keyctl, sys_keyctl, compat_sys_keyctl)
603
604/* arch/example/kernel/sys_example.c */
605#define __NR_clone 220
606__SYSCALL(__NR_clone, sys_clone)
607#define __NR_execve 221
608__SC_COMP(__NR_execve, sys_execve, compat_sys_execve)
609
610#define __NR3264_mmap 222
611__SC_3264(__NR3264_mmap, sys_mmap2, sys_mmap)
612/* mm/fadvise.c */
613#define __NR3264_fadvise64 223
614__SC_COMP(__NR3264_fadvise64, sys_fadvise64_64, compat_sys_fadvise64_64)
615
616/* mm/, CONFIG_MMU only */
617#ifndef __ARCH_NOMMU
618#define __NR_swapon 224
619__SYSCALL(__NR_swapon, sys_swapon)
620#define __NR_swapoff 225
621__SYSCALL(__NR_swapoff, sys_swapoff)
622#define __NR_mprotect 226
623__SYSCALL(__NR_mprotect, sys_mprotect)
624#define __NR_msync 227
625__SYSCALL(__NR_msync, sys_msync)
626#define __NR_mlock 228
627__SYSCALL(__NR_mlock, sys_mlock)
628#define __NR_munlock 229
629__SYSCALL(__NR_munlock, sys_munlock)
630#define __NR_mlockall 230
631__SYSCALL(__NR_mlockall, sys_mlockall)
632#define __NR_munlockall 231
633__SYSCALL(__NR_munlockall, sys_munlockall)
634#define __NR_mincore 232
635__SYSCALL(__NR_mincore, sys_mincore)
636#define __NR_madvise 233
637__SYSCALL(__NR_madvise, sys_madvise)
638#define __NR_remap_file_pages 234
639__SYSCALL(__NR_remap_file_pages, sys_remap_file_pages)
640#define __NR_mbind 235
641__SC_COMP(__NR_mbind, sys_mbind, compat_sys_mbind)
642#define __NR_get_mempolicy 236
643__SC_COMP(__NR_get_mempolicy, sys_get_mempolicy, compat_sys_get_mempolicy)
644#define __NR_set_mempolicy 237
645__SC_COMP(__NR_set_mempolicy, sys_set_mempolicy, compat_sys_set_mempolicy)
646#define __NR_migrate_pages 238
647__SC_COMP(__NR_migrate_pages, sys_migrate_pages, compat_sys_migrate_pages)
648#define __NR_move_pages 239
649__SC_COMP(__NR_move_pages, sys_move_pages, compat_sys_move_pages)
650#endif
651
652#define __NR_rt_tgsigqueueinfo 240
653__SC_COMP(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo, \
654 compat_sys_rt_tgsigqueueinfo)
655#define __NR_perf_event_open 241
656__SYSCALL(__NR_perf_event_open, sys_perf_event_open)
657#define __NR_accept4 242
658__SYSCALL(__NR_accept4, sys_accept4)
659#define __NR_recvmmsg 243
660__SC_COMP(__NR_recvmmsg, sys_recvmmsg, compat_sys_recvmmsg)
661
662/*
663 * Architectures may provide up to 16 syscalls of their own
664 * starting with this value.
665 */
666#define __NR_arch_specific_syscall 244
667
668#define __NR_wait4 260
669__SC_COMP(__NR_wait4, sys_wait4, compat_sys_wait4)
670#define __NR_prlimit64 261
671__SYSCALL(__NR_prlimit64, sys_prlimit64)
672#define __NR_fanotify_init 262
673__SYSCALL(__NR_fanotify_init, sys_fanotify_init)
674#define __NR_fanotify_mark 263
675__SYSCALL(__NR_fanotify_mark, sys_fanotify_mark)
676#define __NR_name_to_handle_at 264
677__SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at)
678#define __NR_open_by_handle_at 265
679__SC_COMP(__NR_open_by_handle_at, sys_open_by_handle_at, \
680 compat_sys_open_by_handle_at)
681#define __NR_clock_adjtime 266
682__SC_COMP(__NR_clock_adjtime, sys_clock_adjtime, compat_sys_clock_adjtime)
683#define __NR_syncfs 267
684__SYSCALL(__NR_syncfs, sys_syncfs)
685#define __NR_setns 268
686__SYSCALL(__NR_setns, sys_setns)
687#define __NR_sendmmsg 269
688__SC_COMP(__NR_sendmmsg, sys_sendmmsg, compat_sys_sendmmsg)
689#define __NR_process_vm_readv 270
690__SC_COMP(__NR_process_vm_readv, sys_process_vm_readv, \
691 compat_sys_process_vm_readv)
692#define __NR_process_vm_writev 271
693__SC_COMP(__NR_process_vm_writev, sys_process_vm_writev, \
694 compat_sys_process_vm_writev)
695#define __NR_kcmp 272
696__SYSCALL(__NR_kcmp, sys_kcmp)
697#define __NR_finit_module 273
698__SYSCALL(__NR_finit_module, sys_finit_module)
699#define __NR_sched_setattr 274
700__SYSCALL(__NR_sched_setattr, sys_sched_setattr)
701#define __NR_sched_getattr 275
702__SYSCALL(__NR_sched_getattr, sys_sched_getattr)
703#define __NR_renameat2 276
704__SYSCALL(__NR_renameat2, sys_renameat2)
705#define __NR_seccomp 277
706__SYSCALL(__NR_seccomp, sys_seccomp)
707#define __NR_getrandom 278
708__SYSCALL(__NR_getrandom, sys_getrandom)
709#define __NR_memfd_create 279
710__SYSCALL(__NR_memfd_create, sys_memfd_create)
711#define __NR_bpf 280
712__SYSCALL(__NR_bpf, sys_bpf)
713#define __NR_execveat 281
714__SC_COMP(__NR_execveat, sys_execveat, compat_sys_execveat)
715#define __NR_userfaultfd 282
716__SYSCALL(__NR_userfaultfd, sys_userfaultfd)
717#define __NR_membarrier 283
718__SYSCALL(__NR_membarrier, sys_membarrier)
719#define __NR_mlock2 284
720__SYSCALL(__NR_mlock2, sys_mlock2)
721#define __NR_copy_file_range 285
722__SYSCALL(__NR_copy_file_range, sys_copy_file_range)
723#define __NR_preadv2 286
724__SC_COMP(__NR_preadv2, sys_preadv2, compat_sys_preadv2)
725#define __NR_pwritev2 287
726__SC_COMP(__NR_pwritev2, sys_pwritev2, compat_sys_pwritev2)
727#define __NR_pkey_mprotect 288
728__SYSCALL(__NR_pkey_mprotect, sys_pkey_mprotect)
729#define __NR_pkey_alloc 289
730__SYSCALL(__NR_pkey_alloc, sys_pkey_alloc)
731#define __NR_pkey_free 290
732__SYSCALL(__NR_pkey_free, sys_pkey_free)
733#define __NR_statx 291
734__SYSCALL(__NR_statx, sys_statx)
735#define __NR_io_pgetevents 292
736__SC_COMP(__NR_io_pgetevents, sys_io_pgetevents, compat_sys_io_pgetevents)
737
738#undef __NR_syscalls
739#define __NR_syscalls 293
740
741/*
742 * 32 bit systems traditionally used different
743 * syscalls for off_t and loff_t arguments, while
744 * 64 bit systems only need the off_t version.
745 * For new 32 bit platforms, there is no need to
746 * implement the old 32 bit off_t syscalls, so
747 * they take different names.
748 * Here we map the numbers so that both versions
749 * use the same syscall table layout.
750 */
751#if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)
752#define __NR_fcntl __NR3264_fcntl
753#define __NR_statfs __NR3264_statfs
754#define __NR_fstatfs __NR3264_fstatfs
755#define __NR_truncate __NR3264_truncate
756#define __NR_ftruncate __NR3264_ftruncate
757#define __NR_lseek __NR3264_lseek
758#define __NR_sendfile __NR3264_sendfile
759#define __NR_newfstatat __NR3264_fstatat
760#define __NR_fstat __NR3264_fstat
761#define __NR_mmap __NR3264_mmap
762#define __NR_fadvise64 __NR3264_fadvise64
763#ifdef __NR3264_stat
764#define __NR_stat __NR3264_stat
765#define __NR_lstat __NR3264_lstat
766#endif
767#else
768#define __NR_fcntl64 __NR3264_fcntl
769#define __NR_statfs64 __NR3264_statfs
770#define __NR_fstatfs64 __NR3264_fstatfs
771#define __NR_truncate64 __NR3264_truncate
772#define __NR_ftruncate64 __NR3264_ftruncate
773#define __NR_llseek __NR3264_lseek
774#define __NR_sendfile64 __NR3264_sendfile
775#define __NR_fstatat64 __NR3264_fstatat
776#define __NR_fstat64 __NR3264_fstat
777#define __NR_mmap2 __NR3264_mmap
778#define __NR_fadvise64_64 __NR3264_fadvise64
779#ifdef __NR3264_stat
780#define __NR_stat64 __NR3264_stat
781#define __NR_lstat64 __NR3264_lstat
782#endif
783#endif
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index b7db3261c62d..66917a4eba27 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -75,6 +75,11 @@ struct bpf_lpm_trie_key {
75 __u8 data[0]; /* Arbitrary size */ 75 __u8 data[0]; /* Arbitrary size */
76}; 76};
77 77
78struct bpf_cgroup_storage_key {
79 __u64 cgroup_inode_id; /* cgroup inode id */
80 __u32 attach_type; /* program attach type */
81};
82
78/* BPF syscall commands, see bpf(2) man-page for details. */ 83/* BPF syscall commands, see bpf(2) man-page for details. */
79enum bpf_cmd { 84enum bpf_cmd {
80 BPF_MAP_CREATE, 85 BPF_MAP_CREATE,
@@ -120,6 +125,8 @@ enum bpf_map_type {
120 BPF_MAP_TYPE_CPUMAP, 125 BPF_MAP_TYPE_CPUMAP,
121 BPF_MAP_TYPE_XSKMAP, 126 BPF_MAP_TYPE_XSKMAP,
122 BPF_MAP_TYPE_SOCKHASH, 127 BPF_MAP_TYPE_SOCKHASH,
128 BPF_MAP_TYPE_CGROUP_STORAGE,
129 BPF_MAP_TYPE_REUSEPORT_SOCKARRAY,
123}; 130};
124 131
125enum bpf_prog_type { 132enum bpf_prog_type {
@@ -144,6 +151,7 @@ enum bpf_prog_type {
144 BPF_PROG_TYPE_CGROUP_SOCK_ADDR, 151 BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
145 BPF_PROG_TYPE_LWT_SEG6LOCAL, 152 BPF_PROG_TYPE_LWT_SEG6LOCAL,
146 BPF_PROG_TYPE_LIRC_MODE2, 153 BPF_PROG_TYPE_LIRC_MODE2,
154 BPF_PROG_TYPE_SK_REUSEPORT,
147}; 155};
148 156
149enum bpf_attach_type { 157enum bpf_attach_type {
@@ -1371,6 +1379,20 @@ union bpf_attr {
1371 * A 8-byte long non-decreasing number on success, or 0 if the 1379 * A 8-byte long non-decreasing number on success, or 0 if the
1372 * socket field is missing inside *skb*. 1380 * socket field is missing inside *skb*.
1373 * 1381 *
1382 * u64 bpf_get_socket_cookie(struct bpf_sock_addr *ctx)
1383 * Description
1384 * Equivalent to bpf_get_socket_cookie() helper that accepts
1385 * *skb*, but gets socket from **struct bpf_sock_addr** contex.
1386 * Return
1387 * A 8-byte long non-decreasing number.
1388 *
1389 * u64 bpf_get_socket_cookie(struct bpf_sock_ops *ctx)
1390 * Description
1391 * Equivalent to bpf_get_socket_cookie() helper that accepts
1392 * *skb*, but gets socket from **struct bpf_sock_ops** contex.
1393 * Return
1394 * A 8-byte long non-decreasing number.
1395 *
1374 * u32 bpf_get_socket_uid(struct sk_buff *skb) 1396 * u32 bpf_get_socket_uid(struct sk_buff *skb)
1375 * Return 1397 * Return
1376 * The owner UID of the socket associated to *skb*. If the socket 1398 * The owner UID of the socket associated to *skb*. If the socket
@@ -1826,7 +1848,7 @@ union bpf_attr {
1826 * A non-negative value equal to or less than *size* on success, 1848 * A non-negative value equal to or less than *size* on success,
1827 * or a negative error in case of failure. 1849 * or a negative error in case of failure.
1828 * 1850 *
1829 * int skb_load_bytes_relative(const struct sk_buff *skb, u32 offset, void *to, u32 len, u32 start_header) 1851 * int bpf_skb_load_bytes_relative(const struct sk_buff *skb, u32 offset, void *to, u32 len, u32 start_header)
1830 * Description 1852 * Description
1831 * This helper is similar to **bpf_skb_load_bytes**\ () in that 1853 * This helper is similar to **bpf_skb_load_bytes**\ () in that
1832 * it provides an easy way to load *len* bytes from *offset* 1854 * it provides an easy way to load *len* bytes from *offset*
@@ -1877,7 +1899,7 @@ union bpf_attr {
1877 * * < 0 if any input argument is invalid 1899 * * < 0 if any input argument is invalid
1878 * * 0 on success (packet is forwarded, nexthop neighbor exists) 1900 * * 0 on success (packet is forwarded, nexthop neighbor exists)
1879 * * > 0 one of **BPF_FIB_LKUP_RET_** codes explaining why the 1901 * * > 0 one of **BPF_FIB_LKUP_RET_** codes explaining why the
1880 * * packet is not forwarded or needs assist from full stack 1902 * packet is not forwarded or needs assist from full stack
1881 * 1903 *
1882 * int bpf_sock_hash_update(struct bpf_sock_ops_kern *skops, struct bpf_map *map, void *key, u64 flags) 1904 * int bpf_sock_hash_update(struct bpf_sock_ops_kern *skops, struct bpf_map *map, void *key, u64 flags)
1883 * Description 1905 * Description
@@ -2033,7 +2055,6 @@ union bpf_attr {
2033 * This helper is only available is the kernel was compiled with 2055 * This helper is only available is the kernel was compiled with
2034 * the **CONFIG_BPF_LIRC_MODE2** configuration option set to 2056 * the **CONFIG_BPF_LIRC_MODE2** configuration option set to
2035 * "**y**". 2057 * "**y**".
2036 *
2037 * Return 2058 * Return
2038 * 0 2059 * 0
2039 * 2060 *
@@ -2053,7 +2074,6 @@ union bpf_attr {
2053 * This helper is only available is the kernel was compiled with 2074 * This helper is only available is the kernel was compiled with
2054 * the **CONFIG_BPF_LIRC_MODE2** configuration option set to 2075 * the **CONFIG_BPF_LIRC_MODE2** configuration option set to
2055 * "**y**". 2076 * "**y**".
2056 *
2057 * Return 2077 * Return
2058 * 0 2078 * 0
2059 * 2079 *
@@ -2073,10 +2093,54 @@ union bpf_attr {
2073 * Return 2093 * Return
2074 * The id is returned or 0 in case the id could not be retrieved. 2094 * The id is returned or 0 in case the id could not be retrieved.
2075 * 2095 *
2096 * u64 bpf_skb_ancestor_cgroup_id(struct sk_buff *skb, int ancestor_level)
2097 * Description
2098 * Return id of cgroup v2 that is ancestor of cgroup associated
2099 * with the *skb* at the *ancestor_level*. The root cgroup is at
2100 * *ancestor_level* zero and each step down the hierarchy
2101 * increments the level. If *ancestor_level* == level of cgroup
2102 * associated with *skb*, then return value will be same as that
2103 * of **bpf_skb_cgroup_id**\ ().
2104 *
2105 * The helper is useful to implement policies based on cgroups
2106 * that are upper in hierarchy than immediate cgroup associated
2107 * with *skb*.
2108 *
2109 * The format of returned id and helper limitations are same as in
2110 * **bpf_skb_cgroup_id**\ ().
2111 * Return
2112 * The id is returned or 0 in case the id could not be retrieved.
2113 *
2076 * u64 bpf_get_current_cgroup_id(void) 2114 * u64 bpf_get_current_cgroup_id(void)
2077 * Return 2115 * Return
2078 * A 64-bit integer containing the current cgroup id based 2116 * A 64-bit integer containing the current cgroup id based
2079 * on the cgroup within which the current task is running. 2117 * on the cgroup within which the current task is running.
2118 *
2119 * void* get_local_storage(void *map, u64 flags)
2120 * Description
2121 * Get the pointer to the local storage area.
2122 * The type and the size of the local storage is defined
2123 * by the *map* argument.
2124 * The *flags* meaning is specific for each map type,
2125 * and has to be 0 for cgroup local storage.
2126 *
2127 * Depending on the bpf program type, a local storage area
2128 * can be shared between multiple instances of the bpf program,
2129 * running simultaneously.
2130 *
2131 * A user should care about the synchronization by himself.
2132 * For example, by using the BPF_STX_XADD instruction to alter
2133 * the shared data.
2134 * Return
2135 * Pointer to the local storage area.
2136 *
2137 * int bpf_sk_select_reuseport(struct sk_reuseport_md *reuse, struct bpf_map *map, void *key, u64 flags)
2138 * Description
2139 * Select a SO_REUSEPORT sk from a BPF_MAP_TYPE_REUSEPORT_ARRAY map
2140 * It checks the selected sk is matching the incoming
2141 * request in the skb.
2142 * Return
2143 * 0 on success, or a negative error in case of failure.
2080 */ 2144 */
2081#define __BPF_FUNC_MAPPER(FN) \ 2145#define __BPF_FUNC_MAPPER(FN) \
2082 FN(unspec), \ 2146 FN(unspec), \
@@ -2159,7 +2223,10 @@ union bpf_attr {
2159 FN(rc_repeat), \ 2223 FN(rc_repeat), \
2160 FN(rc_keydown), \ 2224 FN(rc_keydown), \
2161 FN(skb_cgroup_id), \ 2225 FN(skb_cgroup_id), \
2162 FN(get_current_cgroup_id), 2226 FN(get_current_cgroup_id), \
2227 FN(get_local_storage), \
2228 FN(sk_select_reuseport), \
2229 FN(skb_ancestor_cgroup_id),
2163 2230
2164/* integer value in 'imm' field of BPF_CALL instruction selects which helper 2231/* integer value in 'imm' field of BPF_CALL instruction selects which helper
2165 * function eBPF program intends to call 2232 * function eBPF program intends to call
@@ -2376,6 +2443,30 @@ struct sk_msg_md {
2376 __u32 local_port; /* stored in host byte order */ 2443 __u32 local_port; /* stored in host byte order */
2377}; 2444};
2378 2445
2446struct sk_reuseport_md {
2447 /*
2448 * Start of directly accessible data. It begins from
2449 * the tcp/udp header.
2450 */
2451 void *data;
2452 void *data_end; /* End of directly accessible data */
2453 /*
2454 * Total length of packet (starting from the tcp/udp header).
2455 * Note that the directly accessible bytes (data_end - data)
2456 * could be less than this "len". Those bytes could be
2457 * indirectly read by a helper "bpf_skb_load_bytes()".
2458 */
2459 __u32 len;
2460 /*
2461 * Eth protocol in the mac header (network byte order). e.g.
2462 * ETH_P_IP(0x0800) and ETH_P_IPV6(0x86DD)
2463 */
2464 __u32 eth_protocol;
2465 __u32 ip_protocol; /* IP protocol. e.g. IPPROTO_TCP, IPPROTO_UDP */
2466 __u32 bind_inany; /* Is sock bound to an INANY address? */
2467 __u32 hash; /* A hash of the packet 4 tuples */
2468};
2469
2379#define BPF_TAG_SIZE 8 2470#define BPF_TAG_SIZE 8
2380 2471
2381struct bpf_prog_info { 2472struct bpf_prog_info {
@@ -2557,6 +2648,9 @@ enum {
2557 * Arg1: old_state 2648 * Arg1: old_state
2558 * Arg2: new_state 2649 * Arg2: new_state
2559 */ 2650 */
2651 BPF_SOCK_OPS_TCP_LISTEN_CB, /* Called on listen(2), right after
2652 * socket transition to LISTEN state.
2653 */
2560}; 2654};
2561 2655
2562/* List of TCP states. There is a build check in net/ipv4/tcp.c to detect 2656/* List of TCP states. There is a build check in net/ipv4/tcp.c to detect
diff --git a/tools/include/uapi/linux/in.h b/tools/include/uapi/linux/in.h
new file mode 100644
index 000000000000..48e8a225b985
--- /dev/null
+++ b/tools/include/uapi/linux/in.h
@@ -0,0 +1,301 @@
1/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
2/*
3 * INET An implementation of the TCP/IP protocol suite for the LINUX
4 * operating system. INET is implemented using the BSD Socket
5 * interface as the means of communication with the user level.
6 *
7 * Definitions of the Internet Protocol.
8 *
9 * Version: @(#)in.h 1.0.1 04/21/93
10 *
11 * Authors: Original taken from the GNU Project <netinet/in.h> file.
12 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version
17 * 2 of the License, or (at your option) any later version.
18 */
19#ifndef _UAPI_LINUX_IN_H
20#define _UAPI_LINUX_IN_H
21
22#include <linux/types.h>
23#include <linux/libc-compat.h>
24#include <linux/socket.h>
25
26#if __UAPI_DEF_IN_IPPROTO
27/* Standard well-defined IP protocols. */
28enum {
29 IPPROTO_IP = 0, /* Dummy protocol for TCP */
30#define IPPROTO_IP IPPROTO_IP
31 IPPROTO_ICMP = 1, /* Internet Control Message Protocol */
32#define IPPROTO_ICMP IPPROTO_ICMP
33 IPPROTO_IGMP = 2, /* Internet Group Management Protocol */
34#define IPPROTO_IGMP IPPROTO_IGMP
35 IPPROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */
36#define IPPROTO_IPIP IPPROTO_IPIP
37 IPPROTO_TCP = 6, /* Transmission Control Protocol */
38#define IPPROTO_TCP IPPROTO_TCP
39 IPPROTO_EGP = 8, /* Exterior Gateway Protocol */
40#define IPPROTO_EGP IPPROTO_EGP
41 IPPROTO_PUP = 12, /* PUP protocol */
42#define IPPROTO_PUP IPPROTO_PUP
43 IPPROTO_UDP = 17, /* User Datagram Protocol */
44#define IPPROTO_UDP IPPROTO_UDP
45 IPPROTO_IDP = 22, /* XNS IDP protocol */
46#define IPPROTO_IDP IPPROTO_IDP
47 IPPROTO_TP = 29, /* SO Transport Protocol Class 4 */
48#define IPPROTO_TP IPPROTO_TP
49 IPPROTO_DCCP = 33, /* Datagram Congestion Control Protocol */
50#define IPPROTO_DCCP IPPROTO_DCCP
51 IPPROTO_IPV6 = 41, /* IPv6-in-IPv4 tunnelling */
52#define IPPROTO_IPV6 IPPROTO_IPV6
53 IPPROTO_RSVP = 46, /* RSVP Protocol */
54#define IPPROTO_RSVP IPPROTO_RSVP
55 IPPROTO_GRE = 47, /* Cisco GRE tunnels (rfc 1701,1702) */
56#define IPPROTO_GRE IPPROTO_GRE
57 IPPROTO_ESP = 50, /* Encapsulation Security Payload protocol */
58#define IPPROTO_ESP IPPROTO_ESP
59 IPPROTO_AH = 51, /* Authentication Header protocol */
60#define IPPROTO_AH IPPROTO_AH
61 IPPROTO_MTP = 92, /* Multicast Transport Protocol */
62#define IPPROTO_MTP IPPROTO_MTP
63 IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */
64#define IPPROTO_BEETPH IPPROTO_BEETPH
65 IPPROTO_ENCAP = 98, /* Encapsulation Header */
66#define IPPROTO_ENCAP IPPROTO_ENCAP
67 IPPROTO_PIM = 103, /* Protocol Independent Multicast */
68#define IPPROTO_PIM IPPROTO_PIM
69 IPPROTO_COMP = 108, /* Compression Header Protocol */
70#define IPPROTO_COMP IPPROTO_COMP
71 IPPROTO_SCTP = 132, /* Stream Control Transport Protocol */
72#define IPPROTO_SCTP IPPROTO_SCTP
73 IPPROTO_UDPLITE = 136, /* UDP-Lite (RFC 3828) */
74#define IPPROTO_UDPLITE IPPROTO_UDPLITE
75 IPPROTO_MPLS = 137, /* MPLS in IP (RFC 4023) */
76#define IPPROTO_MPLS IPPROTO_MPLS
77 IPPROTO_RAW = 255, /* Raw IP packets */
78#define IPPROTO_RAW IPPROTO_RAW
79 IPPROTO_MAX
80};
81#endif
82
83#if __UAPI_DEF_IN_ADDR
84/* Internet address. */
85struct in_addr {
86 __be32 s_addr;
87};
88#endif
89
90#define IP_TOS 1
91#define IP_TTL 2
92#define IP_HDRINCL 3
93#define IP_OPTIONS 4
94#define IP_ROUTER_ALERT 5
95#define IP_RECVOPTS 6
96#define IP_RETOPTS 7
97#define IP_PKTINFO 8
98#define IP_PKTOPTIONS 9
99#define IP_MTU_DISCOVER 10
100#define IP_RECVERR 11
101#define IP_RECVTTL 12
102#define IP_RECVTOS 13
103#define IP_MTU 14
104#define IP_FREEBIND 15
105#define IP_IPSEC_POLICY 16
106#define IP_XFRM_POLICY 17
107#define IP_PASSSEC 18
108#define IP_TRANSPARENT 19
109
110/* BSD compatibility */
111#define IP_RECVRETOPTS IP_RETOPTS
112
113/* TProxy original addresses */
114#define IP_ORIGDSTADDR 20
115#define IP_RECVORIGDSTADDR IP_ORIGDSTADDR
116
117#define IP_MINTTL 21
118#define IP_NODEFRAG 22
119#define IP_CHECKSUM 23
120#define IP_BIND_ADDRESS_NO_PORT 24
121#define IP_RECVFRAGSIZE 25
122
123/* IP_MTU_DISCOVER values */
124#define IP_PMTUDISC_DONT 0 /* Never send DF frames */
125#define IP_PMTUDISC_WANT 1 /* Use per route hints */
126#define IP_PMTUDISC_DO 2 /* Always DF */
127#define IP_PMTUDISC_PROBE 3 /* Ignore dst pmtu */
128/* Always use interface mtu (ignores dst pmtu) but don't set DF flag.
129 * Also incoming ICMP frag_needed notifications will be ignored on
130 * this socket to prevent accepting spoofed ones.
131 */
132#define IP_PMTUDISC_INTERFACE 4
133/* weaker version of IP_PMTUDISC_INTERFACE, which allos packets to get
134 * fragmented if they exeed the interface mtu
135 */
136#define IP_PMTUDISC_OMIT 5
137
138#define IP_MULTICAST_IF 32
139#define IP_MULTICAST_TTL 33
140#define IP_MULTICAST_LOOP 34
141#define IP_ADD_MEMBERSHIP 35
142#define IP_DROP_MEMBERSHIP 36
143#define IP_UNBLOCK_SOURCE 37
144#define IP_BLOCK_SOURCE 38
145#define IP_ADD_SOURCE_MEMBERSHIP 39
146#define IP_DROP_SOURCE_MEMBERSHIP 40
147#define IP_MSFILTER 41
148#define MCAST_JOIN_GROUP 42
149#define MCAST_BLOCK_SOURCE 43
150#define MCAST_UNBLOCK_SOURCE 44
151#define MCAST_LEAVE_GROUP 45
152#define MCAST_JOIN_SOURCE_GROUP 46
153#define MCAST_LEAVE_SOURCE_GROUP 47
154#define MCAST_MSFILTER 48
155#define IP_MULTICAST_ALL 49
156#define IP_UNICAST_IF 50
157
158#define MCAST_EXCLUDE 0
159#define MCAST_INCLUDE 1
160
161/* These need to appear somewhere around here */
162#define IP_DEFAULT_MULTICAST_TTL 1
163#define IP_DEFAULT_MULTICAST_LOOP 1
164
165/* Request struct for multicast socket ops */
166
167#if __UAPI_DEF_IP_MREQ
168struct ip_mreq {
169 struct in_addr imr_multiaddr; /* IP multicast address of group */
170 struct in_addr imr_interface; /* local IP address of interface */
171};
172
173struct ip_mreqn {
174 struct in_addr imr_multiaddr; /* IP multicast address of group */
175 struct in_addr imr_address; /* local IP address of interface */
176 int imr_ifindex; /* Interface index */
177};
178
179struct ip_mreq_source {
180 __be32 imr_multiaddr;
181 __be32 imr_interface;
182 __be32 imr_sourceaddr;
183};
184
185struct ip_msfilter {
186 __be32 imsf_multiaddr;
187 __be32 imsf_interface;
188 __u32 imsf_fmode;
189 __u32 imsf_numsrc;
190 __be32 imsf_slist[1];
191};
192
193#define IP_MSFILTER_SIZE(numsrc) \
194 (sizeof(struct ip_msfilter) - sizeof(__u32) \
195 + (numsrc) * sizeof(__u32))
196
197struct group_req {
198 __u32 gr_interface; /* interface index */
199 struct __kernel_sockaddr_storage gr_group; /* group address */
200};
201
202struct group_source_req {
203 __u32 gsr_interface; /* interface index */
204 struct __kernel_sockaddr_storage gsr_group; /* group address */
205 struct __kernel_sockaddr_storage gsr_source; /* source address */
206};
207
208struct group_filter {
209 __u32 gf_interface; /* interface index */
210 struct __kernel_sockaddr_storage gf_group; /* multicast address */
211 __u32 gf_fmode; /* filter mode */
212 __u32 gf_numsrc; /* number of sources */
213 struct __kernel_sockaddr_storage gf_slist[1]; /* interface index */
214};
215
216#define GROUP_FILTER_SIZE(numsrc) \
217 (sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) \
218 + (numsrc) * sizeof(struct __kernel_sockaddr_storage))
219#endif
220
221#if __UAPI_DEF_IN_PKTINFO
222struct in_pktinfo {
223 int ipi_ifindex;
224 struct in_addr ipi_spec_dst;
225 struct in_addr ipi_addr;
226};
227#endif
228
229/* Structure describing an Internet (IP) socket address. */
230#if __UAPI_DEF_SOCKADDR_IN
231#define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr) */
232struct sockaddr_in {
233 __kernel_sa_family_t sin_family; /* Address family */
234 __be16 sin_port; /* Port number */
235 struct in_addr sin_addr; /* Internet address */
236
237 /* Pad to size of `struct sockaddr'. */
238 unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) -
239 sizeof(unsigned short int) - sizeof(struct in_addr)];
240};
241#define sin_zero __pad /* for BSD UNIX comp. -FvK */
242#endif
243
244#if __UAPI_DEF_IN_CLASS
245/*
246 * Definitions of the bits in an Internet address integer.
247 * On subnets, host and network parts are found according
248 * to the subnet mask, not these masks.
249 */
250#define IN_CLASSA(a) ((((long int) (a)) & 0x80000000) == 0)
251#define IN_CLASSA_NET 0xff000000
252#define IN_CLASSA_NSHIFT 24
253#define IN_CLASSA_HOST (0xffffffff & ~IN_CLASSA_NET)
254#define IN_CLASSA_MAX 128
255
256#define IN_CLASSB(a) ((((long int) (a)) & 0xc0000000) == 0x80000000)
257#define IN_CLASSB_NET 0xffff0000
258#define IN_CLASSB_NSHIFT 16
259#define IN_CLASSB_HOST (0xffffffff & ~IN_CLASSB_NET)
260#define IN_CLASSB_MAX 65536
261
262#define IN_CLASSC(a) ((((long int) (a)) & 0xe0000000) == 0xc0000000)
263#define IN_CLASSC_NET 0xffffff00
264#define IN_CLASSC_NSHIFT 8
265#define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET)
266
267#define IN_CLASSD(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000)
268#define IN_MULTICAST(a) IN_CLASSD(a)
269#define IN_MULTICAST_NET 0xF0000000
270
271#define IN_EXPERIMENTAL(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000)
272#define IN_BADCLASS(a) IN_EXPERIMENTAL((a))
273
274/* Address to accept any incoming messages. */
275#define INADDR_ANY ((unsigned long int) 0x00000000)
276
277/* Address to send to all hosts. */
278#define INADDR_BROADCAST ((unsigned long int) 0xffffffff)
279
280/* Address indicating an error return. */
281#define INADDR_NONE ((unsigned long int) 0xffffffff)
282
283/* Network number for local host loopback. */
284#define IN_LOOPBACKNET 127
285
286/* Address to loopback in software to local host. */
287#define INADDR_LOOPBACK 0x7f000001 /* 127.0.0.1 */
288#define IN_LOOPBACK(a) ((((long int) (a)) & 0xff000000) == 0x7f000000)
289
290/* Defines for Multicast INADDR */
291#define INADDR_UNSPEC_GROUP 0xe0000000U /* 224.0.0.0 */
292#define INADDR_ALLHOSTS_GROUP 0xe0000001U /* 224.0.0.1 */
293#define INADDR_ALLRTRS_GROUP 0xe0000002U /* 224.0.0.2 */
294#define INADDR_MAX_LOCAL_GROUP 0xe00000ffU /* 224.0.0.255 */
295#endif
296
297/* <asm/byteorder.h> contains the htonl type stuff.. */
298#include <asm/byteorder.h>
299
300
301#endif /* _UAPI_LINUX_IN_H */
diff --git a/tools/lib/bpf/Build b/tools/lib/bpf/Build
index 6070e655042d..13a861135127 100644
--- a/tools/lib/bpf/Build
+++ b/tools/lib/bpf/Build
@@ -1 +1 @@
libbpf-y := libbpf.o bpf.o nlattr.o btf.o libbpf-y := libbpf.o bpf.o nlattr.o btf.o libbpf_errno.o
diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile
index 5390e7725e43..d49902e818b5 100644
--- a/tools/lib/bpf/Makefile
+++ b/tools/lib/bpf/Makefile
@@ -66,7 +66,7 @@ ifndef VERBOSE
66endif 66endif
67 67
68FEATURE_USER = .libbpf 68FEATURE_USER = .libbpf
69FEATURE_TESTS = libelf libelf-getphdrnum libelf-mmap bpf 69FEATURE_TESTS = libelf libelf-mmap bpf reallocarray
70FEATURE_DISPLAY = libelf bpf 70FEATURE_DISPLAY = libelf bpf
71 71
72INCLUDES = -I. -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(ARCH)/include/uapi -I$(srctree)/tools/include/uapi -I$(srctree)/tools/perf 72INCLUDES = -I. -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(ARCH)/include/uapi -I$(srctree)/tools/include/uapi -I$(srctree)/tools/perf
@@ -116,8 +116,8 @@ ifeq ($(feature-libelf-mmap), 1)
116 override CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT 116 override CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT
117endif 117endif
118 118
119ifeq ($(feature-libelf-getphdrnum), 1) 119ifeq ($(feature-reallocarray), 0)
120 override CFLAGS += -DHAVE_ELF_GETPHDRNUM_SUPPORT 120 override CFLAGS += -DCOMPAT_NEED_REALLOCARRAY
121endif 121endif
122 122
123# Append required CFLAGS 123# Append required CFLAGS
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 9ddc89dae962..60aa4ca8b2c5 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -92,6 +92,7 @@ int bpf_create_map_xattr(const struct bpf_create_map_attr *create_attr)
92 attr.btf_key_type_id = create_attr->btf_key_type_id; 92 attr.btf_key_type_id = create_attr->btf_key_type_id;
93 attr.btf_value_type_id = create_attr->btf_value_type_id; 93 attr.btf_value_type_id = create_attr->btf_value_type_id;
94 attr.map_ifindex = create_attr->map_ifindex; 94 attr.map_ifindex = create_attr->map_ifindex;
95 attr.inner_map_fd = create_attr->inner_map_fd;
95 96
96 return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr)); 97 return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
97} 98}
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 0639a30a457d..6f38164b2618 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -39,6 +39,7 @@ struct bpf_create_map_attr {
39 __u32 btf_key_type_id; 39 __u32 btf_key_type_id;
40 __u32 btf_value_type_id; 40 __u32 btf_value_type_id;
41 __u32 map_ifindex; 41 __u32 map_ifindex;
42 __u32 inner_map_fd;
42}; 43};
43 44
44int bpf_create_map_xattr(const struct bpf_create_map_attr *create_attr); 45int bpf_create_map_xattr(const struct bpf_create_map_attr *create_attr);
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index c36a3a76986a..cf94b0770522 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -16,6 +16,11 @@
16 16
17#define BTF_MAX_NR_TYPES 65535 17#define BTF_MAX_NR_TYPES 65535
18 18
19#define IS_MODIFIER(k) (((k) == BTF_KIND_TYPEDEF) || \
20 ((k) == BTF_KIND_VOLATILE) || \
21 ((k) == BTF_KIND_CONST) || \
22 ((k) == BTF_KIND_RESTRICT))
23
19static struct btf_type btf_void; 24static struct btf_type btf_void;
20 25
21struct btf { 26struct btf {
@@ -32,14 +37,6 @@ struct btf {
32 int fd; 37 int fd;
33}; 38};
34 39
35static const char *btf_name_by_offset(const struct btf *btf, __u32 offset)
36{
37 if (offset < btf->hdr->str_len)
38 return &btf->strings[offset];
39 else
40 return NULL;
41}
42
43static int btf_add_type(struct btf *btf, struct btf_type *t) 40static int btf_add_type(struct btf *btf, struct btf_type *t)
44{ 41{
45 if (btf->types_size - btf->nr_types < 2) { 42 if (btf->types_size - btf->nr_types < 2) {
@@ -269,6 +266,26 @@ __s64 btf__resolve_size(const struct btf *btf, __u32 type_id)
269 return nelems * size; 266 return nelems * size;
270} 267}
271 268
269int btf__resolve_type(const struct btf *btf, __u32 type_id)
270{
271 const struct btf_type *t;
272 int depth = 0;
273
274 t = btf__type_by_id(btf, type_id);
275 while (depth < MAX_RESOLVE_DEPTH &&
276 !btf_type_is_void_or_null(t) &&
277 IS_MODIFIER(BTF_INFO_KIND(t->info))) {
278 type_id = t->type;
279 t = btf__type_by_id(btf, type_id);
280 depth++;
281 }
282
283 if (depth == MAX_RESOLVE_DEPTH || btf_type_is_void_or_null(t))
284 return -EINVAL;
285
286 return type_id;
287}
288
272__s32 btf__find_by_name(const struct btf *btf, const char *type_name) 289__s32 btf__find_by_name(const struct btf *btf, const char *type_name)
273{ 290{
274 __u32 i; 291 __u32 i;
@@ -278,7 +295,7 @@ __s32 btf__find_by_name(const struct btf *btf, const char *type_name)
278 295
279 for (i = 1; i <= btf->nr_types; i++) { 296 for (i = 1; i <= btf->nr_types; i++) {
280 const struct btf_type *t = btf->types[i]; 297 const struct btf_type *t = btf->types[i];
281 const char *name = btf_name_by_offset(btf, t->name_off); 298 const char *name = btf__name_by_offset(btf, t->name_off);
282 299
283 if (name && !strcmp(type_name, name)) 300 if (name && !strcmp(type_name, name))
284 return i; 301 return i;
@@ -368,3 +385,11 @@ int btf__fd(const struct btf *btf)
368{ 385{
369 return btf->fd; 386 return btf->fd;
370} 387}
388
389const char *btf__name_by_offset(const struct btf *btf, __u32 offset)
390{
391 if (offset < btf->hdr->str_len)
392 return &btf->strings[offset];
393 else
394 return NULL;
395}
diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
index caac3a404dc5..4897e0724d4e 100644
--- a/tools/lib/bpf/btf.h
+++ b/tools/lib/bpf/btf.h
@@ -19,6 +19,8 @@ struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log);
19__s32 btf__find_by_name(const struct btf *btf, const char *type_name); 19__s32 btf__find_by_name(const struct btf *btf, const char *type_name);
20const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 id); 20const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 id);
21__s64 btf__resolve_size(const struct btf *btf, __u32 type_id); 21__s64 btf__resolve_size(const struct btf *btf, __u32 type_id);
22int btf__resolve_type(const struct btf *btf, __u32 type_id);
22int btf__fd(const struct btf *btf); 23int btf__fd(const struct btf *btf);
24const char *btf__name_by_offset(const struct btf *btf, __u32 offset);
23 25
24#endif 26#endif
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 1aafdbe827fe..2abd0f112627 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -22,6 +22,7 @@
22 * License along with this program; if not, see <http://www.gnu.org/licenses> 22 * License along with this program; if not, see <http://www.gnu.org/licenses>
23 */ 23 */
24 24
25#define _GNU_SOURCE
25#include <stdlib.h> 26#include <stdlib.h>
26#include <stdio.h> 27#include <stdio.h>
27#include <stdarg.h> 28#include <stdarg.h>
@@ -42,6 +43,7 @@
42#include <sys/stat.h> 43#include <sys/stat.h>
43#include <sys/types.h> 44#include <sys/types.h>
44#include <sys/vfs.h> 45#include <sys/vfs.h>
46#include <tools/libc_compat.h>
45#include <libelf.h> 47#include <libelf.h>
46#include <gelf.h> 48#include <gelf.h>
47 49
@@ -96,54 +98,6 @@ void libbpf_set_print(libbpf_print_fn_t warn,
96 98
97#define STRERR_BUFSIZE 128 99#define STRERR_BUFSIZE 128
98 100
99#define ERRNO_OFFSET(e) ((e) - __LIBBPF_ERRNO__START)
100#define ERRCODE_OFFSET(c) ERRNO_OFFSET(LIBBPF_ERRNO__##c)
101#define NR_ERRNO (__LIBBPF_ERRNO__END - __LIBBPF_ERRNO__START)
102
103static const char *libbpf_strerror_table[NR_ERRNO] = {
104 [ERRCODE_OFFSET(LIBELF)] = "Something wrong in libelf",
105 [ERRCODE_OFFSET(FORMAT)] = "BPF object format invalid",
106 [ERRCODE_OFFSET(KVERSION)] = "'version' section incorrect or lost",
107 [ERRCODE_OFFSET(ENDIAN)] = "Endian mismatch",
108 [ERRCODE_OFFSET(INTERNAL)] = "Internal error in libbpf",
109 [ERRCODE_OFFSET(RELOC)] = "Relocation failed",
110 [ERRCODE_OFFSET(VERIFY)] = "Kernel verifier blocks program loading",
111 [ERRCODE_OFFSET(PROG2BIG)] = "Program too big",
112 [ERRCODE_OFFSET(KVER)] = "Incorrect kernel version",
113 [ERRCODE_OFFSET(PROGTYPE)] = "Kernel doesn't support this program type",
114 [ERRCODE_OFFSET(WRNGPID)] = "Wrong pid in netlink message",
115 [ERRCODE_OFFSET(INVSEQ)] = "Invalid netlink sequence",
116};
117
118int libbpf_strerror(int err, char *buf, size_t size)
119{
120 if (!buf || !size)
121 return -1;
122
123 err = err > 0 ? err : -err;
124
125 if (err < __LIBBPF_ERRNO__START) {
126 int ret;
127
128 ret = strerror_r(err, buf, size);
129 buf[size - 1] = '\0';
130 return ret;
131 }
132
133 if (err < __LIBBPF_ERRNO__END) {
134 const char *msg;
135
136 msg = libbpf_strerror_table[ERRNO_OFFSET(err)];
137 snprintf(buf, size, "%s", msg);
138 buf[size - 1] = '\0';
139 return 0;
140 }
141
142 snprintf(buf, size, "Unknown libbpf error %d", err);
143 buf[size - 1] = '\0';
144 return -1;
145}
146
147#define CHECK_ERR(action, err, out) do { \ 101#define CHECK_ERR(action, err, out) do { \
148 err = action; \ 102 err = action; \
149 if (err) \ 103 if (err) \
@@ -235,6 +189,7 @@ struct bpf_object {
235 size_t nr_maps; 189 size_t nr_maps;
236 190
237 bool loaded; 191 bool loaded;
192 bool has_pseudo_calls;
238 193
239 /* 194 /*
240 * Information when doing elf related work. Only valid if fd 195 * Information when doing elf related work. Only valid if fd
@@ -369,7 +324,7 @@ bpf_object__add_program(struct bpf_object *obj, void *data, size_t size,
369 progs = obj->programs; 324 progs = obj->programs;
370 nr_progs = obj->nr_programs; 325 nr_progs = obj->nr_programs;
371 326
372 progs = realloc(progs, sizeof(progs[0]) * (nr_progs + 1)); 327 progs = reallocarray(progs, nr_progs + 1, sizeof(progs[0]));
373 if (!progs) { 328 if (!progs) {
374 /* 329 /*
375 * In this case the original obj->programs 330 * In this case the original obj->programs
@@ -401,10 +356,6 @@ bpf_object__init_prog_names(struct bpf_object *obj)
401 const char *name = NULL; 356 const char *name = NULL;
402 357
403 prog = &obj->programs[pi]; 358 prog = &obj->programs[pi];
404 if (prog->idx == obj->efile.text_shndx) {
405 name = ".text";
406 goto skip_search;
407 }
408 359
409 for (si = 0; si < symbols->d_size / sizeof(GElf_Sym) && !name; 360 for (si = 0; si < symbols->d_size / sizeof(GElf_Sym) && !name;
410 si++) { 361 si++) {
@@ -427,12 +378,15 @@ bpf_object__init_prog_names(struct bpf_object *obj)
427 } 378 }
428 } 379 }
429 380
381 if (!name && prog->idx == obj->efile.text_shndx)
382 name = ".text";
383
430 if (!name) { 384 if (!name) {
431 pr_warning("failed to find sym for prog %s\n", 385 pr_warning("failed to find sym for prog %s\n",
432 prog->section_name); 386 prog->section_name);
433 return -EINVAL; 387 return -EINVAL;
434 } 388 }
435skip_search: 389
436 prog->name = strdup(name); 390 prog->name = strdup(name);
437 if (!prog->name) { 391 if (!prog->name) {
438 pr_warning("failed to allocate memory for prog sym %s\n", 392 pr_warning("failed to allocate memory for prog sym %s\n",
@@ -514,8 +468,10 @@ static int bpf_object__elf_init(struct bpf_object *obj)
514 } else { 468 } else {
515 obj->efile.fd = open(obj->path, O_RDONLY); 469 obj->efile.fd = open(obj->path, O_RDONLY);
516 if (obj->efile.fd < 0) { 470 if (obj->efile.fd < 0) {
517 pr_warning("failed to open %s: %s\n", obj->path, 471 char errmsg[STRERR_BUFSIZE];
518 strerror(errno)); 472 char *cp = strerror_r(errno, errmsg, sizeof(errmsg));
473
474 pr_warning("failed to open %s: %s\n", obj->path, cp);
519 return -errno; 475 return -errno;
520 } 476 }
521 477
@@ -854,10 +810,11 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
854 data->d_size, name, idx); 810 data->d_size, name, idx);
855 if (err) { 811 if (err) {
856 char errmsg[STRERR_BUFSIZE]; 812 char errmsg[STRERR_BUFSIZE];
813 char *cp = strerror_r(-err, errmsg,
814 sizeof(errmsg));
857 815
858 strerror_r(-err, errmsg, sizeof(errmsg));
859 pr_warning("failed to alloc program %s (%s): %s", 816 pr_warning("failed to alloc program %s (%s): %s",
860 name, obj->path, errmsg); 817 name, obj->path, cp);
861 } 818 }
862 } else if (sh.sh_type == SHT_REL) { 819 } else if (sh.sh_type == SHT_REL) {
863 void *reloc = obj->efile.reloc; 820 void *reloc = obj->efile.reloc;
@@ -871,8 +828,8 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
871 continue; 828 continue;
872 } 829 }
873 830
874 reloc = realloc(reloc, 831 reloc = reallocarray(reloc, nr_reloc,
875 sizeof(*obj->efile.reloc) * nr_reloc); 832 sizeof(*obj->efile.reloc));
876 if (!reloc) { 833 if (!reloc) {
877 pr_warning("realloc failed\n"); 834 pr_warning("realloc failed\n");
878 err = -ENOMEM; 835 err = -ENOMEM;
@@ -920,6 +877,18 @@ bpf_object__find_prog_by_idx(struct bpf_object *obj, int idx)
920 return NULL; 877 return NULL;
921} 878}
922 879
880struct bpf_program *
881bpf_object__find_program_by_title(struct bpf_object *obj, const char *title)
882{
883 struct bpf_program *pos;
884
885 bpf_object__for_each_program(pos, obj) {
886 if (pos->section_name && !strcmp(pos->section_name, title))
887 return pos;
888 }
889 return NULL;
890}
891
923static int 892static int
924bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr, 893bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr,
925 Elf_Data *data, struct bpf_object *obj) 894 Elf_Data *data, struct bpf_object *obj)
@@ -982,6 +951,7 @@ bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr,
982 prog->reloc_desc[i].type = RELO_CALL; 951 prog->reloc_desc[i].type = RELO_CALL;
983 prog->reloc_desc[i].insn_idx = insn_idx; 952 prog->reloc_desc[i].insn_idx = insn_idx;
984 prog->reloc_desc[i].text_off = sym.st_value; 953 prog->reloc_desc[i].text_off = sym.st_value;
954 obj->has_pseudo_calls = true;
985 continue; 955 continue;
986 } 956 }
987 957
@@ -1085,6 +1055,53 @@ static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf)
1085 return 0; 1055 return 0;
1086} 1056}
1087 1057
1058int bpf_map__reuse_fd(struct bpf_map *map, int fd)
1059{
1060 struct bpf_map_info info = {};
1061 __u32 len = sizeof(info);
1062 int new_fd, err;
1063 char *new_name;
1064
1065 err = bpf_obj_get_info_by_fd(fd, &info, &len);
1066 if (err)
1067 return err;
1068
1069 new_name = strdup(info.name);
1070 if (!new_name)
1071 return -errno;
1072
1073 new_fd = open("/", O_RDONLY | O_CLOEXEC);
1074 if (new_fd < 0)
1075 goto err_free_new_name;
1076
1077 new_fd = dup3(fd, new_fd, O_CLOEXEC);
1078 if (new_fd < 0)
1079 goto err_close_new_fd;
1080
1081 err = zclose(map->fd);
1082 if (err)
1083 goto err_close_new_fd;
1084 free(map->name);
1085
1086 map->fd = new_fd;
1087 map->name = new_name;
1088 map->def.type = info.type;
1089 map->def.key_size = info.key_size;
1090 map->def.value_size = info.value_size;
1091 map->def.max_entries = info.max_entries;
1092 map->def.map_flags = info.map_flags;
1093 map->btf_key_type_id = info.btf_key_type_id;
1094 map->btf_value_type_id = info.btf_value_type_id;
1095
1096 return 0;
1097
1098err_close_new_fd:
1099 close(new_fd);
1100err_free_new_name:
1101 free(new_name);
1102 return -errno;
1103}
1104
1088static int 1105static int
1089bpf_object__create_maps(struct bpf_object *obj) 1106bpf_object__create_maps(struct bpf_object *obj)
1090{ 1107{
@@ -1095,8 +1112,15 @@ bpf_object__create_maps(struct bpf_object *obj)
1095 for (i = 0; i < obj->nr_maps; i++) { 1112 for (i = 0; i < obj->nr_maps; i++) {
1096 struct bpf_map *map = &obj->maps[i]; 1113 struct bpf_map *map = &obj->maps[i];
1097 struct bpf_map_def *def = &map->def; 1114 struct bpf_map_def *def = &map->def;
1115 char *cp, errmsg[STRERR_BUFSIZE];
1098 int *pfd = &map->fd; 1116 int *pfd = &map->fd;
1099 1117
1118 if (map->fd >= 0) {
1119 pr_debug("skip map create (preset) %s: fd=%d\n",
1120 map->name, map->fd);
1121 continue;
1122 }
1123
1100 create_attr.name = map->name; 1124 create_attr.name = map->name;
1101 create_attr.map_ifindex = map->map_ifindex; 1125 create_attr.map_ifindex = map->map_ifindex;
1102 create_attr.map_type = def->type; 1126 create_attr.map_type = def->type;
@@ -1116,8 +1140,9 @@ bpf_object__create_maps(struct bpf_object *obj)
1116 1140
1117 *pfd = bpf_create_map_xattr(&create_attr); 1141 *pfd = bpf_create_map_xattr(&create_attr);
1118 if (*pfd < 0 && create_attr.btf_key_type_id) { 1142 if (*pfd < 0 && create_attr.btf_key_type_id) {
1143 cp = strerror_r(errno, errmsg, sizeof(errmsg));
1119 pr_warning("Error in bpf_create_map_xattr(%s):%s(%d). Retrying without BTF.\n", 1144 pr_warning("Error in bpf_create_map_xattr(%s):%s(%d). Retrying without BTF.\n",
1120 map->name, strerror(errno), errno); 1145 map->name, cp, errno);
1121 create_attr.btf_fd = 0; 1146 create_attr.btf_fd = 0;
1122 create_attr.btf_key_type_id = 0; 1147 create_attr.btf_key_type_id = 0;
1123 create_attr.btf_value_type_id = 0; 1148 create_attr.btf_value_type_id = 0;
@@ -1130,9 +1155,9 @@ bpf_object__create_maps(struct bpf_object *obj)
1130 size_t j; 1155 size_t j;
1131 1156
1132 err = *pfd; 1157 err = *pfd;
1158 cp = strerror_r(errno, errmsg, sizeof(errmsg));
1133 pr_warning("failed to create map (name: '%s'): %s\n", 1159 pr_warning("failed to create map (name: '%s'): %s\n",
1134 map->name, 1160 map->name, cp);
1135 strerror(errno));
1136 for (j = 0; j < i; j++) 1161 for (j = 0; j < i; j++)
1137 zclose(obj->maps[j].fd); 1162 zclose(obj->maps[j].fd);
1138 return err; 1163 return err;
@@ -1167,7 +1192,7 @@ bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj,
1167 return -LIBBPF_ERRNO__RELOC; 1192 return -LIBBPF_ERRNO__RELOC;
1168 } 1193 }
1169 new_cnt = prog->insns_cnt + text->insns_cnt; 1194 new_cnt = prog->insns_cnt + text->insns_cnt;
1170 new_insn = realloc(prog->insns, new_cnt * sizeof(*insn)); 1195 new_insn = reallocarray(prog->insns, new_cnt, sizeof(*insn));
1171 if (!new_insn) { 1196 if (!new_insn) {
1172 pr_warning("oom in prog realloc\n"); 1197 pr_warning("oom in prog realloc\n");
1173 return -ENOMEM; 1198 return -ENOMEM;
@@ -1284,6 +1309,7 @@ load_program(enum bpf_prog_type type, enum bpf_attach_type expected_attach_type,
1284 char *license, u32 kern_version, int *pfd, int prog_ifindex) 1309 char *license, u32 kern_version, int *pfd, int prog_ifindex)
1285{ 1310{
1286 struct bpf_load_program_attr load_attr; 1311 struct bpf_load_program_attr load_attr;
1312 char *cp, errmsg[STRERR_BUFSIZE];
1287 char *log_buf; 1313 char *log_buf;
1288 int ret; 1314 int ret;
1289 1315
@@ -1313,7 +1339,8 @@ load_program(enum bpf_prog_type type, enum bpf_attach_type expected_attach_type,
1313 } 1339 }
1314 1340
1315 ret = -LIBBPF_ERRNO__LOAD; 1341 ret = -LIBBPF_ERRNO__LOAD;
1316 pr_warning("load bpf program failed: %s\n", strerror(errno)); 1342 cp = strerror_r(errno, errmsg, sizeof(errmsg));
1343 pr_warning("load bpf program failed: %s\n", cp);
1317 1344
1318 if (log_buf && log_buf[0] != '\0') { 1345 if (log_buf && log_buf[0] != '\0') {
1319 ret = -LIBBPF_ERRNO__VERIFY; 1346 ret = -LIBBPF_ERRNO__VERIFY;
@@ -1431,6 +1458,12 @@ out:
1431 return err; 1458 return err;
1432} 1459}
1433 1460
1461static bool bpf_program__is_function_storage(struct bpf_program *prog,
1462 struct bpf_object *obj)
1463{
1464 return prog->idx == obj->efile.text_shndx && obj->has_pseudo_calls;
1465}
1466
1434static int 1467static int
1435bpf_object__load_progs(struct bpf_object *obj) 1468bpf_object__load_progs(struct bpf_object *obj)
1436{ 1469{
@@ -1438,7 +1471,7 @@ bpf_object__load_progs(struct bpf_object *obj)
1438 int err; 1471 int err;
1439 1472
1440 for (i = 0; i < obj->nr_programs; i++) { 1473 for (i = 0; i < obj->nr_programs; i++) {
1441 if (obj->programs[i].idx == obj->efile.text_shndx) 1474 if (bpf_program__is_function_storage(&obj->programs[i], obj))
1442 continue; 1475 continue;
1443 err = bpf_program__load(&obj->programs[i], 1476 err = bpf_program__load(&obj->programs[i],
1444 obj->license, 1477 obj->license,
@@ -1468,6 +1501,7 @@ static bool bpf_prog_type__needs_kver(enum bpf_prog_type type)
1468 case BPF_PROG_TYPE_SK_MSG: 1501 case BPF_PROG_TYPE_SK_MSG:
1469 case BPF_PROG_TYPE_CGROUP_SOCK_ADDR: 1502 case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
1470 case BPF_PROG_TYPE_LIRC_MODE2: 1503 case BPF_PROG_TYPE_LIRC_MODE2:
1504 case BPF_PROG_TYPE_SK_REUSEPORT:
1471 return false; 1505 return false;
1472 case BPF_PROG_TYPE_UNSPEC: 1506 case BPF_PROG_TYPE_UNSPEC:
1473 case BPF_PROG_TYPE_KPROBE: 1507 case BPF_PROG_TYPE_KPROBE:
@@ -1518,15 +1552,26 @@ out:
1518 return ERR_PTR(err); 1552 return ERR_PTR(err);
1519} 1553}
1520 1554
1521struct bpf_object *bpf_object__open(const char *path) 1555struct bpf_object *bpf_object__open_xattr(struct bpf_object_open_attr *attr)
1522{ 1556{
1523 /* param validation */ 1557 /* param validation */
1524 if (!path) 1558 if (!attr->file)
1525 return NULL; 1559 return NULL;
1526 1560
1527 pr_debug("loading %s\n", path); 1561 pr_debug("loading %s\n", attr->file);
1528 1562
1529 return __bpf_object__open(path, NULL, 0, true); 1563 return __bpf_object__open(attr->file, NULL, 0,
1564 bpf_prog_type__needs_kver(attr->prog_type));
1565}
1566
1567struct bpf_object *bpf_object__open(const char *path)
1568{
1569 struct bpf_object_open_attr attr = {
1570 .file = path,
1571 .prog_type = BPF_PROG_TYPE_UNSPEC,
1572 };
1573
1574 return bpf_object__open_xattr(&attr);
1530} 1575}
1531 1576
1532struct bpf_object *bpf_object__open_buffer(void *obj_buf, 1577struct bpf_object *bpf_object__open_buffer(void *obj_buf,
@@ -1595,6 +1640,7 @@ out:
1595 1640
1596static int check_path(const char *path) 1641static int check_path(const char *path)
1597{ 1642{
1643 char *cp, errmsg[STRERR_BUFSIZE];
1598 struct statfs st_fs; 1644 struct statfs st_fs;
1599 char *dname, *dir; 1645 char *dname, *dir;
1600 int err = 0; 1646 int err = 0;
@@ -1608,7 +1654,8 @@ static int check_path(const char *path)
1608 1654
1609 dir = dirname(dname); 1655 dir = dirname(dname);
1610 if (statfs(dir, &st_fs)) { 1656 if (statfs(dir, &st_fs)) {
1611 pr_warning("failed to statfs %s: %s\n", dir, strerror(errno)); 1657 cp = strerror_r(errno, errmsg, sizeof(errmsg));
1658 pr_warning("failed to statfs %s: %s\n", dir, cp);
1612 err = -errno; 1659 err = -errno;
1613 } 1660 }
1614 free(dname); 1661 free(dname);
@@ -1624,6 +1671,7 @@ static int check_path(const char *path)
1624int bpf_program__pin_instance(struct bpf_program *prog, const char *path, 1671int bpf_program__pin_instance(struct bpf_program *prog, const char *path,
1625 int instance) 1672 int instance)
1626{ 1673{
1674 char *cp, errmsg[STRERR_BUFSIZE];
1627 int err; 1675 int err;
1628 1676
1629 err = check_path(path); 1677 err = check_path(path);
@@ -1642,7 +1690,8 @@ int bpf_program__pin_instance(struct bpf_program *prog, const char *path,
1642 } 1690 }
1643 1691
1644 if (bpf_obj_pin(prog->instances.fds[instance], path)) { 1692 if (bpf_obj_pin(prog->instances.fds[instance], path)) {
1645 pr_warning("failed to pin program: %s\n", strerror(errno)); 1693 cp = strerror_r(errno, errmsg, sizeof(errmsg));
1694 pr_warning("failed to pin program: %s\n", cp);
1646 return -errno; 1695 return -errno;
1647 } 1696 }
1648 pr_debug("pinned program '%s'\n", path); 1697 pr_debug("pinned program '%s'\n", path);
@@ -1652,13 +1701,16 @@ int bpf_program__pin_instance(struct bpf_program *prog, const char *path,
1652 1701
1653static int make_dir(const char *path) 1702static int make_dir(const char *path)
1654{ 1703{
1704 char *cp, errmsg[STRERR_BUFSIZE];
1655 int err = 0; 1705 int err = 0;
1656 1706
1657 if (mkdir(path, 0700) && errno != EEXIST) 1707 if (mkdir(path, 0700) && errno != EEXIST)
1658 err = -errno; 1708 err = -errno;
1659 1709
1660 if (err) 1710 if (err) {
1661 pr_warning("failed to mkdir %s: %s\n", path, strerror(-err)); 1711 cp = strerror_r(-err, errmsg, sizeof(errmsg));
1712 pr_warning("failed to mkdir %s: %s\n", path, cp);
1713 }
1662 return err; 1714 return err;
1663} 1715}
1664 1716
@@ -1705,6 +1757,7 @@ int bpf_program__pin(struct bpf_program *prog, const char *path)
1705 1757
1706int bpf_map__pin(struct bpf_map *map, const char *path) 1758int bpf_map__pin(struct bpf_map *map, const char *path)
1707{ 1759{
1760 char *cp, errmsg[STRERR_BUFSIZE];
1708 int err; 1761 int err;
1709 1762
1710 err = check_path(path); 1763 err = check_path(path);
@@ -1717,7 +1770,8 @@ int bpf_map__pin(struct bpf_map *map, const char *path)
1717 } 1770 }
1718 1771
1719 if (bpf_obj_pin(map->fd, path)) { 1772 if (bpf_obj_pin(map->fd, path)) {
1720 pr_warning("failed to pin map: %s\n", strerror(errno)); 1773 cp = strerror_r(errno, errmsg, sizeof(errmsg));
1774 pr_warning("failed to pin map: %s\n", cp);
1721 return -errno; 1775 return -errno;
1722 } 1776 }
1723 1777
@@ -1863,8 +1917,8 @@ void *bpf_object__priv(struct bpf_object *obj)
1863 return obj ? obj->priv : ERR_PTR(-EINVAL); 1917 return obj ? obj->priv : ERR_PTR(-EINVAL);
1864} 1918}
1865 1919
1866struct bpf_program * 1920static struct bpf_program *
1867bpf_program__next(struct bpf_program *prev, struct bpf_object *obj) 1921__bpf_program__next(struct bpf_program *prev, struct bpf_object *obj)
1868{ 1922{
1869 size_t idx; 1923 size_t idx;
1870 1924
@@ -1885,6 +1939,18 @@ bpf_program__next(struct bpf_program *prev, struct bpf_object *obj)
1885 return &obj->programs[idx]; 1939 return &obj->programs[idx];
1886} 1940}
1887 1941
1942struct bpf_program *
1943bpf_program__next(struct bpf_program *prev, struct bpf_object *obj)
1944{
1945 struct bpf_program *prog = prev;
1946
1947 do {
1948 prog = __bpf_program__next(prog, obj);
1949 } while (prog && bpf_program__is_function_storage(prog, obj));
1950
1951 return prog;
1952}
1953
1888int bpf_program__set_priv(struct bpf_program *prog, void *priv, 1954int bpf_program__set_priv(struct bpf_program *prog, void *priv,
1889 bpf_program_clear_priv_t clear_priv) 1955 bpf_program_clear_priv_t clear_priv)
1890{ 1956{
@@ -1901,6 +1967,11 @@ void *bpf_program__priv(struct bpf_program *prog)
1901 return prog ? prog->priv : ERR_PTR(-EINVAL); 1967 return prog ? prog->priv : ERR_PTR(-EINVAL);
1902} 1968}
1903 1969
1970void bpf_program__set_ifindex(struct bpf_program *prog, __u32 ifindex)
1971{
1972 prog->prog_ifindex = ifindex;
1973}
1974
1904const char *bpf_program__title(struct bpf_program *prog, bool needs_copy) 1975const char *bpf_program__title(struct bpf_program *prog, bool needs_copy)
1905{ 1976{
1906 const char *title; 1977 const char *title;
@@ -1954,6 +2025,9 @@ int bpf_program__nth_fd(struct bpf_program *prog, int n)
1954{ 2025{
1955 int fd; 2026 int fd;
1956 2027
2028 if (!prog)
2029 return -EINVAL;
2030
1957 if (n >= prog->instances.nr || n < 0) { 2031 if (n >= prog->instances.nr || n < 0) {
1958 pr_warning("Can't get the %dth fd from program %s: only %d instances\n", 2032 pr_warning("Can't get the %dth fd from program %s: only %d instances\n",
1959 n, prog->section_name, prog->instances.nr); 2033 n, prog->section_name, prog->instances.nr);
@@ -2042,9 +2116,11 @@ static const struct {
2042 BPF_PROG_SEC("lwt_in", BPF_PROG_TYPE_LWT_IN), 2116 BPF_PROG_SEC("lwt_in", BPF_PROG_TYPE_LWT_IN),
2043 BPF_PROG_SEC("lwt_out", BPF_PROG_TYPE_LWT_OUT), 2117 BPF_PROG_SEC("lwt_out", BPF_PROG_TYPE_LWT_OUT),
2044 BPF_PROG_SEC("lwt_xmit", BPF_PROG_TYPE_LWT_XMIT), 2118 BPF_PROG_SEC("lwt_xmit", BPF_PROG_TYPE_LWT_XMIT),
2119 BPF_PROG_SEC("lwt_seg6local", BPF_PROG_TYPE_LWT_SEG6LOCAL),
2045 BPF_PROG_SEC("sockops", BPF_PROG_TYPE_SOCK_OPS), 2120 BPF_PROG_SEC("sockops", BPF_PROG_TYPE_SOCK_OPS),
2046 BPF_PROG_SEC("sk_skb", BPF_PROG_TYPE_SK_SKB), 2121 BPF_PROG_SEC("sk_skb", BPF_PROG_TYPE_SK_SKB),
2047 BPF_PROG_SEC("sk_msg", BPF_PROG_TYPE_SK_MSG), 2122 BPF_PROG_SEC("sk_msg", BPF_PROG_TYPE_SK_MSG),
2123 BPF_PROG_SEC("lirc_mode2", BPF_PROG_TYPE_LIRC_MODE2),
2048 BPF_SA_PROG_SEC("cgroup/bind4", BPF_CGROUP_INET4_BIND), 2124 BPF_SA_PROG_SEC("cgroup/bind4", BPF_CGROUP_INET4_BIND),
2049 BPF_SA_PROG_SEC("cgroup/bind6", BPF_CGROUP_INET6_BIND), 2125 BPF_SA_PROG_SEC("cgroup/bind6", BPF_CGROUP_INET6_BIND),
2050 BPF_SA_PROG_SEC("cgroup/connect4", BPF_CGROUP_INET4_CONNECT), 2126 BPF_SA_PROG_SEC("cgroup/connect4", BPF_CGROUP_INET4_CONNECT),
@@ -2060,23 +2136,31 @@ static const struct {
2060#undef BPF_S_PROG_SEC 2136#undef BPF_S_PROG_SEC
2061#undef BPF_SA_PROG_SEC 2137#undef BPF_SA_PROG_SEC
2062 2138
2063static int bpf_program__identify_section(struct bpf_program *prog) 2139int libbpf_prog_type_by_name(const char *name, enum bpf_prog_type *prog_type,
2140 enum bpf_attach_type *expected_attach_type)
2064{ 2141{
2065 int i; 2142 int i;
2066 2143
2067 if (!prog->section_name) 2144 if (!name)
2068 goto err; 2145 return -EINVAL;
2069
2070 for (i = 0; i < ARRAY_SIZE(section_names); i++)
2071 if (strncmp(prog->section_name, section_names[i].sec,
2072 section_names[i].len) == 0)
2073 return i;
2074 2146
2075err: 2147 for (i = 0; i < ARRAY_SIZE(section_names); i++) {
2076 pr_warning("failed to guess program type based on section name %s\n", 2148 if (strncmp(name, section_names[i].sec, section_names[i].len))
2077 prog->section_name); 2149 continue;
2150 *prog_type = section_names[i].prog_type;
2151 *expected_attach_type = section_names[i].expected_attach_type;
2152 return 0;
2153 }
2154 return -EINVAL;
2155}
2078 2156
2079 return -1; 2157static int
2158bpf_program__identify_section(struct bpf_program *prog,
2159 enum bpf_prog_type *prog_type,
2160 enum bpf_attach_type *expected_attach_type)
2161{
2162 return libbpf_prog_type_by_name(prog->section_name, prog_type,
2163 expected_attach_type);
2080} 2164}
2081 2165
2082int bpf_map__fd(struct bpf_map *map) 2166int bpf_map__fd(struct bpf_map *map)
@@ -2125,6 +2209,16 @@ void *bpf_map__priv(struct bpf_map *map)
2125 return map ? map->priv : ERR_PTR(-EINVAL); 2209 return map ? map->priv : ERR_PTR(-EINVAL);
2126} 2210}
2127 2211
2212bool bpf_map__is_offload_neutral(struct bpf_map *map)
2213{
2214 return map->def.type == BPF_MAP_TYPE_PERF_EVENT_ARRAY;
2215}
2216
2217void bpf_map__set_ifindex(struct bpf_map *map, __u32 ifindex)
2218{
2219 map->map_ifindex = ifindex;
2220}
2221
2128struct bpf_map * 2222struct bpf_map *
2129bpf_map__next(struct bpf_map *prev, struct bpf_object *obj) 2223bpf_map__next(struct bpf_map *prev, struct bpf_object *obj)
2130{ 2224{
@@ -2199,12 +2293,15 @@ int bpf_prog_load(const char *file, enum bpf_prog_type type,
2199int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr, 2293int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr,
2200 struct bpf_object **pobj, int *prog_fd) 2294 struct bpf_object **pobj, int *prog_fd)
2201{ 2295{
2296 struct bpf_object_open_attr open_attr = {
2297 .file = attr->file,
2298 .prog_type = attr->prog_type,
2299 };
2202 struct bpf_program *prog, *first_prog = NULL; 2300 struct bpf_program *prog, *first_prog = NULL;
2203 enum bpf_attach_type expected_attach_type; 2301 enum bpf_attach_type expected_attach_type;
2204 enum bpf_prog_type prog_type; 2302 enum bpf_prog_type prog_type;
2205 struct bpf_object *obj; 2303 struct bpf_object *obj;
2206 struct bpf_map *map; 2304 struct bpf_map *map;
2207 int section_idx;
2208 int err; 2305 int err;
2209 2306
2210 if (!attr) 2307 if (!attr)
@@ -2212,8 +2309,7 @@ int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr,
2212 if (!attr->file) 2309 if (!attr->file)
2213 return -EINVAL; 2310 return -EINVAL;
2214 2311
2215 obj = __bpf_object__open(attr->file, NULL, 0, 2312 obj = bpf_object__open_xattr(&open_attr);
2216 bpf_prog_type__needs_kver(attr->prog_type));
2217 if (IS_ERR_OR_NULL(obj)) 2313 if (IS_ERR_OR_NULL(obj))
2218 return -ENOENT; 2314 return -ENOENT;
2219 2315
@@ -2226,26 +2322,27 @@ int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr,
2226 prog->prog_ifindex = attr->ifindex; 2322 prog->prog_ifindex = attr->ifindex;
2227 expected_attach_type = attr->expected_attach_type; 2323 expected_attach_type = attr->expected_attach_type;
2228 if (prog_type == BPF_PROG_TYPE_UNSPEC) { 2324 if (prog_type == BPF_PROG_TYPE_UNSPEC) {
2229 section_idx = bpf_program__identify_section(prog); 2325 err = bpf_program__identify_section(prog, &prog_type,
2230 if (section_idx < 0) { 2326 &expected_attach_type);
2327 if (err < 0) {
2328 pr_warning("failed to guess program type based on section name %s\n",
2329 prog->section_name);
2231 bpf_object__close(obj); 2330 bpf_object__close(obj);
2232 return -EINVAL; 2331 return -EINVAL;
2233 } 2332 }
2234 prog_type = section_names[section_idx].prog_type;
2235 expected_attach_type =
2236 section_names[section_idx].expected_attach_type;
2237 } 2333 }
2238 2334
2239 bpf_program__set_type(prog, prog_type); 2335 bpf_program__set_type(prog, prog_type);
2240 bpf_program__set_expected_attach_type(prog, 2336 bpf_program__set_expected_attach_type(prog,
2241 expected_attach_type); 2337 expected_attach_type);
2242 2338
2243 if (prog->idx != obj->efile.text_shndx && !first_prog) 2339 if (!bpf_program__is_function_storage(prog, obj) && !first_prog)
2244 first_prog = prog; 2340 first_prog = prog;
2245 } 2341 }
2246 2342
2247 bpf_map__for_each(map, obj) { 2343 bpf_map__for_each(map, obj) {
2248 map->map_ifindex = attr->ifindex; 2344 if (!bpf_map__is_offload_neutral(map))
2345 map->map_ifindex = attr->ifindex;
2249 } 2346 }
2250 2347
2251 if (!first_prog) { 2348 if (!first_prog) {
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index b33ae02f7d0e..96c55fac54c3 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -66,7 +66,13 @@ void libbpf_set_print(libbpf_print_fn_t warn,
66/* Hide internal to user */ 66/* Hide internal to user */
67struct bpf_object; 67struct bpf_object;
68 68
69struct bpf_object_open_attr {
70 const char *file;
71 enum bpf_prog_type prog_type;
72};
73
69struct bpf_object *bpf_object__open(const char *path); 74struct bpf_object *bpf_object__open(const char *path);
75struct bpf_object *bpf_object__open_xattr(struct bpf_object_open_attr *attr);
70struct bpf_object *bpf_object__open_buffer(void *obj_buf, 76struct bpf_object *bpf_object__open_buffer(void *obj_buf,
71 size_t obj_buf_sz, 77 size_t obj_buf_sz,
72 const char *name); 78 const char *name);
@@ -80,6 +86,9 @@ const char *bpf_object__name(struct bpf_object *obj);
80unsigned int bpf_object__kversion(struct bpf_object *obj); 86unsigned int bpf_object__kversion(struct bpf_object *obj);
81int bpf_object__btf_fd(const struct bpf_object *obj); 87int bpf_object__btf_fd(const struct bpf_object *obj);
82 88
89struct bpf_program *
90bpf_object__find_program_by_title(struct bpf_object *obj, const char *title);
91
83struct bpf_object *bpf_object__next(struct bpf_object *prev); 92struct bpf_object *bpf_object__next(struct bpf_object *prev);
84#define bpf_object__for_each_safe(pos, tmp) \ 93#define bpf_object__for_each_safe(pos, tmp) \
85 for ((pos) = bpf_object__next(NULL), \ 94 for ((pos) = bpf_object__next(NULL), \
@@ -92,6 +101,9 @@ int bpf_object__set_priv(struct bpf_object *obj, void *priv,
92 bpf_object_clear_priv_t clear_priv); 101 bpf_object_clear_priv_t clear_priv);
93void *bpf_object__priv(struct bpf_object *prog); 102void *bpf_object__priv(struct bpf_object *prog);
94 103
104int libbpf_prog_type_by_name(const char *name, enum bpf_prog_type *prog_type,
105 enum bpf_attach_type *expected_attach_type);
106
95/* Accessors of bpf_program */ 107/* Accessors of bpf_program */
96struct bpf_program; 108struct bpf_program;
97struct bpf_program *bpf_program__next(struct bpf_program *prog, 109struct bpf_program *bpf_program__next(struct bpf_program *prog,
@@ -109,6 +121,7 @@ int bpf_program__set_priv(struct bpf_program *prog, void *priv,
109 bpf_program_clear_priv_t clear_priv); 121 bpf_program_clear_priv_t clear_priv);
110 122
111void *bpf_program__priv(struct bpf_program *prog); 123void *bpf_program__priv(struct bpf_program *prog);
124void bpf_program__set_ifindex(struct bpf_program *prog, __u32 ifindex);
112 125
113const char *bpf_program__title(struct bpf_program *prog, bool needs_copy); 126const char *bpf_program__title(struct bpf_program *prog, bool needs_copy);
114 127
@@ -251,6 +264,9 @@ typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *);
251int bpf_map__set_priv(struct bpf_map *map, void *priv, 264int bpf_map__set_priv(struct bpf_map *map, void *priv,
252 bpf_map_clear_priv_t clear_priv); 265 bpf_map_clear_priv_t clear_priv);
253void *bpf_map__priv(struct bpf_map *map); 266void *bpf_map__priv(struct bpf_map *map);
267int bpf_map__reuse_fd(struct bpf_map *map, int fd);
268bool bpf_map__is_offload_neutral(struct bpf_map *map);
269void bpf_map__set_ifindex(struct bpf_map *map, __u32 ifindex);
254int bpf_map__pin(struct bpf_map *map, const char *path); 270int bpf_map__pin(struct bpf_map *map, const char *path);
255 271
256long libbpf_get_error(const void *ptr); 272long libbpf_get_error(const void *ptr);
diff --git a/tools/lib/bpf/libbpf_errno.c b/tools/lib/bpf/libbpf_errno.c
new file mode 100644
index 000000000000..d9ba851bd7f9
--- /dev/null
+++ b/tools/lib/bpf/libbpf_errno.c
@@ -0,0 +1,74 @@
1// SPDX-License-Identifier: LGPL-2.1
2
3/*
4 * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org>
5 * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com>
6 * Copyright (C) 2015 Huawei Inc.
7 * Copyright (C) 2017 Nicira, Inc.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation;
12 * version 2.1 of the License (not later!)
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this program; if not, see <http://www.gnu.org/licenses>
21 */
22
23#include <stdio.h>
24#include <string.h>
25
26#include "libbpf.h"
27
28#define ERRNO_OFFSET(e) ((e) - __LIBBPF_ERRNO__START)
29#define ERRCODE_OFFSET(c) ERRNO_OFFSET(LIBBPF_ERRNO__##c)
30#define NR_ERRNO (__LIBBPF_ERRNO__END - __LIBBPF_ERRNO__START)
31
32static const char *libbpf_strerror_table[NR_ERRNO] = {
33 [ERRCODE_OFFSET(LIBELF)] = "Something wrong in libelf",
34 [ERRCODE_OFFSET(FORMAT)] = "BPF object format invalid",
35 [ERRCODE_OFFSET(KVERSION)] = "'version' section incorrect or lost",
36 [ERRCODE_OFFSET(ENDIAN)] = "Endian mismatch",
37 [ERRCODE_OFFSET(INTERNAL)] = "Internal error in libbpf",
38 [ERRCODE_OFFSET(RELOC)] = "Relocation failed",
39 [ERRCODE_OFFSET(VERIFY)] = "Kernel verifier blocks program loading",
40 [ERRCODE_OFFSET(PROG2BIG)] = "Program too big",
41 [ERRCODE_OFFSET(KVER)] = "Incorrect kernel version",
42 [ERRCODE_OFFSET(PROGTYPE)] = "Kernel doesn't support this program type",
43 [ERRCODE_OFFSET(WRNGPID)] = "Wrong pid in netlink message",
44 [ERRCODE_OFFSET(INVSEQ)] = "Invalid netlink sequence",
45};
46
47int libbpf_strerror(int err, char *buf, size_t size)
48{
49 if (!buf || !size)
50 return -1;
51
52 err = err > 0 ? err : -err;
53
54 if (err < __LIBBPF_ERRNO__START) {
55 int ret;
56
57 ret = strerror_r(err, buf, size);
58 buf[size - 1] = '\0';
59 return ret;
60 }
61
62 if (err < __LIBBPF_ERRNO__END) {
63 const char *msg;
64
65 msg = libbpf_strerror_table[ERRNO_OFFSET(err)];
66 snprintf(buf, size, "%s", msg);
67 buf[size - 1] = '\0';
68 return 0;
69 }
70
71 snprintf(buf, size, "Unknown libbpf error %d", err);
72 buf[size - 1] = '\0';
73 return -1;
74}
diff --git a/tools/memory-model/Documentation/explanation.txt b/tools/memory-model/Documentation/explanation.txt
index 1b09f3175a1f..0cbd1ef8f86d 100644
--- a/tools/memory-model/Documentation/explanation.txt
+++ b/tools/memory-model/Documentation/explanation.txt
@@ -804,7 +804,7 @@ type of fence:
804Second, some types of fence affect the way the memory subsystem 804Second, some types of fence affect the way the memory subsystem
805propagates stores. When a fence instruction is executed on CPU C: 805propagates stores. When a fence instruction is executed on CPU C:
806 806
807 For each other CPU C', smb_wmb() forces all po-earlier stores 807 For each other CPU C', smp_wmb() forces all po-earlier stores
808 on C to propagate to C' before any po-later stores do. 808 on C to propagate to C' before any po-later stores do.
809 809
810 For each other CPU C', any store which propagates to C before 810 For each other CPU C', any store which propagates to C before
diff --git a/tools/memory-model/Documentation/recipes.txt b/tools/memory-model/Documentation/recipes.txt
index ee4309a87fc4..af72700cc20a 100644
--- a/tools/memory-model/Documentation/recipes.txt
+++ b/tools/memory-model/Documentation/recipes.txt
@@ -126,7 +126,7 @@ However, it is not necessarily the case that accesses ordered by
126locking will be seen as ordered by CPUs not holding that lock. 126locking will be seen as ordered by CPUs not holding that lock.
127Consider this example: 127Consider this example:
128 128
129 /* See Z6.0+pooncelock+pooncelock+pombonce.litmus. */ 129 /* See Z6.0+pooncerelease+poacquirerelease+fencembonceonce.litmus. */
130 void CPU0(void) 130 void CPU0(void)
131 { 131 {
132 spin_lock(&mylock); 132 spin_lock(&mylock);
@@ -292,7 +292,7 @@ and to use smp_load_acquire() instead of smp_rmb(). However, the older
292smp_wmb() and smp_rmb() APIs are still heavily used, so it is important 292smp_wmb() and smp_rmb() APIs are still heavily used, so it is important
293to understand their use cases. The general approach is shown below: 293to understand their use cases. The general approach is shown below:
294 294
295 /* See MP+wmbonceonce+rmbonceonce.litmus. */ 295 /* See MP+fencewmbonceonce+fencermbonceonce.litmus. */
296 void CPU0(void) 296 void CPU0(void)
297 { 297 {
298 WRITE_ONCE(x, 1); 298 WRITE_ONCE(x, 1);
@@ -322,9 +322,9 @@ the following write-side code fragment:
322And the xlog_valid_lsn() function in fs/xfs/xfs_log_priv.h contains 322And the xlog_valid_lsn() function in fs/xfs/xfs_log_priv.h contains
323the corresponding read-side code fragment: 323the corresponding read-side code fragment:
324 324
325 cur_cycle = ACCESS_ONCE(log->l_curr_cycle); 325 cur_cycle = READ_ONCE(log->l_curr_cycle);
326 smp_rmb(); 326 smp_rmb();
327 cur_block = ACCESS_ONCE(log->l_curr_block); 327 cur_block = READ_ONCE(log->l_curr_block);
328 328
329Alternatively, consider the following comment in function 329Alternatively, consider the following comment in function
330perf_output_put_handle() in kernel/events/ring_buffer.c: 330perf_output_put_handle() in kernel/events/ring_buffer.c:
@@ -360,7 +360,7 @@ can be seen in the LB+poonceonces.litmus litmus test.
360One way of avoiding the counter-intuitive outcome is through the use of a 360One way of avoiding the counter-intuitive outcome is through the use of a
361control dependency paired with a full memory barrier: 361control dependency paired with a full memory barrier:
362 362
363 /* See LB+ctrlonceonce+mbonceonce.litmus. */ 363 /* See LB+fencembonceonce+ctrlonceonce.litmus. */
364 void CPU0(void) 364 void CPU0(void)
365 { 365 {
366 r0 = READ_ONCE(x); 366 r0 = READ_ONCE(x);
@@ -476,7 +476,7 @@ that one CPU first stores to one variable and then loads from a second,
476while another CPU stores to the second variable and then loads from the 476while another CPU stores to the second variable and then loads from the
477first. Preserving order requires nothing less than full barriers: 477first. Preserving order requires nothing less than full barriers:
478 478
479 /* See SB+mbonceonces.litmus. */ 479 /* See SB+fencembonceonces.litmus. */
480 void CPU0(void) 480 void CPU0(void)
481 { 481 {
482 WRITE_ONCE(x, 1); 482 WRITE_ONCE(x, 1);
diff --git a/tools/memory-model/README b/tools/memory-model/README
index 734f7feaa5dc..ee987ce20aae 100644
--- a/tools/memory-model/README
+++ b/tools/memory-model/README
@@ -35,13 +35,13 @@ BASIC USAGE: HERD7
35The memory model is used, in conjunction with "herd7", to exhaustively 35The memory model is used, in conjunction with "herd7", to exhaustively
36explore the state space of small litmus tests. 36explore the state space of small litmus tests.
37 37
38For example, to run SB+mbonceonces.litmus against the memory model: 38For example, to run SB+fencembonceonces.litmus against the memory model:
39 39
40 $ herd7 -conf linux-kernel.cfg litmus-tests/SB+mbonceonces.litmus 40 $ herd7 -conf linux-kernel.cfg litmus-tests/SB+fencembonceonces.litmus
41 41
42Here is the corresponding output: 42Here is the corresponding output:
43 43
44 Test SB+mbonceonces Allowed 44 Test SB+fencembonceonces Allowed
45 States 3 45 States 3
46 0:r0=0; 1:r0=1; 46 0:r0=0; 1:r0=1;
47 0:r0=1; 1:r0=0; 47 0:r0=1; 1:r0=0;
@@ -50,8 +50,8 @@ Here is the corresponding output:
50 Witnesses 50 Witnesses
51 Positive: 0 Negative: 3 51 Positive: 0 Negative: 3
52 Condition exists (0:r0=0 /\ 1:r0=0) 52 Condition exists (0:r0=0 /\ 1:r0=0)
53 Observation SB+mbonceonces Never 0 3 53 Observation SB+fencembonceonces Never 0 3
54 Time SB+mbonceonces 0.01 54 Time SB+fencembonceonces 0.01
55 Hash=d66d99523e2cac6b06e66f4c995ebb48 55 Hash=d66d99523e2cac6b06e66f4c995ebb48
56 56
57The "Positive: 0 Negative: 3" and the "Never 0 3" each indicate that 57The "Positive: 0 Negative: 3" and the "Never 0 3" each indicate that
@@ -67,16 +67,16 @@ BASIC USAGE: KLITMUS7
67The "klitmus7" tool converts a litmus test into a Linux kernel module, 67The "klitmus7" tool converts a litmus test into a Linux kernel module,
68which may then be loaded and run. 68which may then be loaded and run.
69 69
70For example, to run SB+mbonceonces.litmus against hardware: 70For example, to run SB+fencembonceonces.litmus against hardware:
71 71
72 $ mkdir mymodules 72 $ mkdir mymodules
73 $ klitmus7 -o mymodules litmus-tests/SB+mbonceonces.litmus 73 $ klitmus7 -o mymodules litmus-tests/SB+fencembonceonces.litmus
74 $ cd mymodules ; make 74 $ cd mymodules ; make
75 $ sudo sh run.sh 75 $ sudo sh run.sh
76 76
77The corresponding output includes: 77The corresponding output includes:
78 78
79 Test SB+mbonceonces Allowed 79 Test SB+fencembonceonces Allowed
80 Histogram (3 states) 80 Histogram (3 states)
81 644580 :>0:r0=1; 1:r0=0; 81 644580 :>0:r0=1; 1:r0=0;
82 644328 :>0:r0=0; 1:r0=1; 82 644328 :>0:r0=0; 1:r0=1;
@@ -86,8 +86,8 @@ The corresponding output includes:
86 Positive: 0, Negative: 2000000 86 Positive: 0, Negative: 2000000
87 Condition exists (0:r0=0 /\ 1:r0=0) is NOT validated 87 Condition exists (0:r0=0 /\ 1:r0=0) is NOT validated
88 Hash=d66d99523e2cac6b06e66f4c995ebb48 88 Hash=d66d99523e2cac6b06e66f4c995ebb48
89 Observation SB+mbonceonces Never 0 2000000 89 Observation SB+fencembonceonces Never 0 2000000
90 Time SB+mbonceonces 0.16 90 Time SB+fencembonceonces 0.16
91 91
92The "Positive: 0 Negative: 2000000" and the "Never 0 2000000" indicate 92The "Positive: 0 Negative: 2000000" and the "Never 0 2000000" indicate
93that during two million trials, the state specified in this litmus 93that during two million trials, the state specified in this litmus
diff --git a/tools/memory-model/linux-kernel.bell b/tools/memory-model/linux-kernel.bell
index 64f5740e0e75..b84fb2f67109 100644
--- a/tools/memory-model/linux-kernel.bell
+++ b/tools/memory-model/linux-kernel.bell
@@ -13,7 +13,7 @@
13 13
14"Linux-kernel memory consistency model" 14"Linux-kernel memory consistency model"
15 15
16enum Accesses = 'once (*READ_ONCE,WRITE_ONCE,ACCESS_ONCE*) || 16enum Accesses = 'once (*READ_ONCE,WRITE_ONCE*) ||
17 'release (*smp_store_release*) || 17 'release (*smp_store_release*) ||
18 'acquire (*smp_load_acquire*) || 18 'acquire (*smp_load_acquire*) ||
19 'noreturn (* R of non-return RMW *) 19 'noreturn (* R of non-return RMW *)
diff --git a/tools/memory-model/litmus-tests/IRIW+mbonceonces+OnceOnce.litmus b/tools/memory-model/litmus-tests/IRIW+fencembonceonces+OnceOnce.litmus
index 98a3716efa37..e729d2776e89 100644
--- a/tools/memory-model/litmus-tests/IRIW+mbonceonces+OnceOnce.litmus
+++ b/tools/memory-model/litmus-tests/IRIW+fencembonceonces+OnceOnce.litmus
@@ -1,4 +1,4 @@
1C IRIW+mbonceonces+OnceOnce 1C IRIW+fencembonceonces+OnceOnce
2 2
3(* 3(*
4 * Result: Never 4 * Result: Never
diff --git a/tools/memory-model/litmus-tests/ISA2+pooncelock+pooncelock+pombonce.litmus b/tools/memory-model/litmus-tests/ISA2+pooncelock+pooncelock+pombonce.litmus
index 7a39a0aaa976..0f749e419b34 100644
--- a/tools/memory-model/litmus-tests/ISA2+pooncelock+pooncelock+pombonce.litmus
+++ b/tools/memory-model/litmus-tests/ISA2+pooncelock+pooncelock+pombonce.litmus
@@ -1,4 +1,4 @@
1C ISA2+pooncelock+pooncelock+pombonce.litmus 1C ISA2+pooncelock+pooncelock+pombonce
2 2
3(* 3(*
4 * Result: Sometimes 4 * Result: Sometimes
diff --git a/tools/memory-model/litmus-tests/LB+ctrlonceonce+mbonceonce.litmus b/tools/memory-model/litmus-tests/LB+fencembonceonce+ctrlonceonce.litmus
index de6708229dd1..4727f5aaf03b 100644
--- a/tools/memory-model/litmus-tests/LB+ctrlonceonce+mbonceonce.litmus
+++ b/tools/memory-model/litmus-tests/LB+fencembonceonce+ctrlonceonce.litmus
@@ -1,4 +1,4 @@
1C LB+ctrlonceonce+mbonceonce 1C LB+fencembonceonce+ctrlonceonce
2 2
3(* 3(*
4 * Result: Never 4 * Result: Never
diff --git a/tools/memory-model/litmus-tests/MP+wmbonceonce+rmbonceonce.litmus b/tools/memory-model/litmus-tests/MP+fencewmbonceonce+fencermbonceonce.litmus
index c078f38ff27a..a273da9faa6d 100644
--- a/tools/memory-model/litmus-tests/MP+wmbonceonce+rmbonceonce.litmus
+++ b/tools/memory-model/litmus-tests/MP+fencewmbonceonce+fencermbonceonce.litmus
@@ -1,4 +1,4 @@
1C MP+wmbonceonce+rmbonceonce 1C MP+fencewmbonceonce+fencermbonceonce
2 2
3(* 3(*
4 * Result: Never 4 * Result: Never
diff --git a/tools/memory-model/litmus-tests/R+mbonceonces.litmus b/tools/memory-model/litmus-tests/R+fencembonceonces.litmus
index a0e884ad2132..222a0b850b4a 100644
--- a/tools/memory-model/litmus-tests/R+mbonceonces.litmus
+++ b/tools/memory-model/litmus-tests/R+fencembonceonces.litmus
@@ -1,4 +1,4 @@
1C R+mbonceonces 1C R+fencembonceonces
2 2
3(* 3(*
4 * Result: Never 4 * Result: Never
diff --git a/tools/memory-model/litmus-tests/README b/tools/memory-model/litmus-tests/README
index 17eb9a8c222d..4581ec2d3c57 100644
--- a/tools/memory-model/litmus-tests/README
+++ b/tools/memory-model/litmus-tests/README
@@ -18,7 +18,7 @@ CoWW+poonceonce.litmus
18 Test of write-write coherence, that is, whether or not two 18 Test of write-write coherence, that is, whether or not two
19 successive writes to the same variable are ordered. 19 successive writes to the same variable are ordered.
20 20
21IRIW+mbonceonces+OnceOnce.litmus 21IRIW+fencembonceonces+OnceOnce.litmus
22 Test of independent reads from independent writes with smp_mb() 22 Test of independent reads from independent writes with smp_mb()
23 between each pairs of reads. In other words, is smp_mb() 23 between each pairs of reads. In other words, is smp_mb()
24 sufficient to cause two different reading processes to agree on 24 sufficient to cause two different reading processes to agree on
@@ -47,7 +47,7 @@ ISA2+pooncerelease+poacquirerelease+poacquireonce.litmus
47 Can a release-acquire chain order a prior store against 47 Can a release-acquire chain order a prior store against
48 a later load? 48 a later load?
49 49
50LB+ctrlonceonce+mbonceonce.litmus 50LB+fencembonceonce+ctrlonceonce.litmus
51 Does a control dependency and an smp_mb() suffice for the 51 Does a control dependency and an smp_mb() suffice for the
52 load-buffering litmus test, where each process reads from one 52 load-buffering litmus test, where each process reads from one
53 of two variables then writes to the other? 53 of two variables then writes to the other?
@@ -88,14 +88,14 @@ MP+porevlocks.litmus
88 As below, but with the first access of the writer process 88 As below, but with the first access of the writer process
89 and the second access of reader process protected by a lock. 89 and the second access of reader process protected by a lock.
90 90
91MP+wmbonceonce+rmbonceonce.litmus 91MP+fencewmbonceonce+fencermbonceonce.litmus
92 Does a smp_wmb() (between the stores) and an smp_rmb() (between 92 Does a smp_wmb() (between the stores) and an smp_rmb() (between
93 the loads) suffice for the message-passing litmus test, where one 93 the loads) suffice for the message-passing litmus test, where one
94 process writes data and then a flag, and the other process reads 94 process writes data and then a flag, and the other process reads
95 the flag and then the data. (This is similar to the ISA2 tests, 95 the flag and then the data. (This is similar to the ISA2 tests,
96 but with two processes instead of three.) 96 but with two processes instead of three.)
97 97
98R+mbonceonces.litmus 98R+fencembonceonces.litmus
99 This is the fully ordered (via smp_mb()) version of one of 99 This is the fully ordered (via smp_mb()) version of one of
100 the classic counterintuitive litmus tests that illustrates the 100 the classic counterintuitive litmus tests that illustrates the
101 effects of store propagation delays. 101 effects of store propagation delays.
@@ -103,7 +103,7 @@ R+mbonceonces.litmus
103R+poonceonces.litmus 103R+poonceonces.litmus
104 As above, but without the smp_mb() invocations. 104 As above, but without the smp_mb() invocations.
105 105
106SB+mbonceonces.litmus 106SB+fencembonceonces.litmus
107 This is the fully ordered (again, via smp_mb() version of store 107 This is the fully ordered (again, via smp_mb() version of store
108 buffering, which forms the core of Dekker's mutual-exclusion 108 buffering, which forms the core of Dekker's mutual-exclusion
109 algorithm. 109 algorithm.
@@ -111,15 +111,24 @@ SB+mbonceonces.litmus
111SB+poonceonces.litmus 111SB+poonceonces.litmus
112 As above, but without the smp_mb() invocations. 112 As above, but without the smp_mb() invocations.
113 113
114SB+rfionceonce-poonceonces.litmus
115 This litmus test demonstrates that LKMM is not fully multicopy
116 atomic. (Neither is it other multicopy atomic.) This litmus test
117 also demonstrates the "locations" debugging aid, which designates
118 additional registers and locations to be printed out in the dump
119 of final states in the herd7 output. Without the "locations"
120 statement, only those registers and locations mentioned in the
121 "exists" clause will be printed.
122
114S+poonceonces.litmus 123S+poonceonces.litmus
115 As below, but without the smp_wmb() and acquire load. 124 As below, but without the smp_wmb() and acquire load.
116 125
117S+wmbonceonce+poacquireonce.litmus 126S+fencewmbonceonce+poacquireonce.litmus
118 Can a smp_wmb(), instead of a release, and an acquire order 127 Can a smp_wmb(), instead of a release, and an acquire order
119 a prior store against a subsequent store? 128 a prior store against a subsequent store?
120 129
121WRC+poonceonces+Once.litmus 130WRC+poonceonces+Once.litmus
122WRC+pooncerelease+rmbonceonce+Once.litmus 131WRC+pooncerelease+fencermbonceonce+Once.litmus
123 These two are members of an extension of the MP litmus-test 132 These two are members of an extension of the MP litmus-test
124 class in which the first write is moved to a separate process. 133 class in which the first write is moved to a separate process.
125 The second is forbidden because smp_store_release() is 134 The second is forbidden because smp_store_release() is
@@ -134,7 +143,7 @@ Z6.0+pooncelock+poonceLock+pombonce.litmus
134 As above, but with smp_mb__after_spinlock() immediately 143 As above, but with smp_mb__after_spinlock() immediately
135 following the spin_lock(). 144 following the spin_lock().
136 145
137Z6.0+pooncerelease+poacquirerelease+mbonceonce.litmus 146Z6.0+pooncerelease+poacquirerelease+fencembonceonce.litmus
138 Is the ordering provided by a release-acquire chain sufficient 147 Is the ordering provided by a release-acquire chain sufficient
139 to make ordering apparent to accesses by a process that does 148 to make ordering apparent to accesses by a process that does
140 not participate in that release-acquire chain? 149 not participate in that release-acquire chain?
diff --git a/tools/memory-model/litmus-tests/S+wmbonceonce+poacquireonce.litmus b/tools/memory-model/litmus-tests/S+fencewmbonceonce+poacquireonce.litmus
index c53350205d28..18479823cd6c 100644
--- a/tools/memory-model/litmus-tests/S+wmbonceonce+poacquireonce.litmus
+++ b/tools/memory-model/litmus-tests/S+fencewmbonceonce+poacquireonce.litmus
@@ -1,4 +1,4 @@
1C S+wmbonceonce+poacquireonce 1C S+fencewmbonceonce+poacquireonce
2 2
3(* 3(*
4 * Result: Never 4 * Result: Never
diff --git a/tools/memory-model/litmus-tests/SB+mbonceonces.litmus b/tools/memory-model/litmus-tests/SB+fencembonceonces.litmus
index 74b874ffa8da..ed5fff18d223 100644
--- a/tools/memory-model/litmus-tests/SB+mbonceonces.litmus
+++ b/tools/memory-model/litmus-tests/SB+fencembonceonces.litmus
@@ -1,4 +1,4 @@
1C SB+mbonceonces 1C SB+fencembonceonces
2 2
3(* 3(*
4 * Result: Never 4 * Result: Never
diff --git a/tools/memory-model/litmus-tests/SB+rfionceonce-poonceonces.litmus b/tools/memory-model/litmus-tests/SB+rfionceonce-poonceonces.litmus
new file mode 100644
index 000000000000..04a16603660b
--- /dev/null
+++ b/tools/memory-model/litmus-tests/SB+rfionceonce-poonceonces.litmus
@@ -0,0 +1,32 @@
1C SB+rfionceonce-poonceonces
2
3(*
4 * Result: Sometimes
5 *
6 * This litmus test demonstrates that LKMM is not fully multicopy atomic.
7 *)
8
9{}
10
11P0(int *x, int *y)
12{
13 int r1;
14 int r2;
15
16 WRITE_ONCE(*x, 1);
17 r1 = READ_ONCE(*x);
18 r2 = READ_ONCE(*y);
19}
20
21P1(int *x, int *y)
22{
23 int r3;
24 int r4;
25
26 WRITE_ONCE(*y, 1);
27 r3 = READ_ONCE(*y);
28 r4 = READ_ONCE(*x);
29}
30
31locations [0:r1; 1:r3; x; y] (* Debug aid: Print things not in "exists". *)
32exists (0:r2=0 /\ 1:r4=0)
diff --git a/tools/memory-model/litmus-tests/WRC+pooncerelease+rmbonceonce+Once.litmus b/tools/memory-model/litmus-tests/WRC+pooncerelease+fencermbonceonce+Once.litmus
index ad3448b941e6..e9947250d7de 100644
--- a/tools/memory-model/litmus-tests/WRC+pooncerelease+rmbonceonce+Once.litmus
+++ b/tools/memory-model/litmus-tests/WRC+pooncerelease+fencermbonceonce+Once.litmus
@@ -1,4 +1,4 @@
1C WRC+pooncerelease+rmbonceonce+Once 1C WRC+pooncerelease+fencermbonceonce+Once
2 2
3(* 3(*
4 * Result: Never 4 * Result: Never
diff --git a/tools/memory-model/litmus-tests/Z6.0+pooncerelease+poacquirerelease+mbonceonce.litmus b/tools/memory-model/litmus-tests/Z6.0+pooncerelease+poacquirerelease+fencembonceonce.litmus
index a20fc3fafb53..88e70b87a683 100644
--- a/tools/memory-model/litmus-tests/Z6.0+pooncerelease+poacquirerelease+mbonceonce.litmus
+++ b/tools/memory-model/litmus-tests/Z6.0+pooncerelease+poacquirerelease+fencembonceonce.litmus
@@ -1,4 +1,4 @@
1C Z6.0+pooncerelease+poacquirerelease+mbonceonce 1C Z6.0+pooncerelease+poacquirerelease+fencembonceonce
2 2
3(* 3(*
4 * Result: Sometimes 4 * Result: Sometimes
diff --git a/tools/memory-model/scripts/checkalllitmus.sh b/tools/memory-model/scripts/checkalllitmus.sh
index af0aa15ab84e..ca528f9a24d4 100644..100755
--- a/tools/memory-model/scripts/checkalllitmus.sh
+++ b/tools/memory-model/scripts/checkalllitmus.sh
@@ -9,7 +9,7 @@
9# appended. 9# appended.
10# 10#
11# Usage: 11# Usage:
12# sh checkalllitmus.sh [ directory ] 12# checkalllitmus.sh [ directory ]
13# 13#
14# The LINUX_HERD_OPTIONS environment variable may be used to specify 14# The LINUX_HERD_OPTIONS environment variable may be used to specify
15# arguments to herd, whose default is defined by the checklitmus.sh script. 15# arguments to herd, whose default is defined by the checklitmus.sh script.
diff --git a/tools/memory-model/scripts/checklitmus.sh b/tools/memory-model/scripts/checklitmus.sh
index e2e477472844..bf12a75c0719 100644..100755
--- a/tools/memory-model/scripts/checklitmus.sh
+++ b/tools/memory-model/scripts/checklitmus.sh
@@ -8,7 +8,7 @@
8# with ".out" appended. 8# with ".out" appended.
9# 9#
10# Usage: 10# Usage:
11# sh checklitmus.sh file.litmus 11# checklitmus.sh file.litmus
12# 12#
13# The LINUX_HERD_OPTIONS environment variable may be used to specify 13# The LINUX_HERD_OPTIONS environment variable may be used to specify
14# arguments to herd, which default to "-conf linux-kernel.cfg". Thus, 14# arguments to herd, which default to "-conf linux-kernel.cfg". Thus,
diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
index f76d9914686a..c9d038f91af6 100644
--- a/tools/objtool/Makefile
+++ b/tools/objtool/Makefile
@@ -31,8 +31,8 @@ INCLUDES := -I$(srctree)/tools/include \
31 -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi \ 31 -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi \
32 -I$(srctree)/tools/objtool/arch/$(ARCH)/include 32 -I$(srctree)/tools/objtool/arch/$(ARCH)/include
33WARNINGS := $(EXTRA_WARNINGS) -Wno-switch-default -Wno-switch-enum -Wno-packed 33WARNINGS := $(EXTRA_WARNINGS) -Wno-switch-default -Wno-switch-enum -Wno-packed
34CFLAGS += -Werror $(WARNINGS) $(HOSTCFLAGS) -g $(INCLUDES) 34CFLAGS += -Werror $(WARNINGS) $(KBUILD_HOSTCFLAGS) -g $(INCLUDES)
35LDFLAGS += -lelf $(LIBSUBCMD) $(HOSTLDFLAGS) 35LDFLAGS += -lelf $(LIBSUBCMD) $(KBUILD_HOSTLDFLAGS)
36 36
37# Allow old libelf to be used: 37# Allow old libelf to be used:
38elfshdr := $(shell echo '$(pound)include <libelf.h>' | $(CC) $(CFLAGS) -x c -E - | grep elf_getshdr) 38elfshdr := $(shell echo '$(pound)include <libelf.h>' | $(CC) $(CFLAGS) -x c -E - | grep elf_getshdr)
diff --git a/tools/objtool/arch/x86/include/asm/orc_types.h b/tools/objtool/arch/x86/include/asm/orc_types.h
index 9c9dc579bd7d..46f516dd80ce 100644
--- a/tools/objtool/arch/x86/include/asm/orc_types.h
+++ b/tools/objtool/arch/x86/include/asm/orc_types.h
@@ -88,6 +88,7 @@ struct orc_entry {
88 unsigned sp_reg:4; 88 unsigned sp_reg:4;
89 unsigned bp_reg:4; 89 unsigned bp_reg:4;
90 unsigned type:2; 90 unsigned type:2;
91 unsigned end:1;
91} __packed; 92} __packed;
92 93
93/* 94/*
@@ -101,6 +102,7 @@ struct unwind_hint {
101 s16 sp_offset; 102 s16 sp_offset;
102 u8 sp_reg; 103 u8 sp_reg;
103 u8 type; 104 u8 type;
105 u8 end;
104}; 106};
105#endif /* __ASSEMBLY__ */ 107#endif /* __ASSEMBLY__ */
106 108
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index f4a25bd1871f..2928939b98ec 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1157,6 +1157,7 @@ static int read_unwind_hints(struct objtool_file *file)
1157 1157
1158 cfa->offset = hint->sp_offset; 1158 cfa->offset = hint->sp_offset;
1159 insn->state.type = hint->type; 1159 insn->state.type = hint->type;
1160 insn->state.end = hint->end;
1160 } 1161 }
1161 1162
1162 return 0; 1163 return 0;
diff --git a/tools/objtool/check.h b/tools/objtool/check.h
index c6b68fcb926f..95700a2bcb7c 100644
--- a/tools/objtool/check.h
+++ b/tools/objtool/check.h
@@ -31,7 +31,7 @@ struct insn_state {
31 int stack_size; 31 int stack_size;
32 unsigned char type; 32 unsigned char type;
33 bool bp_scratch; 33 bool bp_scratch;
34 bool drap; 34 bool drap, end;
35 int drap_reg, drap_offset; 35 int drap_reg, drap_offset;
36 struct cfi_reg vals[CFI_NUM_REGS]; 36 struct cfi_reg vals[CFI_NUM_REGS];
37}; 37};
diff --git a/tools/objtool/orc_dump.c b/tools/objtool/orc_dump.c
index c3343820916a..faa444270ee3 100644
--- a/tools/objtool/orc_dump.c
+++ b/tools/objtool/orc_dump.c
@@ -203,7 +203,8 @@ int orc_dump(const char *_objname)
203 203
204 print_reg(orc[i].bp_reg, orc[i].bp_offset); 204 print_reg(orc[i].bp_reg, orc[i].bp_offset);
205 205
206 printf(" type:%s\n", orc_type_name(orc[i].type)); 206 printf(" type:%s end:%d\n",
207 orc_type_name(orc[i].type), orc[i].end);
207 } 208 }
208 209
209 elf_end(elf); 210 elf_end(elf);
diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c
index 18384d9be4e1..3f98dcfbc177 100644
--- a/tools/objtool/orc_gen.c
+++ b/tools/objtool/orc_gen.c
@@ -31,6 +31,8 @@ int create_orc(struct objtool_file *file)
31 struct cfi_reg *cfa = &insn->state.cfa; 31 struct cfi_reg *cfa = &insn->state.cfa;
32 struct cfi_reg *bp = &insn->state.regs[CFI_BP]; 32 struct cfi_reg *bp = &insn->state.regs[CFI_BP];
33 33
34 orc->end = insn->state.end;
35
34 if (cfa->base == CFI_UNDEFINED) { 36 if (cfa->base == CFI_UNDEFINED) {
35 orc->sp_reg = ORC_REG_UNDEFINED; 37 orc->sp_reg = ORC_REG_UNDEFINED;
36 continue; 38 continue;
diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c
index 9074b477bff0..af146bb03b4d 100644
--- a/tools/pci/pcitest.c
+++ b/tools/pci/pcitest.c
@@ -31,12 +31,17 @@
31#define BILLION 1E9 31#define BILLION 1E9
32 32
33static char *result[] = { "NOT OKAY", "OKAY" }; 33static char *result[] = { "NOT OKAY", "OKAY" };
34static char *irq[] = { "LEGACY", "MSI", "MSI-X" };
34 35
35struct pci_test { 36struct pci_test {
36 char *device; 37 char *device;
37 char barnum; 38 char barnum;
38 bool legacyirq; 39 bool legacyirq;
39 unsigned int msinum; 40 unsigned int msinum;
41 unsigned int msixnum;
42 int irqtype;
43 bool set_irqtype;
44 bool get_irqtype;
40 bool read; 45 bool read;
41 bool write; 46 bool write;
42 bool copy; 47 bool copy;
@@ -65,6 +70,24 @@ static int run_test(struct pci_test *test)
65 fprintf(stdout, "%s\n", result[ret]); 70 fprintf(stdout, "%s\n", result[ret]);
66 } 71 }
67 72
73 if (test->set_irqtype) {
74 ret = ioctl(fd, PCITEST_SET_IRQTYPE, test->irqtype);
75 fprintf(stdout, "SET IRQ TYPE TO %s:\t\t", irq[test->irqtype]);
76 if (ret < 0)
77 fprintf(stdout, "FAILED\n");
78 else
79 fprintf(stdout, "%s\n", result[ret]);
80 }
81
82 if (test->get_irqtype) {
83 ret = ioctl(fd, PCITEST_GET_IRQTYPE);
84 fprintf(stdout, "GET IRQ TYPE:\t\t");
85 if (ret < 0)
86 fprintf(stdout, "FAILED\n");
87 else
88 fprintf(stdout, "%s\n", irq[ret]);
89 }
90
68 if (test->legacyirq) { 91 if (test->legacyirq) {
69 ret = ioctl(fd, PCITEST_LEGACY_IRQ, 0); 92 ret = ioctl(fd, PCITEST_LEGACY_IRQ, 0);
70 fprintf(stdout, "LEGACY IRQ:\t"); 93 fprintf(stdout, "LEGACY IRQ:\t");
@@ -83,6 +106,15 @@ static int run_test(struct pci_test *test)
83 fprintf(stdout, "%s\n", result[ret]); 106 fprintf(stdout, "%s\n", result[ret]);
84 } 107 }
85 108
109 if (test->msixnum > 0 && test->msixnum <= 2048) {
110 ret = ioctl(fd, PCITEST_MSIX, test->msixnum);
111 fprintf(stdout, "MSI-X%d:\t\t", test->msixnum);
112 if (ret < 0)
113 fprintf(stdout, "TEST FAILED\n");
114 else
115 fprintf(stdout, "%s\n", result[ret]);
116 }
117
86 if (test->write) { 118 if (test->write) {
87 ret = ioctl(fd, PCITEST_WRITE, test->size); 119 ret = ioctl(fd, PCITEST_WRITE, test->size);
88 fprintf(stdout, "WRITE (%7ld bytes):\t\t", test->size); 120 fprintf(stdout, "WRITE (%7ld bytes):\t\t", test->size);
@@ -133,7 +165,7 @@ int main(int argc, char **argv)
133 /* set default endpoint device */ 165 /* set default endpoint device */
134 test->device = "/dev/pci-endpoint-test.0"; 166 test->device = "/dev/pci-endpoint-test.0";
135 167
136 while ((c = getopt(argc, argv, "D:b:m:lrwcs:")) != EOF) 168 while ((c = getopt(argc, argv, "D:b:m:x:i:Ilrwcs:")) != EOF)
137 switch (c) { 169 switch (c) {
138 case 'D': 170 case 'D':
139 test->device = optarg; 171 test->device = optarg;
@@ -151,6 +183,20 @@ int main(int argc, char **argv)
151 if (test->msinum < 1 || test->msinum > 32) 183 if (test->msinum < 1 || test->msinum > 32)
152 goto usage; 184 goto usage;
153 continue; 185 continue;
186 case 'x':
187 test->msixnum = atoi(optarg);
188 if (test->msixnum < 1 || test->msixnum > 2048)
189 goto usage;
190 continue;
191 case 'i':
192 test->irqtype = atoi(optarg);
193 if (test->irqtype < 0 || test->irqtype > 2)
194 goto usage;
195 test->set_irqtype = true;
196 continue;
197 case 'I':
198 test->get_irqtype = true;
199 continue;
154 case 'r': 200 case 'r':
155 test->read = true; 201 test->read = true;
156 continue; 202 continue;
@@ -173,6 +219,9 @@ usage:
173 "\t-D <dev> PCI endpoint test device {default: /dev/pci-endpoint-test.0}\n" 219 "\t-D <dev> PCI endpoint test device {default: /dev/pci-endpoint-test.0}\n"
174 "\t-b <bar num> BAR test (bar number between 0..5)\n" 220 "\t-b <bar num> BAR test (bar number between 0..5)\n"
175 "\t-m <msi num> MSI test (msi number between 1..32)\n" 221 "\t-m <msi num> MSI test (msi number between 1..32)\n"
222 "\t-x <msix num> \tMSI-X test (msix number between 1..2048)\n"
223 "\t-i <irq type> \tSet IRQ type (0 - Legacy, 1 - MSI, 2 - MSI-X)\n"
224 "\t-I Get current IRQ type configured\n"
176 "\t-l Legacy IRQ test\n" 225 "\t-l Legacy IRQ test\n"
177 "\t-r Read buffer test\n" 226 "\t-r Read buffer test\n"
178 "\t-w Write buffer test\n" 227 "\t-w Write buffer test\n"
diff --git a/tools/pci/pcitest.sh b/tools/pci/pcitest.sh
index 77e8c85ef744..75ed48ff2990 100644
--- a/tools/pci/pcitest.sh
+++ b/tools/pci/pcitest.sh
@@ -16,7 +16,10 @@ echo
16echo "Interrupt tests" 16echo "Interrupt tests"
17echo 17echo
18 18
19pcitest -i 0
19pcitest -l 20pcitest -l
21
22pcitest -i 1
20msi=1 23msi=1
21 24
22while [ $msi -lt 33 ] 25while [ $msi -lt 33 ]
@@ -26,9 +29,21 @@ do
26done 29done
27echo 30echo
28 31
32pcitest -i 2
33msix=1
34
35while [ $msix -lt 2049 ]
36do
37 pcitest -x $msix
38 msix=`expr $msix + 1`
39done
40echo
41
29echo "Read Tests" 42echo "Read Tests"
30echo 43echo
31 44
45pcitest -i 1
46
32pcitest -r -s 1 47pcitest -r -s 1
33pcitest -r -s 1024 48pcitest -r -s 1024
34pcitest -r -s 1025 49pcitest -r -s 1025
diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
index 11300dbe35c5..236b9b97dfdb 100644
--- a/tools/perf/Documentation/perf-list.txt
+++ b/tools/perf/Documentation/perf-list.txt
@@ -18,6 +18,10 @@ various perf commands with the -e option.
18 18
19OPTIONS 19OPTIONS
20------- 20-------
21-d::
22--desc::
23Print extra event descriptions. (default)
24
21--no-desc:: 25--no-desc::
22Don't print descriptions. 26Don't print descriptions.
23 27
@@ -25,11 +29,13 @@ Don't print descriptions.
25--long-desc:: 29--long-desc::
26Print longer event descriptions. 30Print longer event descriptions.
27 31
32--debug::
33Enable debugging output.
34
28--details:: 35--details::
29Print how named events are resolved internally into perf events, and also 36Print how named events are resolved internally into perf events, and also
30any extra expressions computed by perf stat. 37any extra expressions computed by perf stat.
31 38
32
33[[EVENT_MODIFIERS]] 39[[EVENT_MODIFIERS]]
34EVENT MODIFIERS 40EVENT MODIFIERS
35--------------- 41---------------
@@ -234,7 +240,7 @@ perf also supports group leader sampling using the :S specifier.
234 perf record -e '{cycles,instructions}:S' ... 240 perf record -e '{cycles,instructions}:S' ...
235 perf report --group 241 perf report --group
236 242
237Normally all events in a event group sample, but with :S only 243Normally all events in an event group sample, but with :S only
238the first event (the leader) samples, and it only reads the values of the 244the first event (the leader) samples, and it only reads the values of the
239other events in the group. 245other events in the group.
240 246
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 04168da4268e..246dee081efd 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -94,7 +94,7 @@ OPTIONS
94 "perf report" to view group events together. 94 "perf report" to view group events together.
95 95
96--filter=<filter>:: 96--filter=<filter>::
97 Event filter. This option should follow a event selector (-e) which 97 Event filter. This option should follow an event selector (-e) which
98 selects either tracepoint event(s) or a hardware trace PMU 98 selects either tracepoint event(s) or a hardware trace PMU
99 (e.g. Intel PT or CoreSight). 99 (e.g. Intel PT or CoreSight).
100 100
@@ -153,7 +153,7 @@ OPTIONS
153 153
154--exclude-perf:: 154--exclude-perf::
155 Don't record events issued by perf itself. This option should follow 155 Don't record events issued by perf itself. This option should follow
156 a event selector (-e) which selects tracepoint event(s). It adds a 156 an event selector (-e) which selects tracepoint event(s). It adds a
157 filter expression 'common_pid != $PERFPID' to filters. If other 157 filter expression 'common_pid != $PERFPID' to filters. If other
158 '--filter' exists, the new filter expression will be combined with 158 '--filter' exists, the new filter expression will be combined with
159 them by '&&'. 159 them by '&&'.
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index f5a3b402589e..f6d1a03c7523 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -54,6 +54,8 @@ endif
54 54
55ifeq ($(SRCARCH),arm64) 55ifeq ($(SRCARCH),arm64)
56 NO_PERF_REGS := 0 56 NO_PERF_REGS := 0
57 NO_SYSCALL_TABLE := 0
58 CFLAGS += -I$(OUTPUT)arch/arm64/include/generated
57 LIBUNWIND_LIBS = -lunwind -lunwind-aarch64 59 LIBUNWIND_LIBS = -lunwind -lunwind-aarch64
58endif 60endif
59 61
@@ -905,8 +907,8 @@ bindir = $(abspath $(prefix)/$(bindir_relative))
905mandir = share/man 907mandir = share/man
906infodir = share/info 908infodir = share/info
907perfexecdir = libexec/perf-core 909perfexecdir = libexec/perf-core
908perf_include_dir = lib/include/perf 910perf_include_dir = lib/perf/include
909perf_examples_dir = lib/examples/perf 911perf_examples_dir = lib/perf/examples
910sharedir = $(prefix)/share 912sharedir = $(prefix)/share
911template_dir = share/perf-core/templates 913template_dir = share/perf-core/templates
912STRACE_GROUPS_DIR = share/perf-core/strace/groups 914STRACE_GROUPS_DIR = share/perf-core/strace/groups
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index ecc9fc952655..b3d1b12a5081 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -384,6 +384,8 @@ export INSTALL SHELL_PATH
384 384
385SHELL = $(SHELL_PATH) 385SHELL = $(SHELL_PATH)
386 386
387linux_uapi_dir := $(srctree)/tools/include/uapi/linux
388
387beauty_outdir := $(OUTPUT)trace/beauty/generated 389beauty_outdir := $(OUTPUT)trace/beauty/generated
388beauty_ioctl_outdir := $(beauty_outdir)/ioctl 390beauty_ioctl_outdir := $(beauty_outdir)/ioctl
389drm_ioctl_array := $(beauty_ioctl_outdir)/drm_ioctl_array.c 391drm_ioctl_array := $(beauty_ioctl_outdir)/drm_ioctl_array.c
@@ -431,6 +433,12 @@ kvm_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/kvm_ioctl.sh
431$(kvm_ioctl_array): $(kvm_hdr_dir)/kvm.h $(kvm_ioctl_tbl) 433$(kvm_ioctl_array): $(kvm_hdr_dir)/kvm.h $(kvm_ioctl_tbl)
432 $(Q)$(SHELL) '$(kvm_ioctl_tbl)' $(kvm_hdr_dir) > $@ 434 $(Q)$(SHELL) '$(kvm_ioctl_tbl)' $(kvm_hdr_dir) > $@
433 435
436socket_ipproto_array := $(beauty_outdir)/socket_ipproto_array.c
437socket_ipproto_tbl := $(srctree)/tools/perf/trace/beauty/socket_ipproto.sh
438
439$(socket_ipproto_array): $(linux_uapi_dir)/in.h $(socket_ipproto_tbl)
440 $(Q)$(SHELL) '$(socket_ipproto_tbl)' $(linux_uapi_dir) > $@
441
434vhost_virtio_ioctl_array := $(beauty_ioctl_outdir)/vhost_virtio_ioctl_array.c 442vhost_virtio_ioctl_array := $(beauty_ioctl_outdir)/vhost_virtio_ioctl_array.c
435vhost_virtio_hdr_dir := $(srctree)/tools/include/uapi/linux 443vhost_virtio_hdr_dir := $(srctree)/tools/include/uapi/linux
436vhost_virtio_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/vhost_virtio_ioctl.sh 444vhost_virtio_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/vhost_virtio_ioctl.sh
@@ -566,6 +574,7 @@ prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(drm_ioc
566 $(sndrv_ctl_ioctl_array) \ 574 $(sndrv_ctl_ioctl_array) \
567 $(kcmp_type_array) \ 575 $(kcmp_type_array) \
568 $(kvm_ioctl_array) \ 576 $(kvm_ioctl_array) \
577 $(socket_ipproto_array) \
569 $(vhost_virtio_ioctl_array) \ 578 $(vhost_virtio_ioctl_array) \
570 $(madvise_behavior_array) \ 579 $(madvise_behavior_array) \
571 $(perf_ioctl_array) \ 580 $(perf_ioctl_array) \
@@ -860,6 +869,7 @@ clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clea
860 $(OUTPUT)$(sndrv_pcm_ioctl_array) \ 869 $(OUTPUT)$(sndrv_pcm_ioctl_array) \
861 $(OUTPUT)$(kvm_ioctl_array) \ 870 $(OUTPUT)$(kvm_ioctl_array) \
862 $(OUTPUT)$(kcmp_type_array) \ 871 $(OUTPUT)$(kcmp_type_array) \
872 $(OUTPUT)$(socket_ipproto_array) \
863 $(OUTPUT)$(vhost_virtio_ioctl_array) \ 873 $(OUTPUT)$(vhost_virtio_ioctl_array) \
864 $(OUTPUT)$(perf_ioctl_array) \ 874 $(OUTPUT)$(perf_ioctl_array) \
865 $(OUTPUT)$(prctl_option_array) \ 875 $(OUTPUT)$(prctl_option_array) \
diff --git a/tools/perf/arch/arm64/Makefile b/tools/perf/arch/arm64/Makefile
index 91de4860faad..f013b115dc86 100644
--- a/tools/perf/arch/arm64/Makefile
+++ b/tools/perf/arch/arm64/Makefile
@@ -4,3 +4,24 @@ PERF_HAVE_DWARF_REGS := 1
4endif 4endif
5PERF_HAVE_JITDUMP := 1 5PERF_HAVE_JITDUMP := 1
6PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1 6PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
7
8#
9# Syscall table generation for perf
10#
11
12out := $(OUTPUT)arch/arm64/include/generated/asm
13header := $(out)/syscalls.c
14sysdef := $(srctree)/tools/include/uapi/asm-generic/unistd.h
15sysprf := $(srctree)/tools/perf/arch/arm64/entry/syscalls/
16systbl := $(sysprf)/mksyscalltbl
17
18# Create output directory if not already present
19_dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)')
20
21$(header): $(sysdef) $(systbl)
22 $(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(sysdef) > $@
23
24clean::
25 $(call QUIET_CLEAN, arm64) $(RM) $(header)
26
27archheaders: $(header)
diff --git a/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl b/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl
new file mode 100755
index 000000000000..52e197317d3e
--- /dev/null
+++ b/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl
@@ -0,0 +1,62 @@
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3#
4# Generate system call table for perf. Derived from
5# powerpc script.
6#
7# Copyright IBM Corp. 2017
8# Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
9# Changed by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
10# Changed by: Kim Phillips <kim.phillips@arm.com>
11
12gcc=$1
13hostcc=$2
14input=$3
15
16if ! test -r $input; then
17 echo "Could not read input file" >&2
18 exit 1
19fi
20
21create_table_from_c()
22{
23 local sc nr last_sc
24
25 create_table_exe=`mktemp /tmp/create-table-XXXXXX`
26
27 {
28
29 cat <<-_EoHEADER
30 #include <stdio.h>
31 #define __ARCH_WANT_RENAMEAT
32 #include "$input"
33 int main(int argc, char *argv[])
34 {
35 _EoHEADER
36
37 while read sc nr; do
38 printf "%s\n" " printf(\"\\t[%d] = \\\"$sc\\\",\\n\", __NR_$sc);"
39 last_sc=$sc
40 done
41
42 printf "%s\n" " printf(\"#define SYSCALLTBL_ARM64_MAX_ID %d\\n\", __NR_$last_sc);"
43 printf "}\n"
44
45 } | $hostcc -o $create_table_exe -x c -
46
47 $create_table_exe
48
49 rm -f $create_table_exe
50}
51
52create_table()
53{
54 echo "static const char *syscalltbl_arm64[] = {"
55 create_table_from_c
56 echo "};"
57}
58
59$gcc -E -dM -x c $input \
60 |sed -ne 's/^#define __NR_//p' \
61 |sort -t' ' -k2 -nu \
62 |create_table
diff --git a/tools/perf/arch/powerpc/util/skip-callchain-idx.c b/tools/perf/arch/powerpc/util/skip-callchain-idx.c
index ef5d59a5742e..7c6eeb4633fe 100644
--- a/tools/perf/arch/powerpc/util/skip-callchain-idx.c
+++ b/tools/perf/arch/powerpc/util/skip-callchain-idx.c
@@ -58,9 +58,13 @@ static int check_return_reg(int ra_regno, Dwarf_Frame *frame)
58 } 58 }
59 59
60 /* 60 /*
61 * Check if return address is on the stack. 61 * Check if return address is on the stack. If return address
62 * is in a register (typically R0), it is yet to be saved on
63 * the stack.
62 */ 64 */
63 if (nops != 0 || ops != NULL) 65 if ((nops != 0 || ops != NULL) &&
66 !(nops == 1 && ops[0].atom == DW_OP_regx &&
67 ops[0].number2 == 0 && ops[0].offset == 0))
64 return 0; 68 return 0;
65 69
66 /* 70 /*
@@ -246,7 +250,7 @@ int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain)
246 if (!chain || chain->nr < 3) 250 if (!chain || chain->nr < 3)
247 return skip_slot; 251 return skip_slot;
248 252
249 ip = chain->ips[2]; 253 ip = chain->ips[1];
250 254
251 thread__find_symbol(thread, PERF_RECORD_MISC_USER, ip, &al); 255 thread__find_symbol(thread, PERF_RECORD_MISC_USER, ip, &al);
252 256
diff --git a/tools/perf/arch/s390/util/kvm-stat.c b/tools/perf/arch/s390/util/kvm-stat.c
index d233e2eb9592..aaabab5e2830 100644
--- a/tools/perf/arch/s390/util/kvm-stat.c
+++ b/tools/perf/arch/s390/util/kvm-stat.c
@@ -102,7 +102,7 @@ const char * const kvm_skip_events[] = {
102 102
103int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid) 103int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid)
104{ 104{
105 if (strstr(cpuid, "IBM/S390")) { 105 if (strstr(cpuid, "IBM")) {
106 kvm->exit_reasons = sie_exit_reasons; 106 kvm->exit_reasons = sie_exit_reasons;
107 kvm->exit_reasons_isa = "SIE"; 107 kvm->exit_reasons_isa = "SIE";
108 } else 108 } else
diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index 6a8738f7ead3..f3aa9d02a5ab 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -2193,7 +2193,7 @@ static void print_cacheline(struct c2c_hists *c2c_hists,
2193 fprintf(out, "%s\n", bf); 2193 fprintf(out, "%s\n", bf);
2194 fprintf(out, " -------------------------------------------------------------\n"); 2194 fprintf(out, " -------------------------------------------------------------\n");
2195 2195
2196 hists__fprintf(&c2c_hists->hists, false, 0, 0, 0, out, true); 2196 hists__fprintf(&c2c_hists->hists, false, 0, 0, 0, out, false);
2197} 2197}
2198 2198
2199static void print_pareto(FILE *out) 2199static void print_pareto(FILE *out)
@@ -2268,7 +2268,7 @@ static void perf_c2c__hists_fprintf(FILE *out, struct perf_session *session)
2268 fprintf(out, "=================================================\n"); 2268 fprintf(out, "=================================================\n");
2269 fprintf(out, "#\n"); 2269 fprintf(out, "#\n");
2270 2270
2271 hists__fprintf(&c2c.hists.hists, true, 0, 0, 0, stdout, false); 2271 hists__fprintf(&c2c.hists.hists, true, 0, 0, 0, stdout, true);
2272 2272
2273 fprintf(out, "\n"); 2273 fprintf(out, "\n");
2274 fprintf(out, "=================================================\n"); 2274 fprintf(out, "=================================================\n");
@@ -2349,6 +2349,9 @@ static int perf_c2c__browse_cacheline(struct hist_entry *he)
2349 " s Toggle full length of symbol and source line columns \n" 2349 " s Toggle full length of symbol and source line columns \n"
2350 " q Return back to cacheline list \n"; 2350 " q Return back to cacheline list \n";
2351 2351
2352 if (!he)
2353 return 0;
2354
2352 /* Display compact version first. */ 2355 /* Display compact version first. */
2353 c2c.symbol_full = false; 2356 c2c.symbol_full = false;
2354 2357
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index d660cb7b222b..39db2ee32d48 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -696,7 +696,7 @@ static void hists__process(struct hists *hists)
696 hists__output_resort(hists, NULL); 696 hists__output_resort(hists, NULL);
697 697
698 hists__fprintf(hists, !quiet, 0, 0, 0, stdout, 698 hists__fprintf(hists, !quiet, 0, 0, 0, stdout,
699 symbol_conf.use_callchain); 699 !symbol_conf.use_callchain);
700} 700}
701 701
702static void data__fprintf(void) 702static void data__fprintf(void)
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index c04dc7b53797..02f7a3c27761 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -478,8 +478,8 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
478 478
479 hists__fprintf_nr_sample_events(hists, rep, evname, stdout); 479 hists__fprintf_nr_sample_events(hists, rep, evname, stdout);
480 hists__fprintf(hists, !quiet, 0, 0, rep->min_percent, stdout, 480 hists__fprintf(hists, !quiet, 0, 0, rep->min_percent, stdout,
481 symbol_conf.use_callchain || 481 !(symbol_conf.use_callchain ||
482 symbol_conf.show_branchflag_count); 482 symbol_conf.show_branchflag_count));
483 fprintf(stdout, "\n\n"); 483 fprintf(stdout, "\n\n");
484 } 484 }
485 485
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 05be023c3f0e..d097b5b47eb8 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -296,18 +296,6 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)
296 return perf_evsel__open_per_thread(evsel, evsel_list->threads); 296 return perf_evsel__open_per_thread(evsel, evsel_list->threads);
297} 297}
298 298
299/*
300 * Does the counter have nsecs as a unit?
301 */
302static inline int nsec_counter(struct perf_evsel *evsel)
303{
304 if (perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) ||
305 perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
306 return 1;
307
308 return 0;
309}
310
311static int process_synthesized_event(struct perf_tool *tool __maybe_unused, 299static int process_synthesized_event(struct perf_tool *tool __maybe_unused,
312 union perf_event *event, 300 union perf_event *event,
313 struct perf_sample *sample __maybe_unused, 301 struct perf_sample *sample __maybe_unused,
@@ -1058,34 +1046,6 @@ static void print_metric_header(void *ctx, const char *color __maybe_unused,
1058 fprintf(os->fh, "%*s ", metric_only_len, unit); 1046 fprintf(os->fh, "%*s ", metric_only_len, unit);
1059} 1047}
1060 1048
1061static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg)
1062{
1063 FILE *output = stat_config.output;
1064 double msecs = avg / NSEC_PER_MSEC;
1065 const char *fmt_v, *fmt_n;
1066 char name[25];
1067
1068 fmt_v = csv_output ? "%.6f%s" : "%18.6f%s";
1069 fmt_n = csv_output ? "%s" : "%-25s";
1070
1071 aggr_printout(evsel, id, nr);
1072
1073 scnprintf(name, sizeof(name), "%s%s",
1074 perf_evsel__name(evsel), csv_output ? "" : " (msec)");
1075
1076 fprintf(output, fmt_v, msecs, csv_sep);
1077
1078 if (csv_output)
1079 fprintf(output, "%s%s", evsel->unit, csv_sep);
1080 else
1081 fprintf(output, "%-*s%s", unit_width, evsel->unit, csv_sep);
1082
1083 fprintf(output, fmt_n, name);
1084
1085 if (evsel->cgrp)
1086 fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
1087}
1088
1089static int first_shadow_cpu(struct perf_evsel *evsel, int id) 1049static int first_shadow_cpu(struct perf_evsel *evsel, int id)
1090{ 1050{
1091 int i; 1051 int i;
@@ -1241,11 +1201,7 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval,
1241 return; 1201 return;
1242 } 1202 }
1243 1203
1244 if (metric_only) 1204 if (!metric_only)
1245 /* nothing */;
1246 else if (nsec_counter(counter))
1247 nsec_printout(id, nr, counter, uval);
1248 else
1249 abs_printout(id, nr, counter, uval); 1205 abs_printout(id, nr, counter, uval);
1250 1206
1251 out.print_metric = pm; 1207 out.print_metric = pm;
@@ -1331,7 +1287,7 @@ static void collect_all_aliases(struct perf_evsel *counter,
1331 alias->scale != counter->scale || 1287 alias->scale != counter->scale ||
1332 alias->cgrp != counter->cgrp || 1288 alias->cgrp != counter->cgrp ||
1333 strcmp(alias->unit, counter->unit) || 1289 strcmp(alias->unit, counter->unit) ||
1334 nsec_counter(alias) != nsec_counter(counter)) 1290 perf_evsel__is_clock(alias) != perf_evsel__is_clock(counter))
1335 break; 1291 break;
1336 alias->merged_stat = true; 1292 alias->merged_stat = true;
1337 cb(alias, data, false); 1293 cb(alias, data, false);
@@ -2449,6 +2405,18 @@ static int add_default_attributes(void)
2449 return 0; 2405 return 0;
2450 2406
2451 if (transaction_run) { 2407 if (transaction_run) {
2408 /* Handle -T as -M transaction. Once platform specific metrics
2409 * support has been added to the json files, all archictures
2410 * will use this approach. To determine transaction support
2411 * on an architecture test for such a metric name.
2412 */
2413 if (metricgroup__has_metric("transaction")) {
2414 struct option opt = { .value = &evsel_list };
2415
2416 return metricgroup__parse_groups(&opt, "transaction",
2417 &metric_events);
2418 }
2419
2452 if (pmu_have_event("cpu", "cycles-ct") && 2420 if (pmu_have_event("cpu", "cycles-ct") &&
2453 pmu_have_event("cpu", "el-start")) 2421 pmu_have_event("cpu", "el-start"))
2454 err = parse_events(evsel_list, transaction_attrs, 2422 err = parse_events(evsel_list, transaction_attrs,
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index ffdc2769ff9f..d21d8751e749 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -307,7 +307,7 @@ static void perf_top__print_sym_table(struct perf_top *top)
307 hists__output_recalc_col_len(hists, top->print_entries - printed); 307 hists__output_recalc_col_len(hists, top->print_entries - printed);
308 putchar('\n'); 308 putchar('\n');
309 hists__fprintf(hists, false, top->print_entries - printed, win_width, 309 hists__fprintf(hists, false, top->print_entries - printed, win_width,
310 top->min_percent, stdout, symbol_conf.use_callchain); 310 top->min_percent, stdout, !symbol_conf.use_callchain);
311} 311}
312 312
313static void prompt_integer(int *target, const char *msg) 313static void prompt_integer(int *target, const char *msg)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 6a748eca2edb..88561eed7950 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -291,7 +291,7 @@ size_t strarray__scnprintf(struct strarray *sa, char *bf, size_t size, const cha
291{ 291{
292 int idx = val - sa->offset; 292 int idx = val - sa->offset;
293 293
294 if (idx < 0 || idx >= sa->nr_entries) 294 if (idx < 0 || idx >= sa->nr_entries || sa->entries[idx] == NULL)
295 return scnprintf(bf, size, intfmt, val); 295 return scnprintf(bf, size, intfmt, val);
296 296
297 return scnprintf(bf, size, "%s", sa->entries[idx]); 297 return scnprintf(bf, size, "%s", sa->entries[idx]);
@@ -761,10 +761,12 @@ static struct syscall_fmt {
761 .arg = { [0] = STRARRAY(resource, rlimit_resources), }, }, 761 .arg = { [0] = STRARRAY(resource, rlimit_resources), }, },
762 { .name = "socket", 762 { .name = "socket",
763 .arg = { [0] = STRARRAY(family, socket_families), 763 .arg = { [0] = STRARRAY(family, socket_families),
764 [1] = { .scnprintf = SCA_SK_TYPE, /* type */ }, }, }, 764 [1] = { .scnprintf = SCA_SK_TYPE, /* type */ },
765 [2] = { .scnprintf = SCA_SK_PROTO, /* protocol */ }, }, },
765 { .name = "socketpair", 766 { .name = "socketpair",
766 .arg = { [0] = STRARRAY(family, socket_families), 767 .arg = { [0] = STRARRAY(family, socket_families),
767 [1] = { .scnprintf = SCA_SK_TYPE, /* type */ }, }, }, 768 [1] = { .scnprintf = SCA_SK_TYPE, /* type */ },
769 [2] = { .scnprintf = SCA_SK_PROTO, /* protocol */ }, }, },
768 { .name = "stat", .alias = "newstat", }, 770 { .name = "stat", .alias = "newstat", },
769 { .name = "statx", 771 { .name = "statx",
770 .arg = { [0] = { .scnprintf = SCA_FDAT, /* fdat */ }, 772 .arg = { [0] = { .scnprintf = SCA_FDAT, /* fdat */ },
@@ -2990,6 +2992,7 @@ static int trace__parse_events_option(const struct option *opt, const char *str,
2990 2992
2991 if (trace__validate_ev_qualifier(trace)) 2993 if (trace__validate_ev_qualifier(trace))
2992 goto out; 2994 goto out;
2995 trace->trace_syscalls = true;
2993 } 2996 }
2994 2997
2995 err = 0; 2998 err = 0;
@@ -3045,7 +3048,7 @@ int cmd_trace(int argc, const char **argv)
3045 }, 3048 },
3046 .output = stderr, 3049 .output = stderr,
3047 .show_comm = true, 3050 .show_comm = true,
3048 .trace_syscalls = true, 3051 .trace_syscalls = false,
3049 .kernel_syscallchains = false, 3052 .kernel_syscallchains = false,
3050 .max_stack = UINT_MAX, 3053 .max_stack = UINT_MAX,
3051 }; 3054 };
@@ -3191,13 +3194,7 @@ int cmd_trace(int argc, const char **argv)
3191 3194
3192 if (!trace.trace_syscalls && !trace.trace_pgfaults && 3195 if (!trace.trace_syscalls && !trace.trace_pgfaults &&
3193 trace.evlist->nr_entries == 0 /* Was --events used? */) { 3196 trace.evlist->nr_entries == 0 /* Was --events used? */) {
3194 pr_err("Please specify something to trace.\n"); 3197 trace.trace_syscalls = true;
3195 return -1;
3196 }
3197
3198 if (!trace.trace_syscalls && trace.ev_qualifier) {
3199 pr_err("The -e option can't be used with --no-syscalls.\n");
3200 goto out;
3201 } 3198 }
3202 3199
3203 if (output_name != NULL) { 3200 if (output_name != NULL) {
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index 10f333e2e825..de28466c0186 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -7,6 +7,7 @@ include/uapi/drm/i915_drm.h
7include/uapi/linux/fcntl.h 7include/uapi/linux/fcntl.h
8include/uapi/linux/kcmp.h 8include/uapi/linux/kcmp.h
9include/uapi/linux/kvm.h 9include/uapi/linux/kvm.h
10include/uapi/linux/in.h
10include/uapi/linux/perf_event.h 11include/uapi/linux/perf_event.h
11include/uapi/linux/prctl.h 12include/uapi/linux/prctl.h
12include/uapi/linux/sched.h 13include/uapi/linux/sched.h
@@ -35,6 +36,7 @@ arch/s390/include/uapi/asm/ptrace.h
35arch/s390/include/uapi/asm/sie.h 36arch/s390/include/uapi/asm/sie.h
36arch/arm/include/uapi/asm/kvm.h 37arch/arm/include/uapi/asm/kvm.h
37arch/arm64/include/uapi/asm/kvm.h 38arch/arm64/include/uapi/asm/kvm.h
39arch/arm64/include/uapi/asm/unistd.h
38arch/alpha/include/uapi/asm/errno.h 40arch/alpha/include/uapi/asm/errno.h
39arch/mips/include/asm/errno.h 41arch/mips/include/asm/errno.h
40arch/mips/include/uapi/asm/errno.h 42arch/mips/include/uapi/asm/errno.h
@@ -53,6 +55,7 @@ include/uapi/asm-generic/errno.h
53include/uapi/asm-generic/errno-base.h 55include/uapi/asm-generic/errno-base.h
54include/uapi/asm-generic/ioctls.h 56include/uapi/asm-generic/ioctls.h
55include/uapi/asm-generic/mman-common.h 57include/uapi/asm-generic/mman-common.h
58include/uapi/asm-generic/unistd.h
56' 59'
57 60
58check_2 () { 61check_2 () {
diff --git a/tools/perf/include/bpf/bpf.h b/tools/perf/include/bpf/bpf.h
index dd764ad5efdf..a63aa6241b7f 100644
--- a/tools/perf/include/bpf/bpf.h
+++ b/tools/perf/include/bpf/bpf.h
@@ -1,6 +1,9 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#ifndef _PERF_BPF_H 2#ifndef _PERF_BPF_H
3#define _PERF_BPF_H 3#define _PERF_BPF_H
4
5#include <uapi/linux/bpf.h>
6
4#define SEC(NAME) __attribute__((section(NAME), used)) 7#define SEC(NAME) __attribute__((section(NAME), used))
5 8
6#define probe(function, vars) \ 9#define probe(function, vars) \
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index d215714f48df..21bf7f5a3cf5 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -25,7 +25,9 @@ static inline unsigned long long rdclock(void)
25 return ts.tv_sec * 1000000000ULL + ts.tv_nsec; 25 return ts.tv_sec * 1000000000ULL + ts.tv_nsec;
26} 26}
27 27
28#ifndef MAX_NR_CPUS
28#define MAX_NR_CPUS 1024 29#define MAX_NR_CPUS 1024
30#endif
29 31
30extern const char *input_name; 32extern const char *input_name;
31extern bool perf_host, perf_guest; 33extern bool perf_host, perf_guest;
diff --git a/tools/perf/pmu-events/arch/arm64/cavium/thunderx2/core-imp-def.json b/tools/perf/pmu-events/arch/arm64/cavium/thunderx2/core-imp-def.json
index bc03c06c3918..752e47eb6977 100644
--- a/tools/perf/pmu-events/arch/arm64/cavium/thunderx2/core-imp-def.json
+++ b/tools/perf/pmu-events/arch/arm64/cavium/thunderx2/core-imp-def.json
@@ -12,6 +12,21 @@
12 "ArchStdEvent": "L1D_CACHE_REFILL_WR", 12 "ArchStdEvent": "L1D_CACHE_REFILL_WR",
13 }, 13 },
14 { 14 {
15 "ArchStdEvent": "L1D_CACHE_REFILL_INNER",
16 },
17 {
18 "ArchStdEvent": "L1D_CACHE_REFILL_OUTER",
19 },
20 {
21 "ArchStdEvent": "L1D_CACHE_WB_VICTIM",
22 },
23 {
24 "ArchStdEvent": "L1D_CACHE_WB_CLEAN",
25 },
26 {
27 "ArchStdEvent": "L1D_CACHE_INVAL",
28 },
29 {
15 "ArchStdEvent": "L1D_TLB_REFILL_RD", 30 "ArchStdEvent": "L1D_TLB_REFILL_RD",
16 }, 31 },
17 { 32 {
@@ -24,9 +39,75 @@
24 "ArchStdEvent": "L1D_TLB_WR", 39 "ArchStdEvent": "L1D_TLB_WR",
25 }, 40 },
26 { 41 {
42 "ArchStdEvent": "L2D_TLB_REFILL_RD",
43 },
44 {
45 "ArchStdEvent": "L2D_TLB_REFILL_WR",
46 },
47 {
48 "ArchStdEvent": "L2D_TLB_RD",
49 },
50 {
51 "ArchStdEvent": "L2D_TLB_WR",
52 },
53 {
27 "ArchStdEvent": "BUS_ACCESS_RD", 54 "ArchStdEvent": "BUS_ACCESS_RD",
28 }, 55 },
29 { 56 {
30 "ArchStdEvent": "BUS_ACCESS_WR", 57 "ArchStdEvent": "BUS_ACCESS_WR",
31 } 58 },
59 {
60 "ArchStdEvent": "MEM_ACCESS_RD",
61 },
62 {
63 "ArchStdEvent": "MEM_ACCESS_WR",
64 },
65 {
66 "ArchStdEvent": "UNALIGNED_LD_SPEC",
67 },
68 {
69 "ArchStdEvent": "UNALIGNED_ST_SPEC",
70 },
71 {
72 "ArchStdEvent": "UNALIGNED_LDST_SPEC",
73 },
74 {
75 "ArchStdEvent": "EXC_UNDEF",
76 },
77 {
78 "ArchStdEvent": "EXC_SVC",
79 },
80 {
81 "ArchStdEvent": "EXC_PABORT",
82 },
83 {
84 "ArchStdEvent": "EXC_DABORT",
85 },
86 {
87 "ArchStdEvent": "EXC_IRQ",
88 },
89 {
90 "ArchStdEvent": "EXC_FIQ",
91 },
92 {
93 "ArchStdEvent": "EXC_SMC",
94 },
95 {
96 "ArchStdEvent": "EXC_HVC",
97 },
98 {
99 "ArchStdEvent": "EXC_TRAP_PABORT",
100 },
101 {
102 "ArchStdEvent": "EXC_TRAP_DABORT",
103 },
104 {
105 "ArchStdEvent": "EXC_TRAP_OTHER",
106 },
107 {
108 "ArchStdEvent": "EXC_TRAP_IRQ",
109 },
110 {
111 "ArchStdEvent": "EXC_TRAP_FIQ",
112 }
32] 113]
diff --git a/tools/perf/pmu-events/arch/s390/cf_z10/basic.json b/tools/perf/pmu-events/arch/s390/cf_z10/basic.json
index 8bf16759ca53..2dd8dafff2ef 100644
--- a/tools/perf/pmu-events/arch/s390/cf_z10/basic.json
+++ b/tools/perf/pmu-events/arch/s390/cf_z10/basic.json
@@ -1,71 +1,83 @@
1[ 1[
2 { 2 {
3 "Unit": "CPU-M-CF",
3 "EventCode": "0", 4 "EventCode": "0",
4 "EventName": "CPU_CYCLES", 5 "EventName": "CPU_CYCLES",
5 "BriefDescription": "CPU Cycles", 6 "BriefDescription": "CPU Cycles",
6 "PublicDescription": "Cycle Count" 7 "PublicDescription": "Cycle Count"
7 }, 8 },
8 { 9 {
10 "Unit": "CPU-M-CF",
9 "EventCode": "1", 11 "EventCode": "1",
10 "EventName": "INSTRUCTIONS", 12 "EventName": "INSTRUCTIONS",
11 "BriefDescription": "Instructions", 13 "BriefDescription": "Instructions",
12 "PublicDescription": "Instruction Count" 14 "PublicDescription": "Instruction Count"
13 }, 15 },
14 { 16 {
17 "Unit": "CPU-M-CF",
15 "EventCode": "2", 18 "EventCode": "2",
16 "EventName": "L1I_DIR_WRITES", 19 "EventName": "L1I_DIR_WRITES",
17 "BriefDescription": "L1I Directory Writes", 20 "BriefDescription": "L1I Directory Writes",
18 "PublicDescription": "Level-1 I-Cache Directory Write Count" 21 "PublicDescription": "Level-1 I-Cache Directory Write Count"
19 }, 22 },
20 { 23 {
24 "Unit": "CPU-M-CF",
21 "EventCode": "3", 25 "EventCode": "3",
22 "EventName": "L1I_PENALTY_CYCLES", 26 "EventName": "L1I_PENALTY_CYCLES",
23 "BriefDescription": "L1I Penalty Cycles", 27 "BriefDescription": "L1I Penalty Cycles",
24 "PublicDescription": "Level-1 I-Cache Penalty Cycle Count" 28 "PublicDescription": "Level-1 I-Cache Penalty Cycle Count"
25 }, 29 },
26 { 30 {
31 "Unit": "CPU-M-CF",
27 "EventCode": "4", 32 "EventCode": "4",
28 "EventName": "L1D_DIR_WRITES", 33 "EventName": "L1D_DIR_WRITES",
29 "BriefDescription": "L1D Directory Writes", 34 "BriefDescription": "L1D Directory Writes",
30 "PublicDescription": "Level-1 D-Cache Directory Write Count" 35 "PublicDescription": "Level-1 D-Cache Directory Write Count"
31 }, 36 },
32 { 37 {
38 "Unit": "CPU-M-CF",
33 "EventCode": "5", 39 "EventCode": "5",
34 "EventName": "L1D_PENALTY_CYCLES", 40 "EventName": "L1D_PENALTY_CYCLES",
35 "BriefDescription": "L1D Penalty Cycles", 41 "BriefDescription": "L1D Penalty Cycles",
36 "PublicDescription": "Level-1 D-Cache Penalty Cycle Count" 42 "PublicDescription": "Level-1 D-Cache Penalty Cycle Count"
37 }, 43 },
38 { 44 {
45 "Unit": "CPU-M-CF",
39 "EventCode": "32", 46 "EventCode": "32",
40 "EventName": "PROBLEM_STATE_CPU_CYCLES", 47 "EventName": "PROBLEM_STATE_CPU_CYCLES",
41 "BriefDescription": "Problem-State CPU Cycles", 48 "BriefDescription": "Problem-State CPU Cycles",
42 "PublicDescription": "Problem-State Cycle Count" 49 "PublicDescription": "Problem-State Cycle Count"
43 }, 50 },
44 { 51 {
52 "Unit": "CPU-M-CF",
45 "EventCode": "33", 53 "EventCode": "33",
46 "EventName": "PROBLEM_STATE_INSTRUCTIONS", 54 "EventName": "PROBLEM_STATE_INSTRUCTIONS",
47 "BriefDescription": "Problem-State Instructions", 55 "BriefDescription": "Problem-State Instructions",
48 "PublicDescription": "Problem-State Instruction Count" 56 "PublicDescription": "Problem-State Instruction Count"
49 }, 57 },
50 { 58 {
59 "Unit": "CPU-M-CF",
51 "EventCode": "34", 60 "EventCode": "34",
52 "EventName": "PROBLEM_STATE_L1I_DIR_WRITES", 61 "EventName": "PROBLEM_STATE_L1I_DIR_WRITES",
53 "BriefDescription": "Problem-State L1I Directory Writes", 62 "BriefDescription": "Problem-State L1I Directory Writes",
54 "PublicDescription": "Problem-State Level-1 I-Cache Directory Write Count" 63 "PublicDescription": "Problem-State Level-1 I-Cache Directory Write Count"
55 }, 64 },
56 { 65 {
66 "Unit": "CPU-M-CF",
57 "EventCode": "35", 67 "EventCode": "35",
58 "EventName": "PROBLEM_STATE_L1I_PENALTY_CYCLES", 68 "EventName": "PROBLEM_STATE_L1I_PENALTY_CYCLES",
59 "BriefDescription": "Problem-State L1I Penalty Cycles", 69 "BriefDescription": "Problem-State L1I Penalty Cycles",
60 "PublicDescription": "Problem-State Level-1 I-Cache Penalty Cycle Count" 70 "PublicDescription": "Problem-State Level-1 I-Cache Penalty Cycle Count"
61 }, 71 },
62 { 72 {
73 "Unit": "CPU-M-CF",
63 "EventCode": "36", 74 "EventCode": "36",
64 "EventName": "PROBLEM_STATE_L1D_DIR_WRITES", 75 "EventName": "PROBLEM_STATE_L1D_DIR_WRITES",
65 "BriefDescription": "Problem-State L1D Directory Writes", 76 "BriefDescription": "Problem-State L1D Directory Writes",
66 "PublicDescription": "Problem-State Level-1 D-Cache Directory Write Count" 77 "PublicDescription": "Problem-State Level-1 D-Cache Directory Write Count"
67 }, 78 },
68 { 79 {
80 "Unit": "CPU-M-CF",
69 "EventCode": "37", 81 "EventCode": "37",
70 "EventName": "PROBLEM_STATE_L1D_PENALTY_CYCLES", 82 "EventName": "PROBLEM_STATE_L1D_PENALTY_CYCLES",
71 "BriefDescription": "Problem-State L1D Penalty Cycles", 83 "BriefDescription": "Problem-State L1D Penalty Cycles",
diff --git a/tools/perf/pmu-events/arch/s390/cf_z10/crypto.json b/tools/perf/pmu-events/arch/s390/cf_z10/crypto.json
index 7e5b72492141..db286f19e7b6 100644
--- a/tools/perf/pmu-events/arch/s390/cf_z10/crypto.json
+++ b/tools/perf/pmu-events/arch/s390/cf_z10/crypto.json
@@ -1,95 +1,111 @@
1[ 1[
2 { 2 {
3 "Unit": "CPU-M-CF",
3 "EventCode": "64", 4 "EventCode": "64",
4 "EventName": "PRNG_FUNCTIONS", 5 "EventName": "PRNG_FUNCTIONS",
5 "BriefDescription": "PRNG Functions", 6 "BriefDescription": "PRNG Functions",
6 "PublicDescription": "Total number of the PRNG functions issued by the CPU" 7 "PublicDescription": "Total number of the PRNG functions issued by the CPU"
7 }, 8 },
8 { 9 {
10 "Unit": "CPU-M-CF",
9 "EventCode": "65", 11 "EventCode": "65",
10 "EventName": "PRNG_CYCLES", 12 "EventName": "PRNG_CYCLES",
11 "BriefDescription": "PRNG Cycles", 13 "BriefDescription": "PRNG Cycles",
12 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU" 14 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU"
13 }, 15 },
14 { 16 {
17 "Unit": "CPU-M-CF",
15 "EventCode": "66", 18 "EventCode": "66",
16 "EventName": "PRNG_BLOCKED_FUNCTIONS", 19 "EventName": "PRNG_BLOCKED_FUNCTIONS",
17 "BriefDescription": "PRNG Blocked Functions", 20 "BriefDescription": "PRNG Blocked Functions",
18 "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" 21 "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
19 }, 22 },
20 { 23 {
24 "Unit": "CPU-M-CF",
21 "EventCode": "67", 25 "EventCode": "67",
22 "EventName": "PRNG_BLOCKED_CYCLES", 26 "EventName": "PRNG_BLOCKED_CYCLES",
23 "BriefDescription": "PRNG Blocked Cycles", 27 "BriefDescription": "PRNG Blocked Cycles",
24 "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" 28 "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
25 }, 29 },
26 { 30 {
31 "Unit": "CPU-M-CF",
27 "EventCode": "68", 32 "EventCode": "68",
28 "EventName": "SHA_FUNCTIONS", 33 "EventName": "SHA_FUNCTIONS",
29 "BriefDescription": "SHA Functions", 34 "BriefDescription": "SHA Functions",
30 "PublicDescription": "Total number of SHA functions issued by the CPU" 35 "PublicDescription": "Total number of SHA functions issued by the CPU"
31 }, 36 },
32 { 37 {
38 "Unit": "CPU-M-CF",
33 "EventCode": "69", 39 "EventCode": "69",
34 "EventName": "SHA_CYCLES", 40 "EventName": "SHA_CYCLES",
35 "BriefDescription": "SHA Cycles", 41 "BriefDescription": "SHA Cycles",
36 "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU" 42 "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU"
37 }, 43 },
38 { 44 {
45 "Unit": "CPU-M-CF",
39 "EventCode": "70", 46 "EventCode": "70",
40 "EventName": "SHA_BLOCKED_FUNCTIONS", 47 "EventName": "SHA_BLOCKED_FUNCTIONS",
41 "BriefDescription": "SHA Blocked Functions", 48 "BriefDescription": "SHA Blocked Functions",
42 "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU" 49 "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU"
43 }, 50 },
44 { 51 {
52 "Unit": "CPU-M-CF",
45 "EventCode": "71", 53 "EventCode": "71",
46 "EventName": "SHA_BLOCKED_CYCLES", 54 "EventName": "SHA_BLOCKED_CYCLES",
47 "BriefDescription": "SHA Bloced Cycles", 55 "BriefDescription": "SHA Bloced Cycles",
48 "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU" 56 "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU"
49 }, 57 },
50 { 58 {
59 "Unit": "CPU-M-CF",
51 "EventCode": "72", 60 "EventCode": "72",
52 "EventName": "DEA_FUNCTIONS", 61 "EventName": "DEA_FUNCTIONS",
53 "BriefDescription": "DEA Functions", 62 "BriefDescription": "DEA Functions",
54 "PublicDescription": "Total number of the DEA functions issued by the CPU" 63 "PublicDescription": "Total number of the DEA functions issued by the CPU"
55 }, 64 },
56 { 65 {
66 "Unit": "CPU-M-CF",
57 "EventCode": "73", 67 "EventCode": "73",
58 "EventName": "DEA_CYCLES", 68 "EventName": "DEA_CYCLES",
59 "BriefDescription": "DEA Cycles", 69 "BriefDescription": "DEA Cycles",
60 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU" 70 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU"
61 }, 71 },
62 { 72 {
73 "Unit": "CPU-M-CF",
63 "EventCode": "74", 74 "EventCode": "74",
64 "EventName": "DEA_BLOCKED_FUNCTIONS", 75 "EventName": "DEA_BLOCKED_FUNCTIONS",
65 "BriefDescription": "DEA Blocked Functions", 76 "BriefDescription": "DEA Blocked Functions",
66 "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" 77 "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
67 }, 78 },
68 { 79 {
80 "Unit": "CPU-M-CF",
69 "EventCode": "75", 81 "EventCode": "75",
70 "EventName": "DEA_BLOCKED_CYCLES", 82 "EventName": "DEA_BLOCKED_CYCLES",
71 "BriefDescription": "DEA Blocked Cycles", 83 "BriefDescription": "DEA Blocked Cycles",
72 "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" 84 "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
73 }, 85 },
74 { 86 {
87 "Unit": "CPU-M-CF",
75 "EventCode": "76", 88 "EventCode": "76",
76 "EventName": "AES_FUNCTIONS", 89 "EventName": "AES_FUNCTIONS",
77 "BriefDescription": "AES Functions", 90 "BriefDescription": "AES Functions",
78 "PublicDescription": "Total number of AES functions issued by the CPU" 91 "PublicDescription": "Total number of AES functions issued by the CPU"
79 }, 92 },
80 { 93 {
94 "Unit": "CPU-M-CF",
81 "EventCode": "77", 95 "EventCode": "77",
82 "EventName": "AES_CYCLES", 96 "EventName": "AES_CYCLES",
83 "BriefDescription": "AES Cycles", 97 "BriefDescription": "AES Cycles",
84 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU" 98 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU"
85 }, 99 },
86 { 100 {
101 "Unit": "CPU-M-CF",
87 "EventCode": "78", 102 "EventCode": "78",
88 "EventName": "AES_BLOCKED_FUNCTIONS", 103 "EventName": "AES_BLOCKED_FUNCTIONS",
89 "BriefDescription": "AES Blocked Functions", 104 "BriefDescription": "AES Blocked Functions",
90 "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" 105 "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
91 }, 106 },
92 { 107 {
108 "Unit": "CPU-M-CF",
93 "EventCode": "79", 109 "EventCode": "79",
94 "EventName": "AES_BLOCKED_CYCLES", 110 "EventName": "AES_BLOCKED_CYCLES",
95 "BriefDescription": "AES Blocked Cycles", 111 "BriefDescription": "AES Blocked Cycles",
diff --git a/tools/perf/pmu-events/arch/s390/cf_z10/extended.json b/tools/perf/pmu-events/arch/s390/cf_z10/extended.json
index 0feedb40f30f..b6b7f29ca831 100644
--- a/tools/perf/pmu-events/arch/s390/cf_z10/extended.json
+++ b/tools/perf/pmu-events/arch/s390/cf_z10/extended.json
@@ -1,107 +1,125 @@
1[ 1[
2 { 2 {
3 "Unit": "CPU-M-CF",
3 "EventCode": "128", 4 "EventCode": "128",
4 "EventName": "L1I_L2_SOURCED_WRITES", 5 "EventName": "L1I_L2_SOURCED_WRITES",
5 "BriefDescription": "L1I L2 Sourced Writes", 6 "BriefDescription": "L1I L2 Sourced Writes",
6 "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from the Level-2 (L1.5) cache" 7 "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from the Level-2 (L1.5) cache"
7 }, 8 },
8 { 9 {
10 "Unit": "CPU-M-CF",
9 "EventCode": "129", 11 "EventCode": "129",
10 "EventName": "L1D_L2_SOURCED_WRITES", 12 "EventName": "L1D_L2_SOURCED_WRITES",
11 "BriefDescription": "L1D L2 Sourced Writes", 13 "BriefDescription": "L1D L2 Sourced Writes",
12 "PublicDescription": "A directory write to the Level-1 D-Cache directory where the installed cache line was sourced from the Level-2 (L1.5) cache" 14 "PublicDescription": "A directory write to the Level-1 D-Cache directory where the installed cache line was sourced from the Level-2 (L1.5) cache"
13 }, 15 },
14 { 16 {
17 "Unit": "CPU-M-CF",
15 "EventCode": "130", 18 "EventCode": "130",
16 "EventName": "L1I_L3_LOCAL_WRITES", 19 "EventName": "L1I_L3_LOCAL_WRITES",
17 "BriefDescription": "L1I L3 Local Writes", 20 "BriefDescription": "L1I L3 Local Writes",
18 "PublicDescription": "A directory write to the Level-1 I-Cache directory where the installed cache line was sourced from the Level-3 cache that is on the same book as the Instruction cache (Local L2 cache)" 21 "PublicDescription": "A directory write to the Level-1 I-Cache directory where the installed cache line was sourced from the Level-3 cache that is on the same book as the Instruction cache (Local L2 cache)"
19 }, 22 },
20 { 23 {
24 "Unit": "CPU-M-CF",
21 "EventCode": "131", 25 "EventCode": "131",
22 "EventName": "L1D_L3_LOCAL_WRITES", 26 "EventName": "L1D_L3_LOCAL_WRITES",
23 "BriefDescription": "L1D L3 Local Writes", 27 "BriefDescription": "L1D L3 Local Writes",
24 "PublicDescription": "A directory write to the Level-1 D-Cache directory where the installtion cache line was source from the Level-3 cache that is on the same book as the Data cache (Local L2 cache)" 28 "PublicDescription": "A directory write to the Level-1 D-Cache directory where the installtion cache line was source from the Level-3 cache that is on the same book as the Data cache (Local L2 cache)"
25 }, 29 },
26 { 30 {
31 "Unit": "CPU-M-CF",
27 "EventCode": "132", 32 "EventCode": "132",
28 "EventName": "L1I_L3_REMOTE_WRITES", 33 "EventName": "L1I_L3_REMOTE_WRITES",
29 "BriefDescription": "L1I L3 Remote Writes", 34 "BriefDescription": "L1I L3 Remote Writes",
30 "PublicDescription": "A directory write to the Level-1 I-Cache directory where the installed cache line was sourced from a Level-3 cache that is not on the same book as the Instruction cache (Remote L2 cache)" 35 "PublicDescription": "A directory write to the Level-1 I-Cache directory where the installed cache line was sourced from a Level-3 cache that is not on the same book as the Instruction cache (Remote L2 cache)"
31 }, 36 },
32 { 37 {
38 "Unit": "CPU-M-CF",
33 "EventCode": "133", 39 "EventCode": "133",
34 "EventName": "L1D_L3_REMOTE_WRITES", 40 "EventName": "L1D_L3_REMOTE_WRITES",
35 "BriefDescription": "L1D L3 Remote Writes", 41 "BriefDescription": "L1D L3 Remote Writes",
36 "PublicDescription": "A directory write to the Level-1 D-Cache directory where the installed cache line was sourced from a Level-3 cache that is not on the same book as the Data cache (Remote L2 cache)" 42 "PublicDescription": "A directory write to the Level-1 D-Cache directory where the installed cache line was sourced from a Level-3 cache that is not on the same book as the Data cache (Remote L2 cache)"
37 }, 43 },
38 { 44 {
45 "Unit": "CPU-M-CF",
39 "EventCode": "134", 46 "EventCode": "134",
40 "EventName": "L1D_LMEM_SOURCED_WRITES", 47 "EventName": "L1D_LMEM_SOURCED_WRITES",
41 "BriefDescription": "L1D Local Memory Sourced Writes", 48 "BriefDescription": "L1D Local Memory Sourced Writes",
42 "PublicDescription": "A directory write to the Level-1 D-Cache directory where the installed cache line was sourced from memory that is attached to the same book as the Data cache (Local Memory)" 49 "PublicDescription": "A directory write to the Level-1 D-Cache directory where the installed cache line was sourced from memory that is attached to the same book as the Data cache (Local Memory)"
43 }, 50 },
44 { 51 {
52 "Unit": "CPU-M-CF",
45 "EventCode": "135", 53 "EventCode": "135",
46 "EventName": "L1I_LMEM_SOURCED_WRITES", 54 "EventName": "L1I_LMEM_SOURCED_WRITES",
47 "BriefDescription": "L1I Local Memory Sourced Writes", 55 "BriefDescription": "L1I Local Memory Sourced Writes",
48 "PublicDescription": "A directory write to the Level-1 I-Cache where the installed cache line was sourced from memory that is attached to the s ame book as the Instruction cache (Local Memory)" 56 "PublicDescription": "A directory write to the Level-1 I-Cache where the installed cache line was sourced from memory that is attached to the s ame book as the Instruction cache (Local Memory)"
49 }, 57 },
50 { 58 {
59 "Unit": "CPU-M-CF",
51 "EventCode": "136", 60 "EventCode": "136",
52 "EventName": "L1D_RO_EXCL_WRITES", 61 "EventName": "L1D_RO_EXCL_WRITES",
53 "BriefDescription": "L1D Read-only Exclusive Writes", 62 "BriefDescription": "L1D Read-only Exclusive Writes",
54 "PublicDescription": "A directory write to the Level-1 D-Cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line" 63 "PublicDescription": "A directory write to the Level-1 D-Cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line"
55 }, 64 },
56 { 65 {
66 "Unit": "CPU-M-CF",
57 "EventCode": "137", 67 "EventCode": "137",
58 "EventName": "L1I_CACHELINE_INVALIDATES", 68 "EventName": "L1I_CACHELINE_INVALIDATES",
59 "BriefDescription": "L1I Cacheline Invalidates", 69 "BriefDescription": "L1I Cacheline Invalidates",
60 "PublicDescription": "A cache line in the Level-1 I-Cache has been invalidated by a store on the same CPU as the Level-1 I-Cache" 70 "PublicDescription": "A cache line in the Level-1 I-Cache has been invalidated by a store on the same CPU as the Level-1 I-Cache"
61 }, 71 },
62 { 72 {
73 "Unit": "CPU-M-CF",
63 "EventCode": "138", 74 "EventCode": "138",
64 "EventName": "ITLB1_WRITES", 75 "EventName": "ITLB1_WRITES",
65 "BriefDescription": "ITLB1 Writes", 76 "BriefDescription": "ITLB1 Writes",
66 "PublicDescription": "A translation entry has been written into the Level-1 Instruction Translation Lookaside Buffer" 77 "PublicDescription": "A translation entry has been written into the Level-1 Instruction Translation Lookaside Buffer"
67 }, 78 },
68 { 79 {
80 "Unit": "CPU-M-CF",
69 "EventCode": "139", 81 "EventCode": "139",
70 "EventName": "DTLB1_WRITES", 82 "EventName": "DTLB1_WRITES",
71 "BriefDescription": "DTLB1 Writes", 83 "BriefDescription": "DTLB1 Writes",
72 "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer" 84 "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer"
73 }, 85 },
74 { 86 {
87 "Unit": "CPU-M-CF",
75 "EventCode": "140", 88 "EventCode": "140",
76 "EventName": "TLB2_PTE_WRITES", 89 "EventName": "TLB2_PTE_WRITES",
77 "BriefDescription": "TLB2 PTE Writes", 90 "BriefDescription": "TLB2 PTE Writes",
78 "PublicDescription": "A translation entry has been written to the Level-2 TLB Page Table Entry arrays" 91 "PublicDescription": "A translation entry has been written to the Level-2 TLB Page Table Entry arrays"
79 }, 92 },
80 { 93 {
94 "Unit": "CPU-M-CF",
81 "EventCode": "141", 95 "EventCode": "141",
82 "EventName": "TLB2_CRSTE_WRITES", 96 "EventName": "TLB2_CRSTE_WRITES",
83 "BriefDescription": "TLB2 CRSTE Writes", 97 "BriefDescription": "TLB2 CRSTE Writes",
84 "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays" 98 "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays"
85 }, 99 },
86 { 100 {
101 "Unit": "CPU-M-CF",
87 "EventCode": "142", 102 "EventCode": "142",
88 "EventName": "TLB2_CRSTE_HPAGE_WRITES", 103 "EventName": "TLB2_CRSTE_HPAGE_WRITES",
89 "BriefDescription": "TLB2 CRSTE One-Megabyte Page Writes", 104 "BriefDescription": "TLB2 CRSTE One-Megabyte Page Writes",
90 "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays for a one-megabyte large page translation" 105 "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays for a one-megabyte large page translation"
91 }, 106 },
92 { 107 {
108 "Unit": "CPU-M-CF",
93 "EventCode": "145", 109 "EventCode": "145",
94 "EventName": "ITLB1_MISSES", 110 "EventName": "ITLB1_MISSES",
95 "BriefDescription": "ITLB1 Misses", 111 "BriefDescription": "ITLB1 Misses",
96 "PublicDescription": "Level-1 Instruction TLB miss in progress. Incremented by one for every cycle an ITLB1 miss is in progress" 112 "PublicDescription": "Level-1 Instruction TLB miss in progress. Incremented by one for every cycle an ITLB1 miss is in progress"
97 }, 113 },
98 { 114 {
115 "Unit": "CPU-M-CF",
99 "EventCode": "146", 116 "EventCode": "146",
100 "EventName": "DTLB1_MISSES", 117 "EventName": "DTLB1_MISSES",
101 "BriefDescription": "DTLB1 Misses", 118 "BriefDescription": "DTLB1 Misses",
102 "PublicDescription": "Level-1 Data TLB miss in progress. Incremented by one for every cycle an DTLB1 miss is in progress" 119 "PublicDescription": "Level-1 Data TLB miss in progress. Incremented by one for every cycle an DTLB1 miss is in progress"
103 }, 120 },
104 { 121 {
122 "Unit": "CPU-M-CF",
105 "EventCode": "147", 123 "EventCode": "147",
106 "EventName": "L2C_STORES_SENT", 124 "EventName": "L2C_STORES_SENT",
107 "BriefDescription": "L2C Stores Sent", 125 "BriefDescription": "L2C Stores Sent",
diff --git a/tools/perf/pmu-events/arch/s390/cf_z13/basic.json b/tools/perf/pmu-events/arch/s390/cf_z13/basic.json
index 8bf16759ca53..2dd8dafff2ef 100644
--- a/tools/perf/pmu-events/arch/s390/cf_z13/basic.json
+++ b/tools/perf/pmu-events/arch/s390/cf_z13/basic.json
@@ -1,71 +1,83 @@
1[ 1[
2 { 2 {
3 "Unit": "CPU-M-CF",
3 "EventCode": "0", 4 "EventCode": "0",
4 "EventName": "CPU_CYCLES", 5 "EventName": "CPU_CYCLES",
5 "BriefDescription": "CPU Cycles", 6 "BriefDescription": "CPU Cycles",
6 "PublicDescription": "Cycle Count" 7 "PublicDescription": "Cycle Count"
7 }, 8 },
8 { 9 {
10 "Unit": "CPU-M-CF",
9 "EventCode": "1", 11 "EventCode": "1",
10 "EventName": "INSTRUCTIONS", 12 "EventName": "INSTRUCTIONS",
11 "BriefDescription": "Instructions", 13 "BriefDescription": "Instructions",
12 "PublicDescription": "Instruction Count" 14 "PublicDescription": "Instruction Count"
13 }, 15 },
14 { 16 {
17 "Unit": "CPU-M-CF",
15 "EventCode": "2", 18 "EventCode": "2",
16 "EventName": "L1I_DIR_WRITES", 19 "EventName": "L1I_DIR_WRITES",
17 "BriefDescription": "L1I Directory Writes", 20 "BriefDescription": "L1I Directory Writes",
18 "PublicDescription": "Level-1 I-Cache Directory Write Count" 21 "PublicDescription": "Level-1 I-Cache Directory Write Count"
19 }, 22 },
20 { 23 {
24 "Unit": "CPU-M-CF",
21 "EventCode": "3", 25 "EventCode": "3",
22 "EventName": "L1I_PENALTY_CYCLES", 26 "EventName": "L1I_PENALTY_CYCLES",
23 "BriefDescription": "L1I Penalty Cycles", 27 "BriefDescription": "L1I Penalty Cycles",
24 "PublicDescription": "Level-1 I-Cache Penalty Cycle Count" 28 "PublicDescription": "Level-1 I-Cache Penalty Cycle Count"
25 }, 29 },
26 { 30 {
31 "Unit": "CPU-M-CF",
27 "EventCode": "4", 32 "EventCode": "4",
28 "EventName": "L1D_DIR_WRITES", 33 "EventName": "L1D_DIR_WRITES",
29 "BriefDescription": "L1D Directory Writes", 34 "BriefDescription": "L1D Directory Writes",
30 "PublicDescription": "Level-1 D-Cache Directory Write Count" 35 "PublicDescription": "Level-1 D-Cache Directory Write Count"
31 }, 36 },
32 { 37 {
38 "Unit": "CPU-M-CF",
33 "EventCode": "5", 39 "EventCode": "5",
34 "EventName": "L1D_PENALTY_CYCLES", 40 "EventName": "L1D_PENALTY_CYCLES",
35 "BriefDescription": "L1D Penalty Cycles", 41 "BriefDescription": "L1D Penalty Cycles",
36 "PublicDescription": "Level-1 D-Cache Penalty Cycle Count" 42 "PublicDescription": "Level-1 D-Cache Penalty Cycle Count"
37 }, 43 },
38 { 44 {
45 "Unit": "CPU-M-CF",
39 "EventCode": "32", 46 "EventCode": "32",
40 "EventName": "PROBLEM_STATE_CPU_CYCLES", 47 "EventName": "PROBLEM_STATE_CPU_CYCLES",
41 "BriefDescription": "Problem-State CPU Cycles", 48 "BriefDescription": "Problem-State CPU Cycles",
42 "PublicDescription": "Problem-State Cycle Count" 49 "PublicDescription": "Problem-State Cycle Count"
43 }, 50 },
44 { 51 {
52 "Unit": "CPU-M-CF",
45 "EventCode": "33", 53 "EventCode": "33",
46 "EventName": "PROBLEM_STATE_INSTRUCTIONS", 54 "EventName": "PROBLEM_STATE_INSTRUCTIONS",
47 "BriefDescription": "Problem-State Instructions", 55 "BriefDescription": "Problem-State Instructions",
48 "PublicDescription": "Problem-State Instruction Count" 56 "PublicDescription": "Problem-State Instruction Count"
49 }, 57 },
50 { 58 {
59 "Unit": "CPU-M-CF",
51 "EventCode": "34", 60 "EventCode": "34",
52 "EventName": "PROBLEM_STATE_L1I_DIR_WRITES", 61 "EventName": "PROBLEM_STATE_L1I_DIR_WRITES",
53 "BriefDescription": "Problem-State L1I Directory Writes", 62 "BriefDescription": "Problem-State L1I Directory Writes",
54 "PublicDescription": "Problem-State Level-1 I-Cache Directory Write Count" 63 "PublicDescription": "Problem-State Level-1 I-Cache Directory Write Count"
55 }, 64 },
56 { 65 {
66 "Unit": "CPU-M-CF",
57 "EventCode": "35", 67 "EventCode": "35",
58 "EventName": "PROBLEM_STATE_L1I_PENALTY_CYCLES", 68 "EventName": "PROBLEM_STATE_L1I_PENALTY_CYCLES",
59 "BriefDescription": "Problem-State L1I Penalty Cycles", 69 "BriefDescription": "Problem-State L1I Penalty Cycles",
60 "PublicDescription": "Problem-State Level-1 I-Cache Penalty Cycle Count" 70 "PublicDescription": "Problem-State Level-1 I-Cache Penalty Cycle Count"
61 }, 71 },
62 { 72 {
73 "Unit": "CPU-M-CF",
63 "EventCode": "36", 74 "EventCode": "36",
64 "EventName": "PROBLEM_STATE_L1D_DIR_WRITES", 75 "EventName": "PROBLEM_STATE_L1D_DIR_WRITES",
65 "BriefDescription": "Problem-State L1D Directory Writes", 76 "BriefDescription": "Problem-State L1D Directory Writes",
66 "PublicDescription": "Problem-State Level-1 D-Cache Directory Write Count" 77 "PublicDescription": "Problem-State Level-1 D-Cache Directory Write Count"
67 }, 78 },
68 { 79 {
80 "Unit": "CPU-M-CF",
69 "EventCode": "37", 81 "EventCode": "37",
70 "EventName": "PROBLEM_STATE_L1D_PENALTY_CYCLES", 82 "EventName": "PROBLEM_STATE_L1D_PENALTY_CYCLES",
71 "BriefDescription": "Problem-State L1D Penalty Cycles", 83 "BriefDescription": "Problem-State L1D Penalty Cycles",
diff --git a/tools/perf/pmu-events/arch/s390/cf_z13/crypto.json b/tools/perf/pmu-events/arch/s390/cf_z13/crypto.json
index 7e5b72492141..db286f19e7b6 100644
--- a/tools/perf/pmu-events/arch/s390/cf_z13/crypto.json
+++ b/tools/perf/pmu-events/arch/s390/cf_z13/crypto.json
@@ -1,95 +1,111 @@
1[ 1[
2 { 2 {
3 "Unit": "CPU-M-CF",
3 "EventCode": "64", 4 "EventCode": "64",
4 "EventName": "PRNG_FUNCTIONS", 5 "EventName": "PRNG_FUNCTIONS",
5 "BriefDescription": "PRNG Functions", 6 "BriefDescription": "PRNG Functions",
6 "PublicDescription": "Total number of the PRNG functions issued by the CPU" 7 "PublicDescription": "Total number of the PRNG functions issued by the CPU"
7 }, 8 },
8 { 9 {
10 "Unit": "CPU-M-CF",
9 "EventCode": "65", 11 "EventCode": "65",
10 "EventName": "PRNG_CYCLES", 12 "EventName": "PRNG_CYCLES",
11 "BriefDescription": "PRNG Cycles", 13 "BriefDescription": "PRNG Cycles",
12 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU" 14 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU"
13 }, 15 },
14 { 16 {
17 "Unit": "CPU-M-CF",
15 "EventCode": "66", 18 "EventCode": "66",
16 "EventName": "PRNG_BLOCKED_FUNCTIONS", 19 "EventName": "PRNG_BLOCKED_FUNCTIONS",
17 "BriefDescription": "PRNG Blocked Functions", 20 "BriefDescription": "PRNG Blocked Functions",
18 "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" 21 "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
19 }, 22 },
20 { 23 {
24 "Unit": "CPU-M-CF",
21 "EventCode": "67", 25 "EventCode": "67",
22 "EventName": "PRNG_BLOCKED_CYCLES", 26 "EventName": "PRNG_BLOCKED_CYCLES",
23 "BriefDescription": "PRNG Blocked Cycles", 27 "BriefDescription": "PRNG Blocked Cycles",
24 "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" 28 "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
25 }, 29 },
26 { 30 {
31 "Unit": "CPU-M-CF",
27 "EventCode": "68", 32 "EventCode": "68",
28 "EventName": "SHA_FUNCTIONS", 33 "EventName": "SHA_FUNCTIONS",
29 "BriefDescription": "SHA Functions", 34 "BriefDescription": "SHA Functions",
30 "PublicDescription": "Total number of SHA functions issued by the CPU" 35 "PublicDescription": "Total number of SHA functions issued by the CPU"
31 }, 36 },
32 { 37 {
38 "Unit": "CPU-M-CF",
33 "EventCode": "69", 39 "EventCode": "69",
34 "EventName": "SHA_CYCLES", 40 "EventName": "SHA_CYCLES",
35 "BriefDescription": "SHA Cycles", 41 "BriefDescription": "SHA Cycles",
36 "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU" 42 "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU"
37 }, 43 },
38 { 44 {
45 "Unit": "CPU-M-CF",
39 "EventCode": "70", 46 "EventCode": "70",
40 "EventName": "SHA_BLOCKED_FUNCTIONS", 47 "EventName": "SHA_BLOCKED_FUNCTIONS",
41 "BriefDescription": "SHA Blocked Functions", 48 "BriefDescription": "SHA Blocked Functions",
42 "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU" 49 "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU"
43 }, 50 },
44 { 51 {
52 "Unit": "CPU-M-CF",
45 "EventCode": "71", 53 "EventCode": "71",
46 "EventName": "SHA_BLOCKED_CYCLES", 54 "EventName": "SHA_BLOCKED_CYCLES",
47 "BriefDescription": "SHA Bloced Cycles", 55 "BriefDescription": "SHA Bloced Cycles",
48 "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU" 56 "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU"
49 }, 57 },
50 { 58 {
59 "Unit": "CPU-M-CF",
51 "EventCode": "72", 60 "EventCode": "72",
52 "EventName": "DEA_FUNCTIONS", 61 "EventName": "DEA_FUNCTIONS",
53 "BriefDescription": "DEA Functions", 62 "BriefDescription": "DEA Functions",
54 "PublicDescription": "Total number of the DEA functions issued by the CPU" 63 "PublicDescription": "Total number of the DEA functions issued by the CPU"
55 }, 64 },
56 { 65 {
66 "Unit": "CPU-M-CF",
57 "EventCode": "73", 67 "EventCode": "73",
58 "EventName": "DEA_CYCLES", 68 "EventName": "DEA_CYCLES",
59 "BriefDescription": "DEA Cycles", 69 "BriefDescription": "DEA Cycles",
60 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU" 70 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU"
61 }, 71 },
62 { 72 {
73 "Unit": "CPU-M-CF",
63 "EventCode": "74", 74 "EventCode": "74",
64 "EventName": "DEA_BLOCKED_FUNCTIONS", 75 "EventName": "DEA_BLOCKED_FUNCTIONS",
65 "BriefDescription": "DEA Blocked Functions", 76 "BriefDescription": "DEA Blocked Functions",
66 "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" 77 "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
67 }, 78 },
68 { 79 {
80 "Unit": "CPU-M-CF",
69 "EventCode": "75", 81 "EventCode": "75",
70 "EventName": "DEA_BLOCKED_CYCLES", 82 "EventName": "DEA_BLOCKED_CYCLES",
71 "BriefDescription": "DEA Blocked Cycles", 83 "BriefDescription": "DEA Blocked Cycles",
72 "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" 84 "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
73 }, 85 },
74 { 86 {
87 "Unit": "CPU-M-CF",
75 "EventCode": "76", 88 "EventCode": "76",
76 "EventName": "AES_FUNCTIONS", 89 "EventName": "AES_FUNCTIONS",
77 "BriefDescription": "AES Functions", 90 "BriefDescription": "AES Functions",
78 "PublicDescription": "Total number of AES functions issued by the CPU" 91 "PublicDescription": "Total number of AES functions issued by the CPU"
79 }, 92 },
80 { 93 {
94 "Unit": "CPU-M-CF",
81 "EventCode": "77", 95 "EventCode": "77",
82 "EventName": "AES_CYCLES", 96 "EventName": "AES_CYCLES",
83 "BriefDescription": "AES Cycles", 97 "BriefDescription": "AES Cycles",
84 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU" 98 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU"
85 }, 99 },
86 { 100 {
101 "Unit": "CPU-M-CF",
87 "EventCode": "78", 102 "EventCode": "78",
88 "EventName": "AES_BLOCKED_FUNCTIONS", 103 "EventName": "AES_BLOCKED_FUNCTIONS",
89 "BriefDescription": "AES Blocked Functions", 104 "BriefDescription": "AES Blocked Functions",
90 "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" 105 "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
91 }, 106 },
92 { 107 {
108 "Unit": "CPU-M-CF",
93 "EventCode": "79", 109 "EventCode": "79",
94 "EventName": "AES_BLOCKED_CYCLES", 110 "EventName": "AES_BLOCKED_CYCLES",
95 "BriefDescription": "AES Blocked Cycles", 111 "BriefDescription": "AES Blocked Cycles",
diff --git a/tools/perf/pmu-events/arch/s390/cf_z13/extended.json b/tools/perf/pmu-events/arch/s390/cf_z13/extended.json
index 9a002b6967f1..436ce33f1182 100644
--- a/tools/perf/pmu-events/arch/s390/cf_z13/extended.json
+++ b/tools/perf/pmu-events/arch/s390/cf_z13/extended.json
@@ -1,335 +1,391 @@
1[ 1[
2 { 2 {
3 "Unit": "CPU-M-CF",
3 "EventCode": "128", 4 "EventCode": "128",
4 "EventName": "L1D_RO_EXCL_WRITES", 5 "EventName": "L1D_RO_EXCL_WRITES",
5 "BriefDescription": "L1D Read-only Exclusive Writes", 6 "BriefDescription": "L1D Read-only Exclusive Writes",
6 "PublicDescription": "A directory write to the Level-1 Data cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line." 7 "PublicDescription": "A directory write to the Level-1 Data cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line."
7 }, 8 },
8 { 9 {
10 "Unit": "CPU-M-CF",
9 "EventCode": "129", 11 "EventCode": "129",
10 "EventName": "DTLB1_WRITES", 12 "EventName": "DTLB1_WRITES",
11 "BriefDescription": "DTLB1 Writes", 13 "BriefDescription": "DTLB1 Writes",
12 "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer" 14 "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer"
13 }, 15 },
14 { 16 {
17 "Unit": "CPU-M-CF",
15 "EventCode": "130", 18 "EventCode": "130",
16 "EventName": "DTLB1_MISSES", 19 "EventName": "DTLB1_MISSES",
17 "BriefDescription": "DTLB1 Misses", 20 "BriefDescription": "DTLB1 Misses",
18 "PublicDescription": "Level-1 Data TLB miss in progress. Incremented by one for every cycle a DTLB1 miss is in progress." 21 "PublicDescription": "Level-1 Data TLB miss in progress. Incremented by one for every cycle a DTLB1 miss is in progress."
19 }, 22 },
20 { 23 {
24 "Unit": "CPU-M-CF",
21 "EventCode": "131", 25 "EventCode": "131",
22 "EventName": "DTLB1_HPAGE_WRITES", 26 "EventName": "DTLB1_HPAGE_WRITES",
23 "BriefDescription": "DTLB1 One-Megabyte Page Writes", 27 "BriefDescription": "DTLB1 One-Megabyte Page Writes",
24 "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer for a one-megabyte page" 28 "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer for a one-megabyte page"
25 }, 29 },
26 { 30 {
31 "Unit": "CPU-M-CF",
27 "EventCode": "132", 32 "EventCode": "132",
28 "EventName": "DTLB1_GPAGE_WRITES", 33 "EventName": "DTLB1_GPAGE_WRITES",
29 "BriefDescription": "DTLB1 Two-Gigabyte Page Writes", 34 "BriefDescription": "DTLB1 Two-Gigabyte Page Writes",
30 "PublicDescription": "Counter:132 Name:DTLB1_GPAGE_WRITES A translation entry has been written to the Level-1 Data Translation Lookaside Buffer for a two-gigabyte page." 35 "PublicDescription": "Counter:132 Name:DTLB1_GPAGE_WRITES A translation entry has been written to the Level-1 Data Translation Lookaside Buffer for a two-gigabyte page."
31 }, 36 },
32 { 37 {
38 "Unit": "CPU-M-CF",
33 "EventCode": "133", 39 "EventCode": "133",
34 "EventName": "L1D_L2D_SOURCED_WRITES", 40 "EventName": "L1D_L2D_SOURCED_WRITES",
35 "BriefDescription": "L1D L2D Sourced Writes", 41 "BriefDescription": "L1D L2D Sourced Writes",
36 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Data cache" 42 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Data cache"
37 }, 43 },
38 { 44 {
45 "Unit": "CPU-M-CF",
39 "EventCode": "134", 46 "EventCode": "134",
40 "EventName": "ITLB1_WRITES", 47 "EventName": "ITLB1_WRITES",
41 "BriefDescription": "ITLB1 Writes", 48 "BriefDescription": "ITLB1 Writes",
42 "PublicDescription": "A translation entry has been written to the Level-1 Instruction Translation Lookaside Buffer" 49 "PublicDescription": "A translation entry has been written to the Level-1 Instruction Translation Lookaside Buffer"
43 }, 50 },
44 { 51 {
52 "Unit": "CPU-M-CF",
45 "EventCode": "135", 53 "EventCode": "135",
46 "EventName": "ITLB1_MISSES", 54 "EventName": "ITLB1_MISSES",
47 "BriefDescription": "ITLB1 Misses", 55 "BriefDescription": "ITLB1 Misses",
48 "PublicDescription": "Level-1 Instruction TLB miss in progress. Incremented by one for every cycle an ITLB1 miss is in progress" 56 "PublicDescription": "Level-1 Instruction TLB miss in progress. Incremented by one for every cycle an ITLB1 miss is in progress"
49 }, 57 },
50 { 58 {
59 "Unit": "CPU-M-CF",
51 "EventCode": "136", 60 "EventCode": "136",
52 "EventName": "L1I_L2I_SOURCED_WRITES", 61 "EventName": "L1I_L2I_SOURCED_WRITES",
53 "BriefDescription": "L1I L2I Sourced Writes", 62 "BriefDescription": "L1I L2I Sourced Writes",
54 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from the Level-2 Instruction cache" 63 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from the Level-2 Instruction cache"
55 }, 64 },
56 { 65 {
66 "Unit": "CPU-M-CF",
57 "EventCode": "137", 67 "EventCode": "137",
58 "EventName": "TLB2_PTE_WRITES", 68 "EventName": "TLB2_PTE_WRITES",
59 "BriefDescription": "TLB2 PTE Writes", 69 "BriefDescription": "TLB2 PTE Writes",
60 "PublicDescription": "A translation entry has been written to the Level-2 TLB Page Table Entry arrays" 70 "PublicDescription": "A translation entry has been written to the Level-2 TLB Page Table Entry arrays"
61 }, 71 },
62 { 72 {
73 "Unit": "CPU-M-CF",
63 "EventCode": "138", 74 "EventCode": "138",
64 "EventName": "TLB2_CRSTE_HPAGE_WRITES", 75 "EventName": "TLB2_CRSTE_HPAGE_WRITES",
65 "BriefDescription": "TLB2 CRSTE One-Megabyte Page Writes", 76 "BriefDescription": "TLB2 CRSTE One-Megabyte Page Writes",
66 "PublicDescription": "A translation entry has been written to the Level-2 TLB Combined Region Segment Table Entry arrays for a one-megabyte large page translation" 77 "PublicDescription": "A translation entry has been written to the Level-2 TLB Combined Region Segment Table Entry arrays for a one-megabyte large page translation"
67 }, 78 },
68 { 79 {
80 "Unit": "CPU-M-CF",
69 "EventCode": "139", 81 "EventCode": "139",
70 "EventName": "TLB2_CRSTE_WRITES", 82 "EventName": "TLB2_CRSTE_WRITES",
71 "BriefDescription": "TLB2 CRSTE Writes", 83 "BriefDescription": "TLB2 CRSTE Writes",
72 "PublicDescription": "A translation entry has been written to the Level-2 TLB Combined Region Segment Table Entry arrays" 84 "PublicDescription": "A translation entry has been written to the Level-2 TLB Combined Region Segment Table Entry arrays"
73 }, 85 },
74 { 86 {
87 "Unit": "CPU-M-CF",
75 "EventCode": "140", 88 "EventCode": "140",
76 "EventName": "TX_C_TEND", 89 "EventName": "TX_C_TEND",
77 "BriefDescription": "Completed TEND instructions in constrained TX mode", 90 "BriefDescription": "Completed TEND instructions in constrained TX mode",
78 "PublicDescription": "A TEND instruction has completed in a constrained transactional-execution mode" 91 "PublicDescription": "A TEND instruction has completed in a constrained transactional-execution mode"
79 }, 92 },
80 { 93 {
94 "Unit": "CPU-M-CF",
81 "EventCode": "141", 95 "EventCode": "141",
82 "EventName": "TX_NC_TEND", 96 "EventName": "TX_NC_TEND",
83 "BriefDescription": "Completed TEND instructions in non-constrained TX mode", 97 "BriefDescription": "Completed TEND instructions in non-constrained TX mode",
84 "PublicDescription": "A TEND instruction has completed in a non-constrained transactional-execution mode" 98 "PublicDescription": "A TEND instruction has completed in a non-constrained transactional-execution mode"
85 }, 99 },
86 { 100 {
101 "Unit": "CPU-M-CF",
87 "EventCode": "143", 102 "EventCode": "143",
88 "EventName": "L1C_TLB1_MISSES", 103 "EventName": "L1C_TLB1_MISSES",
89 "BriefDescription": "L1C TLB1 Misses", 104 "BriefDescription": "L1C TLB1 Misses",
90 "PublicDescription": "Increments by one for any cycle where a Level-1 cache or Level-1 TLB miss is in progress." 105 "PublicDescription": "Increments by one for any cycle where a Level-1 cache or Level-1 TLB miss is in progress."
91 }, 106 },
92 { 107 {
108 "Unit": "CPU-M-CF",
93 "EventCode": "144", 109 "EventCode": "144",
94 "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES", 110 "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES",
95 "BriefDescription": "L1D On-Chip L3 Sourced Writes", 111 "BriefDescription": "L1D On-Chip L3 Sourced Writes",
96 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache without intervention" 112 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache without intervention"
97 }, 113 },
98 { 114 {
115 "Unit": "CPU-M-CF",
99 "EventCode": "145", 116 "EventCode": "145",
100 "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_IV", 117 "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_IV",
101 "BriefDescription": "L1D On-Chip L3 Sourced Writes with Intervention", 118 "BriefDescription": "L1D On-Chip L3 Sourced Writes with Intervention",
102 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache with intervention" 119 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache with intervention"
103 }, 120 },
104 { 121 {
122 "Unit": "CPU-M-CF",
105 "EventCode": "146", 123 "EventCode": "146",
106 "EventName": "L1D_ONNODE_L4_SOURCED_WRITES", 124 "EventName": "L1D_ONNODE_L4_SOURCED_WRITES",
107 "BriefDescription": "L1D On-Node L4 Sourced Writes", 125 "BriefDescription": "L1D On-Node L4 Sourced Writes",
108 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Node Level-4 cache" 126 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Node Level-4 cache"
109 }, 127 },
110 { 128 {
129 "Unit": "CPU-M-CF",
111 "EventCode": "147", 130 "EventCode": "147",
112 "EventName": "L1D_ONNODE_L3_SOURCED_WRITES_IV", 131 "EventName": "L1D_ONNODE_L3_SOURCED_WRITES_IV",
113 "BriefDescription": "L1D On-Node L3 Sourced Writes with Intervention", 132 "BriefDescription": "L1D On-Node L3 Sourced Writes with Intervention",
114 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Node Level-3 cache with intervention" 133 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Node Level-3 cache with intervention"
115 }, 134 },
116 { 135 {
136 "Unit": "CPU-M-CF",
117 "EventCode": "148", 137 "EventCode": "148",
118 "EventName": "L1D_ONNODE_L3_SOURCED_WRITES", 138 "EventName": "L1D_ONNODE_L3_SOURCED_WRITES",
119 "BriefDescription": "L1D On-Node L3 Sourced Writes", 139 "BriefDescription": "L1D On-Node L3 Sourced Writes",
120 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Node Level-3 cache without intervention" 140 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Node Level-3 cache without intervention"
121 }, 141 },
122 { 142 {
143 "Unit": "CPU-M-CF",
123 "EventCode": "149", 144 "EventCode": "149",
124 "EventName": "L1D_ONDRAWER_L4_SOURCED_WRITES", 145 "EventName": "L1D_ONDRAWER_L4_SOURCED_WRITES",
125 "BriefDescription": "L1D On-Drawer L4 Sourced Writes", 146 "BriefDescription": "L1D On-Drawer L4 Sourced Writes",
126 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Drawer Level-4 cache" 147 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Drawer Level-4 cache"
127 }, 148 },
128 { 149 {
150 "Unit": "CPU-M-CF",
129 "EventCode": "150", 151 "EventCode": "150",
130 "EventName": "L1D_ONDRAWER_L3_SOURCED_WRITES_IV", 152 "EventName": "L1D_ONDRAWER_L3_SOURCED_WRITES_IV",
131 "BriefDescription": "L1D On-Drawer L3 Sourced Writes with Intervention", 153 "BriefDescription": "L1D On-Drawer L3 Sourced Writes with Intervention",
132 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Drawer Level-3 cache with intervention" 154 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Drawer Level-3 cache with intervention"
133 }, 155 },
134 { 156 {
157 "Unit": "CPU-M-CF",
135 "EventCode": "151", 158 "EventCode": "151",
136 "EventName": "L1D_ONDRAWER_L3_SOURCED_WRITES", 159 "EventName": "L1D_ONDRAWER_L3_SOURCED_WRITES",
137 "BriefDescription": "L1D On-Drawer L3 Sourced Writes", 160 "BriefDescription": "L1D On-Drawer L3 Sourced Writes",
138 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Drawer Level-3 cache without intervention" 161 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Drawer Level-3 cache without intervention"
139 }, 162 },
140 { 163 {
164 "Unit": "CPU-M-CF",
141 "EventCode": "152", 165 "EventCode": "152",
142 "EventName": "L1D_OFFDRAWER_SCOL_L4_SOURCED_WRITES", 166 "EventName": "L1D_OFFDRAWER_SCOL_L4_SOURCED_WRITES",
143 "BriefDescription": "L1D Off-Drawer Same-Column L4 Sourced Writes", 167 "BriefDescription": "L1D Off-Drawer Same-Column L4 Sourced Writes",
144 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-4 cache" 168 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-4 cache"
145 }, 169 },
146 { 170 {
171 "Unit": "CPU-M-CF",
147 "EventCode": "153", 172 "EventCode": "153",
148 "EventName": "L1D_OFFDRAWER_SCOL_L3_SOURCED_WRITES_IV", 173 "EventName": "L1D_OFFDRAWER_SCOL_L3_SOURCED_WRITES_IV",
149 "BriefDescription": "L1D Off-Drawer Same-Column L3 Sourced Writes with Intervention", 174 "BriefDescription": "L1D Off-Drawer Same-Column L3 Sourced Writes with Intervention",
150 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-3 cache with intervention" 175 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-3 cache with intervention"
151 }, 176 },
152 { 177 {
178 "Unit": "CPU-M-CF",
153 "EventCode": "154", 179 "EventCode": "154",
154 "EventName": "L1D_OFFDRAWER_SCOL_L3_SOURCED_WRITES", 180 "EventName": "L1D_OFFDRAWER_SCOL_L3_SOURCED_WRITES",
155 "BriefDescription": "L1D Off-Drawer Same-Column L3 Sourced Writes", 181 "BriefDescription": "L1D Off-Drawer Same-Column L3 Sourced Writes",
156 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-3 cache without intervention" 182 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-3 cache without intervention"
157 }, 183 },
158 { 184 {
185 "Unit": "CPU-M-CF",
159 "EventCode": "155", 186 "EventCode": "155",
160 "EventName": "L1D_OFFDRAWER_FCOL_L4_SOURCED_WRITES", 187 "EventName": "L1D_OFFDRAWER_FCOL_L4_SOURCED_WRITES",
161 "BriefDescription": "L1D Off-Drawer Far-Column L3 Sourced Writes", 188 "BriefDescription": "L1D Off-Drawer Far-Column L3 Sourced Writes",
162 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-4 cache" 189 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-4 cache"
163 }, 190 },
164 { 191 {
192 "Unit": "CPU-M-CF",
165 "EventCode": "156", 193 "EventCode": "156",
166 "EventName": "L1D_OFFDRAWER_FCOL_L3_SOURCED_WRITES_IV", 194 "EventName": "L1D_OFFDRAWER_FCOL_L3_SOURCED_WRITES_IV",
167 "BriefDescription": "L1D Off-Drawer Far-Column L3 Sourced Writes with Intervention", 195 "BriefDescription": "L1D Off-Drawer Far-Column L3 Sourced Writes with Intervention",
168 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-3 cache with intervention" 196 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-3 cache with intervention"
169 }, 197 },
170 { 198 {
199 "Unit": "CPU-M-CF",
171 "EventCode": "157", 200 "EventCode": "157",
172 "EventName": "L1D_OFFDRAWER_FCOL_L3_SOURCED_WRITES", 201 "EventName": "L1D_OFFDRAWER_FCOL_L3_SOURCED_WRITES",
173 "BriefDescription": "L1D Off-Drawer Far-Column L3 Sourced Writes", 202 "BriefDescription": "L1D Off-Drawer Far-Column L3 Sourced Writes",
174 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-3 cache without intervention" 203 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-3 cache without intervention"
175 }, 204 },
176 { 205 {
206 "Unit": "CPU-M-CF",
177 "EventCode": "158", 207 "EventCode": "158",
178 "EventName": "L1D_ONNODE_MEM_SOURCED_WRITES", 208 "EventName": "L1D_ONNODE_MEM_SOURCED_WRITES",
179 "BriefDescription": "L1D On-Node Memory Sourced Writes", 209 "BriefDescription": "L1D On-Node Memory Sourced Writes",
180 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Node memory" 210 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Node memory"
181 }, 211 },
182 { 212 {
213 "Unit": "CPU-M-CF",
183 "EventCode": "159", 214 "EventCode": "159",
184 "EventName": "L1D_ONDRAWER_MEM_SOURCED_WRITES", 215 "EventName": "L1D_ONDRAWER_MEM_SOURCED_WRITES",
185 "BriefDescription": "L1D On-Drawer Memory Sourced Writes", 216 "BriefDescription": "L1D On-Drawer Memory Sourced Writes",
186 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Drawer memory" 217 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Drawer memory"
187 }, 218 },
188 { 219 {
220 "Unit": "CPU-M-CF",
189 "EventCode": "160", 221 "EventCode": "160",
190 "EventName": "L1D_OFFDRAWER_MEM_SOURCED_WRITES", 222 "EventName": "L1D_OFFDRAWER_MEM_SOURCED_WRITES",
191 "BriefDescription": "L1D Off-Drawer Memory Sourced Writes", 223 "BriefDescription": "L1D Off-Drawer Memory Sourced Writes",
192 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Drawer memory" 224 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Drawer memory"
193 }, 225 },
194 { 226 {
227 "Unit": "CPU-M-CF",
195 "EventCode": "161", 228 "EventCode": "161",
196 "EventName": "L1D_ONCHIP_MEM_SOURCED_WRITES", 229 "EventName": "L1D_ONCHIP_MEM_SOURCED_WRITES",
197 "BriefDescription": "L1D On-Chip Memory Sourced Writes", 230 "BriefDescription": "L1D On-Chip Memory Sourced Writes",
198 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip memory" 231 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip memory"
199 }, 232 },
200 { 233 {
234 "Unit": "CPU-M-CF",
201 "EventCode": "162", 235 "EventCode": "162",
202 "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES", 236 "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES",
203 "BriefDescription": "L1I On-Chip L3 Sourced Writes", 237 "BriefDescription": "L1I On-Chip L3 Sourced Writes",
204 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Chip Level-3 cache without intervention" 238 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Chip Level-3 cache without intervention"
205 }, 239 },
206 { 240 {
241 "Unit": "CPU-M-CF",
207 "EventCode": "163", 242 "EventCode": "163",
208 "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES_IV", 243 "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES_IV",
209 "BriefDescription": "L1I On-Chip L3 Sourced Writes with Intervention", 244 "BriefDescription": "L1I On-Chip L3 Sourced Writes with Intervention",
210 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On Chip Level-3 cache with intervention" 245 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On Chip Level-3 cache with intervention"
211 }, 246 },
212 { 247 {
248 "Unit": "CPU-M-CF",
213 "EventCode": "164", 249 "EventCode": "164",
214 "EventName": "L1I_ONNODE_L4_SOURCED_WRITES", 250 "EventName": "L1I_ONNODE_L4_SOURCED_WRITES",
215 "BriefDescription": "L1I On-Chip L4 Sourced Writes", 251 "BriefDescription": "L1I On-Chip L4 Sourced Writes",
216 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Node Level-4 cache" 252 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Node Level-4 cache"
217 }, 253 },
218 { 254 {
255 "Unit": "CPU-M-CF",
219 "EventCode": "165", 256 "EventCode": "165",
220 "EventName": "L1I_ONNODE_L3_SOURCED_WRITES_IV", 257 "EventName": "L1I_ONNODE_L3_SOURCED_WRITES_IV",
221 "BriefDescription": "L1I On-Node L3 Sourced Writes with Intervention", 258 "BriefDescription": "L1I On-Node L3 Sourced Writes with Intervention",
222 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Node Level-3 cache with intervention" 259 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Node Level-3 cache with intervention"
223 }, 260 },
224 { 261 {
262 "Unit": "CPU-M-CF",
225 "EventCode": "166", 263 "EventCode": "166",
226 "EventName": "L1I_ONNODE_L3_SOURCED_WRITES", 264 "EventName": "L1I_ONNODE_L3_SOURCED_WRITES",
227 "BriefDescription": "L1I On-Node L3 Sourced Writes", 265 "BriefDescription": "L1I On-Node L3 Sourced Writes",
228 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Node Level-3 cache without intervention" 266 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Node Level-3 cache without intervention"
229 }, 267 },
230 { 268 {
269 "Unit": "CPU-M-CF",
231 "EventCode": "167", 270 "EventCode": "167",
232 "EventName": "L1I_ONDRAWER_L4_SOURCED_WRITES", 271 "EventName": "L1I_ONDRAWER_L4_SOURCED_WRITES",
233 "BriefDescription": "L1I On-Drawer L4 Sourced Writes", 272 "BriefDescription": "L1I On-Drawer L4 Sourced Writes",
234 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Drawer Level-4 cache" 273 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Drawer Level-4 cache"
235 }, 274 },
236 { 275 {
276 "Unit": "CPU-M-CF",
237 "EventCode": "168", 277 "EventCode": "168",
238 "EventName": "L1I_ONDRAWER_L3_SOURCED_WRITES_IV", 278 "EventName": "L1I_ONDRAWER_L3_SOURCED_WRITES_IV",
239 "BriefDescription": "L1I On-Drawer L3 Sourced Writes with Intervention", 279 "BriefDescription": "L1I On-Drawer L3 Sourced Writes with Intervention",
240 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Drawer Level-3 cache with intervention" 280 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Drawer Level-3 cache with intervention"
241 }, 281 },
242 { 282 {
283 "Unit": "CPU-M-CF",
243 "EventCode": "169", 284 "EventCode": "169",
244 "EventName": "L1I_ONDRAWER_L3_SOURCED_WRITES", 285 "EventName": "L1I_ONDRAWER_L3_SOURCED_WRITES",
245 "BriefDescription": "L1I On-Drawer L3 Sourced Writes", 286 "BriefDescription": "L1I On-Drawer L3 Sourced Writes",
246 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Drawer Level-3 cache without intervention" 287 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Drawer Level-3 cache without intervention"
247 }, 288 },
248 { 289 {
290 "Unit": "CPU-M-CF",
249 "EventCode": "170", 291 "EventCode": "170",
250 "EventName": "L1I_OFFDRAWER_SCOL_L4_SOURCED_WRITES", 292 "EventName": "L1I_OFFDRAWER_SCOL_L4_SOURCED_WRITES",
251 "BriefDescription": "L1I Off-Drawer Same-Column L4 Sourced Writes", 293 "BriefDescription": "L1I Off-Drawer Same-Column L4 Sourced Writes",
252 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-4 cache" 294 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-4 cache"
253 }, 295 },
254 { 296 {
297 "Unit": "CPU-M-CF",
255 "EventCode": "171", 298 "EventCode": "171",
256 "EventName": "L1I_OFFDRAWER_SCOL_L3_SOURCED_WRITES_IV", 299 "EventName": "L1I_OFFDRAWER_SCOL_L3_SOURCED_WRITES_IV",
257 "BriefDescription": "L1I Off-Drawer Same-Column L3 Sourced Writes with Intervention", 300 "BriefDescription": "L1I Off-Drawer Same-Column L3 Sourced Writes with Intervention",
258 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-3 cache with intervention" 301 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-3 cache with intervention"
259 }, 302 },
260 { 303 {
304 "Unit": "CPU-M-CF",
261 "EventCode": "172", 305 "EventCode": "172",
262 "EventName": "L1I_OFFDRAWER_SCOL_L3_SOURCED_WRITES", 306 "EventName": "L1I_OFFDRAWER_SCOL_L3_SOURCED_WRITES",
263 "BriefDescription": "L1I Off-Drawer Same-Column L3 Sourced Writes", 307 "BriefDescription": "L1I Off-Drawer Same-Column L3 Sourced Writes",
264 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-3 cache without intervention" 308 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-3 cache without intervention"
265 }, 309 },
266 { 310 {
311 "Unit": "CPU-M-CF",
267 "EventCode": "173", 312 "EventCode": "173",
268 "EventName": "L1I_OFFDRAWER_FCOL_L4_SOURCED_WRITES", 313 "EventName": "L1I_OFFDRAWER_FCOL_L4_SOURCED_WRITES",
269 "BriefDescription": "L1I Off-Drawer Far-Column L4 Sourced Writes", 314 "BriefDescription": "L1I Off-Drawer Far-Column L4 Sourced Writes",
270 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-4 cache" 315 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-4 cache"
271 }, 316 },
272 { 317 {
318 "Unit": "CPU-M-CF",
273 "EventCode": "174", 319 "EventCode": "174",
274 "EventName": "L1I_OFFDRAWER_FCOL_L3_SOURCED_WRITES_IV", 320 "EventName": "L1I_OFFDRAWER_FCOL_L3_SOURCED_WRITES_IV",
275 "BriefDescription": "L1I Off-Drawer Far-Column L3 Sourced Writes with Intervention", 321 "BriefDescription": "L1I Off-Drawer Far-Column L3 Sourced Writes with Intervention",
276 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-3 cache with intervention" 322 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-3 cache with intervention"
277 }, 323 },
278 { 324 {
325 "Unit": "CPU-M-CF",
279 "EventCode": "175", 326 "EventCode": "175",
280 "EventName": "L1I_OFFDRAWER_FCOL_L3_SOURCED_WRITES", 327 "EventName": "L1I_OFFDRAWER_FCOL_L3_SOURCED_WRITES",
281 "BriefDescription": "L1I Off-Drawer Far-Column L3 Sourced Writes", 328 "BriefDescription": "L1I Off-Drawer Far-Column L3 Sourced Writes",
282 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-3 cache without intervention" 329 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-3 cache without intervention"
283 }, 330 },
284 { 331 {
332 "Unit": "CPU-M-CF",
285 "EventCode": "176", 333 "EventCode": "176",
286 "EventName": "L1I_ONNODE_MEM_SOURCED_WRITES", 334 "EventName": "L1I_ONNODE_MEM_SOURCED_WRITES",
287 "BriefDescription": "L1I On-Node Memory Sourced Writes", 335 "BriefDescription": "L1I On-Node Memory Sourced Writes",
288 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Node memory" 336 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Node memory"
289 }, 337 },
290 { 338 {
339 "Unit": "CPU-M-CF",
291 "EventCode": "177", 340 "EventCode": "177",
292 "EventName": "L1I_ONDRAWER_MEM_SOURCED_WRITES", 341 "EventName": "L1I_ONDRAWER_MEM_SOURCED_WRITES",
293 "BriefDescription": "L1I On-Drawer Memory Sourced Writes", 342 "BriefDescription": "L1I On-Drawer Memory Sourced Writes",
294 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Drawer memory" 343 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Drawer memory"
295 }, 344 },
296 { 345 {
346 "Unit": "CPU-M-CF",
297 "EventCode": "178", 347 "EventCode": "178",
298 "EventName": "L1I_OFFDRAWER_MEM_SOURCED_WRITES", 348 "EventName": "L1I_OFFDRAWER_MEM_SOURCED_WRITES",
299 "BriefDescription": "L1I Off-Drawer Memory Sourced Writes", 349 "BriefDescription": "L1I Off-Drawer Memory Sourced Writes",
300 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Drawer memory" 350 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Drawer memory"
301 }, 351 },
302 { 352 {
353 "Unit": "CPU-M-CF",
303 "EventCode": "179", 354 "EventCode": "179",
304 "EventName": "L1I_ONCHIP_MEM_SOURCED_WRITES", 355 "EventName": "L1I_ONCHIP_MEM_SOURCED_WRITES",
305 "BriefDescription": "L1I On-Chip Memory Sourced Writes", 356 "BriefDescription": "L1I On-Chip Memory Sourced Writes",
306 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Chip memory" 357 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Chip memory"
307 }, 358 },
308 { 359 {
360 "Unit": "CPU-M-CF",
309 "EventCode": "218", 361 "EventCode": "218",
310 "EventName": "TX_NC_TABORT", 362 "EventName": "TX_NC_TABORT",
311 "BriefDescription": "Aborted transactions in non-constrained TX mode", 363 "BriefDescription": "Aborted transactions in non-constrained TX mode",
312 "PublicDescription": "A transaction abort has occurred in a non-constrained transactional-execution mode" 364 "PublicDescription": "A transaction abort has occurred in a non-constrained transactional-execution mode"
313 }, 365 },
314 { 366 {
367 "Unit": "CPU-M-CF",
315 "EventCode": "219", 368 "EventCode": "219",
316 "EventName": "TX_C_TABORT_NO_SPECIAL", 369 "EventName": "TX_C_TABORT_NO_SPECIAL",
317 "BriefDescription": "Aborted transactions in constrained TX mode not using special completion logic", 370 "BriefDescription": "Aborted transactions in constrained TX mode not using special completion logic",
318 "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is not using any special logic to allow the transaction to complete" 371 "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is not using any special logic to allow the transaction to complete"
319 }, 372 },
320 { 373 {
374 "Unit": "CPU-M-CF",
321 "EventCode": "220", 375 "EventCode": "220",
322 "EventName": "TX_C_TABORT_SPECIAL", 376 "EventName": "TX_C_TABORT_SPECIAL",
323 "BriefDescription": "Aborted transactions in constrained TX mode using special completion logic", 377 "BriefDescription": "Aborted transactions in constrained TX mode using special completion logic",
324 "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is using special logic to allow the transaction to complete" 378 "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is using special logic to allow the transaction to complete"
325 }, 379 },
326 { 380 {
381 "Unit": "CPU-M-CF",
327 "EventCode": "448", 382 "EventCode": "448",
328 "EventName": "MT_DIAG_CYCLES_ONE_THR_ACTIVE", 383 "EventName": "MT_DIAG_CYCLES_ONE_THR_ACTIVE",
329 "BriefDescription": "Cycle count with one thread active", 384 "BriefDescription": "Cycle count with one thread active",
330 "PublicDescription": "Cycle count with one thread active" 385 "PublicDescription": "Cycle count with one thread active"
331 }, 386 },
332 { 387 {
388 "Unit": "CPU-M-CF",
333 "EventCode": "449", 389 "EventCode": "449",
334 "EventName": "MT_DIAG_CYCLES_TWO_THR_ACTIVE", 390 "EventName": "MT_DIAG_CYCLES_TWO_THR_ACTIVE",
335 "BriefDescription": "Cycle count with two threads active", 391 "BriefDescription": "Cycle count with two threads active",
diff --git a/tools/perf/pmu-events/arch/s390/cf_z13/transaction.json b/tools/perf/pmu-events/arch/s390/cf_z13/transaction.json
new file mode 100644
index 000000000000..1a0034f79f73
--- /dev/null
+++ b/tools/perf/pmu-events/arch/s390/cf_z13/transaction.json
@@ -0,0 +1,7 @@
1[
2 {
3 "BriefDescription": "Transaction count",
4 "MetricName": "transaction",
5 "MetricExpr": "TX_C_TEND + TX_NC_TEND + TX_NC_TABORT + TX_C_TABORT_SPECIAL + TX_C_TABORT_NO_SPECIAL"
6 }
7]
diff --git a/tools/perf/pmu-events/arch/s390/cf_z14/basic.json b/tools/perf/pmu-events/arch/s390/cf_z14/basic.json
index 8f653c9d899d..17fb5241928b 100644
--- a/tools/perf/pmu-events/arch/s390/cf_z14/basic.json
+++ b/tools/perf/pmu-events/arch/s390/cf_z14/basic.json
@@ -1,47 +1,55 @@
1[ 1[
2 { 2 {
3 "Unit": "CPU-M-CF",
3 "EventCode": "0", 4 "EventCode": "0",
4 "EventName": "CPU_CYCLES", 5 "EventName": "CPU_CYCLES",
5 "BriefDescription": "CPU Cycles", 6 "BriefDescription": "CPU Cycles",
6 "PublicDescription": "Cycle Count" 7 "PublicDescription": "Cycle Count"
7 }, 8 },
8 { 9 {
10 "Unit": "CPU-M-CF",
9 "EventCode": "1", 11 "EventCode": "1",
10 "EventName": "INSTRUCTIONS", 12 "EventName": "INSTRUCTIONS",
11 "BriefDescription": "Instructions", 13 "BriefDescription": "Instructions",
12 "PublicDescription": "Instruction Count" 14 "PublicDescription": "Instruction Count"
13 }, 15 },
14 { 16 {
17 "Unit": "CPU-M-CF",
15 "EventCode": "2", 18 "EventCode": "2",
16 "EventName": "L1I_DIR_WRITES", 19 "EventName": "L1I_DIR_WRITES",
17 "BriefDescription": "L1I Directory Writes", 20 "BriefDescription": "L1I Directory Writes",
18 "PublicDescription": "Level-1 I-Cache Directory Write Count" 21 "PublicDescription": "Level-1 I-Cache Directory Write Count"
19 }, 22 },
20 { 23 {
24 "Unit": "CPU-M-CF",
21 "EventCode": "3", 25 "EventCode": "3",
22 "EventName": "L1I_PENALTY_CYCLES", 26 "EventName": "L1I_PENALTY_CYCLES",
23 "BriefDescription": "L1I Penalty Cycles", 27 "BriefDescription": "L1I Penalty Cycles",
24 "PublicDescription": "Level-1 I-Cache Penalty Cycle Count" 28 "PublicDescription": "Level-1 I-Cache Penalty Cycle Count"
25 }, 29 },
26 { 30 {
31 "Unit": "CPU-M-CF",
27 "EventCode": "4", 32 "EventCode": "4",
28 "EventName": "L1D_DIR_WRITES", 33 "EventName": "L1D_DIR_WRITES",
29 "BriefDescription": "L1D Directory Writes", 34 "BriefDescription": "L1D Directory Writes",
30 "PublicDescription": "Level-1 D-Cache Directory Write Count" 35 "PublicDescription": "Level-1 D-Cache Directory Write Count"
31 }, 36 },
32 { 37 {
38 "Unit": "CPU-M-CF",
33 "EventCode": "5", 39 "EventCode": "5",
34 "EventName": "L1D_PENALTY_CYCLES", 40 "EventName": "L1D_PENALTY_CYCLES",
35 "BriefDescription": "L1D Penalty Cycles", 41 "BriefDescription": "L1D Penalty Cycles",
36 "PublicDescription": "Level-1 D-Cache Penalty Cycle Count" 42 "PublicDescription": "Level-1 D-Cache Penalty Cycle Count"
37 }, 43 },
38 { 44 {
45 "Unit": "CPU-M-CF",
39 "EventCode": "32", 46 "EventCode": "32",
40 "EventName": "PROBLEM_STATE_CPU_CYCLES", 47 "EventName": "PROBLEM_STATE_CPU_CYCLES",
41 "BriefDescription": "Problem-State CPU Cycles", 48 "BriefDescription": "Problem-State CPU Cycles",
42 "PublicDescription": "Problem-State Cycle Count" 49 "PublicDescription": "Problem-State Cycle Count"
43 }, 50 },
44 { 51 {
52 "Unit": "CPU-M-CF",
45 "EventCode": "33", 53 "EventCode": "33",
46 "EventName": "PROBLEM_STATE_INSTRUCTIONS", 54 "EventName": "PROBLEM_STATE_INSTRUCTIONS",
47 "BriefDescription": "Problem-State Instructions", 55 "BriefDescription": "Problem-State Instructions",
diff --git a/tools/perf/pmu-events/arch/s390/cf_z14/crypto.json b/tools/perf/pmu-events/arch/s390/cf_z14/crypto.json
index 7e5b72492141..db286f19e7b6 100644
--- a/tools/perf/pmu-events/arch/s390/cf_z14/crypto.json
+++ b/tools/perf/pmu-events/arch/s390/cf_z14/crypto.json
@@ -1,95 +1,111 @@
1[ 1[
2 { 2 {
3 "Unit": "CPU-M-CF",
3 "EventCode": "64", 4 "EventCode": "64",
4 "EventName": "PRNG_FUNCTIONS", 5 "EventName": "PRNG_FUNCTIONS",
5 "BriefDescription": "PRNG Functions", 6 "BriefDescription": "PRNG Functions",
6 "PublicDescription": "Total number of the PRNG functions issued by the CPU" 7 "PublicDescription": "Total number of the PRNG functions issued by the CPU"
7 }, 8 },
8 { 9 {
10 "Unit": "CPU-M-CF",
9 "EventCode": "65", 11 "EventCode": "65",
10 "EventName": "PRNG_CYCLES", 12 "EventName": "PRNG_CYCLES",
11 "BriefDescription": "PRNG Cycles", 13 "BriefDescription": "PRNG Cycles",
12 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU" 14 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU"
13 }, 15 },
14 { 16 {
17 "Unit": "CPU-M-CF",
15 "EventCode": "66", 18 "EventCode": "66",
16 "EventName": "PRNG_BLOCKED_FUNCTIONS", 19 "EventName": "PRNG_BLOCKED_FUNCTIONS",
17 "BriefDescription": "PRNG Blocked Functions", 20 "BriefDescription": "PRNG Blocked Functions",
18 "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" 21 "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
19 }, 22 },
20 { 23 {
24 "Unit": "CPU-M-CF",
21 "EventCode": "67", 25 "EventCode": "67",
22 "EventName": "PRNG_BLOCKED_CYCLES", 26 "EventName": "PRNG_BLOCKED_CYCLES",
23 "BriefDescription": "PRNG Blocked Cycles", 27 "BriefDescription": "PRNG Blocked Cycles",
24 "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" 28 "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
25 }, 29 },
26 { 30 {
31 "Unit": "CPU-M-CF",
27 "EventCode": "68", 32 "EventCode": "68",
28 "EventName": "SHA_FUNCTIONS", 33 "EventName": "SHA_FUNCTIONS",
29 "BriefDescription": "SHA Functions", 34 "BriefDescription": "SHA Functions",
30 "PublicDescription": "Total number of SHA functions issued by the CPU" 35 "PublicDescription": "Total number of SHA functions issued by the CPU"
31 }, 36 },
32 { 37 {
38 "Unit": "CPU-M-CF",
33 "EventCode": "69", 39 "EventCode": "69",
34 "EventName": "SHA_CYCLES", 40 "EventName": "SHA_CYCLES",
35 "BriefDescription": "SHA Cycles", 41 "BriefDescription": "SHA Cycles",
36 "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU" 42 "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU"
37 }, 43 },
38 { 44 {
45 "Unit": "CPU-M-CF",
39 "EventCode": "70", 46 "EventCode": "70",
40 "EventName": "SHA_BLOCKED_FUNCTIONS", 47 "EventName": "SHA_BLOCKED_FUNCTIONS",
41 "BriefDescription": "SHA Blocked Functions", 48 "BriefDescription": "SHA Blocked Functions",
42 "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU" 49 "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU"
43 }, 50 },
44 { 51 {
52 "Unit": "CPU-M-CF",
45 "EventCode": "71", 53 "EventCode": "71",
46 "EventName": "SHA_BLOCKED_CYCLES", 54 "EventName": "SHA_BLOCKED_CYCLES",
47 "BriefDescription": "SHA Bloced Cycles", 55 "BriefDescription": "SHA Bloced Cycles",
48 "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU" 56 "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU"
49 }, 57 },
50 { 58 {
59 "Unit": "CPU-M-CF",
51 "EventCode": "72", 60 "EventCode": "72",
52 "EventName": "DEA_FUNCTIONS", 61 "EventName": "DEA_FUNCTIONS",
53 "BriefDescription": "DEA Functions", 62 "BriefDescription": "DEA Functions",
54 "PublicDescription": "Total number of the DEA functions issued by the CPU" 63 "PublicDescription": "Total number of the DEA functions issued by the CPU"
55 }, 64 },
56 { 65 {
66 "Unit": "CPU-M-CF",
57 "EventCode": "73", 67 "EventCode": "73",
58 "EventName": "DEA_CYCLES", 68 "EventName": "DEA_CYCLES",
59 "BriefDescription": "DEA Cycles", 69 "BriefDescription": "DEA Cycles",
60 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU" 70 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU"
61 }, 71 },
62 { 72 {
73 "Unit": "CPU-M-CF",
63 "EventCode": "74", 74 "EventCode": "74",
64 "EventName": "DEA_BLOCKED_FUNCTIONS", 75 "EventName": "DEA_BLOCKED_FUNCTIONS",
65 "BriefDescription": "DEA Blocked Functions", 76 "BriefDescription": "DEA Blocked Functions",
66 "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" 77 "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
67 }, 78 },
68 { 79 {
80 "Unit": "CPU-M-CF",
69 "EventCode": "75", 81 "EventCode": "75",
70 "EventName": "DEA_BLOCKED_CYCLES", 82 "EventName": "DEA_BLOCKED_CYCLES",
71 "BriefDescription": "DEA Blocked Cycles", 83 "BriefDescription": "DEA Blocked Cycles",
72 "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" 84 "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
73 }, 85 },
74 { 86 {
87 "Unit": "CPU-M-CF",
75 "EventCode": "76", 88 "EventCode": "76",
76 "EventName": "AES_FUNCTIONS", 89 "EventName": "AES_FUNCTIONS",
77 "BriefDescription": "AES Functions", 90 "BriefDescription": "AES Functions",
78 "PublicDescription": "Total number of AES functions issued by the CPU" 91 "PublicDescription": "Total number of AES functions issued by the CPU"
79 }, 92 },
80 { 93 {
94 "Unit": "CPU-M-CF",
81 "EventCode": "77", 95 "EventCode": "77",
82 "EventName": "AES_CYCLES", 96 "EventName": "AES_CYCLES",
83 "BriefDescription": "AES Cycles", 97 "BriefDescription": "AES Cycles",
84 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU" 98 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU"
85 }, 99 },
86 { 100 {
101 "Unit": "CPU-M-CF",
87 "EventCode": "78", 102 "EventCode": "78",
88 "EventName": "AES_BLOCKED_FUNCTIONS", 103 "EventName": "AES_BLOCKED_FUNCTIONS",
89 "BriefDescription": "AES Blocked Functions", 104 "BriefDescription": "AES Blocked Functions",
90 "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" 105 "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
91 }, 106 },
92 { 107 {
108 "Unit": "CPU-M-CF",
93 "EventCode": "79", 109 "EventCode": "79",
94 "EventName": "AES_BLOCKED_CYCLES", 110 "EventName": "AES_BLOCKED_CYCLES",
95 "BriefDescription": "AES Blocked Cycles", 111 "BriefDescription": "AES Blocked Cycles",
diff --git a/tools/perf/pmu-events/arch/s390/cf_z14/extended.json b/tools/perf/pmu-events/arch/s390/cf_z14/extended.json
index aa4dfb46b65b..e7a3524b748f 100644
--- a/tools/perf/pmu-events/arch/s390/cf_z14/extended.json
+++ b/tools/perf/pmu-events/arch/s390/cf_z14/extended.json
@@ -1,317 +1,370 @@
1[ 1[
2 { 2 {
3 "Unit": "CPU-M-CF",
3 "EventCode": "128", 4 "EventCode": "128",
4 "EventName": "L1D_RO_EXCL_WRITES", 5 "EventName": "L1D_RO_EXCL_WRITES",
5 "BriefDescription": "L1D Read-only Exclusive Writes", 6 "BriefDescription": "L1D Read-only Exclusive Writes",
6 "PublicDescription": "Counter:128 Name:L1D_RO_EXCL_WRITES A directory write to the Level-1 Data cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line" 7 "PublicDescription": "Counter:128 Name:L1D_RO_EXCL_WRITES A directory write to the Level-1 Data cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line"
7 }, 8 },
8 { 9 {
10 "Unit": "CPU-M-CF",
9 "EventCode": "129", 11 "EventCode": "129",
10 "EventName": "DTLB2_WRITES", 12 "EventName": "DTLB2_WRITES",
11 "BriefDescription": "DTLB2 Writes", 13 "BriefDescription": "DTLB2 Writes",
12 "PublicDescription": "A translation has been written into The Translation Lookaside Buffer 2 (TLB2) and the request was made by the data cache" 14 "PublicDescription": "A translation has been written into The Translation Lookaside Buffer 2 (TLB2) and the request was made by the data cache"
13 }, 15 },
14 { 16 {
17 "Unit": "CPU-M-CF",
15 "EventCode": "130", 18 "EventCode": "130",
16 "EventName": "DTLB2_MISSES", 19 "EventName": "DTLB2_MISSES",
17 "BriefDescription": "DTLB2 Misses", 20 "BriefDescription": "DTLB2 Misses",
18 "PublicDescription": "A TLB2 miss is in progress for a request made by the data cache. Incremented by one for every TLB2 miss in progress for the Level-1 Data cache on this cycle" 21 "PublicDescription": "A TLB2 miss is in progress for a request made by the data cache. Incremented by one for every TLB2 miss in progress for the Level-1 Data cache on this cycle"
19 }, 22 },
20 { 23 {
24 "Unit": "CPU-M-CF",
21 "EventCode": "131", 25 "EventCode": "131",
22 "EventName": "DTLB2_HPAGE_WRITES", 26 "EventName": "DTLB2_HPAGE_WRITES",
23 "BriefDescription": "DTLB2 One-Megabyte Page Writes", 27 "BriefDescription": "DTLB2 One-Megabyte Page Writes",
24 "PublicDescription": "A translation entry was written into the Combined Region and Segment Table Entry array in the Level-2 TLB for a one-megabyte page or a Last Host Translation was done" 28 "PublicDescription": "A translation entry was written into the Combined Region and Segment Table Entry array in the Level-2 TLB for a one-megabyte page or a Last Host Translation was done"
25 }, 29 },
26 { 30 {
31 "Unit": "CPU-M-CF",
27 "EventCode": "132", 32 "EventCode": "132",
28 "EventName": "DTLB2_GPAGE_WRITES", 33 "EventName": "DTLB2_GPAGE_WRITES",
29 "BriefDescription": "DTLB2 Two-Gigabyte Page Writes", 34 "BriefDescription": "DTLB2 Two-Gigabyte Page Writes",
30 "PublicDescription": "A translation entry for a two-gigabyte page was written into the Level-2 TLB" 35 "PublicDescription": "A translation entry for a two-gigabyte page was written into the Level-2 TLB"
31 }, 36 },
32 { 37 {
38 "Unit": "CPU-M-CF",
33 "EventCode": "133", 39 "EventCode": "133",
34 "EventName": "L1D_L2D_SOURCED_WRITES", 40 "EventName": "L1D_L2D_SOURCED_WRITES",
35 "BriefDescription": "L1D L2D Sourced Writes", 41 "BriefDescription": "L1D L2D Sourced Writes",
36 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Data cache" 42 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Data cache"
37 }, 43 },
38 { 44 {
45 "Unit": "CPU-M-CF",
39 "EventCode": "134", 46 "EventCode": "134",
40 "EventName": "ITLB2_WRITES", 47 "EventName": "ITLB2_WRITES",
41 "BriefDescription": "ITLB2 Writes", 48 "BriefDescription": "ITLB2 Writes",
42 "PublicDescription": "A translation entry has been written into the Translation Lookaside Buffer 2 (TLB2) and the request was made by the instruction cache" 49 "PublicDescription": "A translation entry has been written into the Translation Lookaside Buffer 2 (TLB2) and the request was made by the instruction cache"
43 }, 50 },
44 { 51 {
52 "Unit": "CPU-M-CF",
45 "EventCode": "135", 53 "EventCode": "135",
46 "EventName": "ITLB2_MISSES", 54 "EventName": "ITLB2_MISSES",
47 "BriefDescription": "ITLB2 Misses", 55 "BriefDescription": "ITLB2 Misses",
48 "PublicDescription": "A TLB2 miss is in progress for a request made by the instruction cache. Incremented by one for every TLB2 miss in progress for the Level-1 Instruction cache in a cycle" 56 "PublicDescription": "A TLB2 miss is in progress for a request made by the instruction cache. Incremented by one for every TLB2 miss in progress for the Level-1 Instruction cache in a cycle"
49 }, 57 },
50 { 58 {
59 "Unit": "CPU-M-CF",
51 "EventCode": "136", 60 "EventCode": "136",
52 "EventName": "L1I_L2I_SOURCED_WRITES", 61 "EventName": "L1I_L2I_SOURCED_WRITES",
53 "BriefDescription": "L1I L2I Sourced Writes", 62 "BriefDescription": "L1I L2I Sourced Writes",
54 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from the Level-2 Instruction cache" 63 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from the Level-2 Instruction cache"
55 }, 64 },
56 { 65 {
66 "Unit": "CPU-M-CF",
57 "EventCode": "137", 67 "EventCode": "137",
58 "EventName": "TLB2_PTE_WRITES", 68 "EventName": "TLB2_PTE_WRITES",
59 "BriefDescription": "TLB2 PTE Writes", 69 "BriefDescription": "TLB2 PTE Writes",
60 "PublicDescription": "A translation entry was written into the Page Table Entry array in the Level-2 TLB" 70 "PublicDescription": "A translation entry was written into the Page Table Entry array in the Level-2 TLB"
61 }, 71 },
62 { 72 {
73 "Unit": "CPU-M-CF",
63 "EventCode": "138", 74 "EventCode": "138",
64 "EventName": "TLB2_CRSTE_WRITES", 75 "EventName": "TLB2_CRSTE_WRITES",
65 "BriefDescription": "TLB2 CRSTE Writes", 76 "BriefDescription": "TLB2 CRSTE Writes",
66 "PublicDescription": "Translation entries were written into the Combined Region and Segment Table Entry array and the Page Table Entry array in the Level-2 TLB" 77 "PublicDescription": "Translation entries were written into the Combined Region and Segment Table Entry array and the Page Table Entry array in the Level-2 TLB"
67 }, 78 },
68 { 79 {
80 "Unit": "CPU-M-CF",
69 "EventCode": "139", 81 "EventCode": "139",
70 "EventName": "TLB2_ENGINES_BUSY", 82 "EventName": "TLB2_ENGINES_BUSY",
71 "BriefDescription": "TLB2 Engines Busy", 83 "BriefDescription": "TLB2 Engines Busy",
72 "PublicDescription": "The number of Level-2 TLB translation engines busy in a cycle" 84 "PublicDescription": "The number of Level-2 TLB translation engines busy in a cycle"
73 }, 85 },
74 { 86 {
87 "Unit": "CPU-M-CF",
75 "EventCode": "140", 88 "EventCode": "140",
76 "EventName": "TX_C_TEND", 89 "EventName": "TX_C_TEND",
77 "BriefDescription": "Completed TEND instructions in constrained TX mode", 90 "BriefDescription": "Completed TEND instructions in constrained TX mode",
78 "PublicDescription": "A TEND instruction has completed in a constrained transactional-execution mode" 91 "PublicDescription": "A TEND instruction has completed in a constrained transactional-execution mode"
79 }, 92 },
80 { 93 {
94 "Unit": "CPU-M-CF",
81 "EventCode": "141", 95 "EventCode": "141",
82 "EventName": "TX_NC_TEND", 96 "EventName": "TX_NC_TEND",
83 "BriefDescription": "Completed TEND instructions in non-constrained TX mode", 97 "BriefDescription": "Completed TEND instructions in non-constrained TX mode",
84 "PublicDescription": "A TEND instruction has completed in a non-constrained transactional-execution mode" 98 "PublicDescription": "A TEND instruction has completed in a non-constrained transactional-execution mode"
85 }, 99 },
86 { 100 {
101 "Unit": "CPU-M-CF",
87 "EventCode": "143", 102 "EventCode": "143",
88 "EventName": "L1C_TLB2_MISSES", 103 "EventName": "L1C_TLB2_MISSES",
89 "BriefDescription": "L1C TLB2 Misses", 104 "BriefDescription": "L1C TLB2 Misses",
90 "PublicDescription": "Increments by one for any cycle where a level-1 cache or level-2 TLB miss is in progress" 105 "PublicDescription": "Increments by one for any cycle where a level-1 cache or level-2 TLB miss is in progress"
91 }, 106 },
92 { 107 {
108 "Unit": "CPU-M-CF",
93 "EventCode": "144", 109 "EventCode": "144",
94 "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES", 110 "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES",
95 "BriefDescription": "L1D On-Chip L3 Sourced Writes", 111 "BriefDescription": "L1D On-Chip L3 Sourced Writes",
96 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache without intervention" 112 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache without intervention"
97 }, 113 },
98 { 114 {
115 "Unit": "CPU-M-CF",
99 "EventCode": "145", 116 "EventCode": "145",
100 "EventName": "L1D_ONCHIP_MEMORY_SOURCED_WRITES", 117 "EventName": "L1D_ONCHIP_MEMORY_SOURCED_WRITES",
101 "BriefDescription": "L1D On-Chip Memory Sourced Writes", 118 "BriefDescription": "L1D On-Chip Memory Sourced Writes",
102 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip memory" 119 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip memory"
103 }, 120 },
104 { 121 {
122 "Unit": "CPU-M-CF",
105 "EventCode": "146", 123 "EventCode": "146",
106 "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_IV", 124 "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_IV",
107 "BriefDescription": "L1D On-Chip L3 Sourced Writes with Intervention", 125 "BriefDescription": "L1D On-Chip L3 Sourced Writes with Intervention",
108 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache with intervention" 126 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache with intervention"
109 }, 127 },
110 { 128 {
129 "Unit": "CPU-M-CF",
111 "EventCode": "147", 130 "EventCode": "147",
112 "EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES", 131 "EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES",
113 "BriefDescription": "L1D On-Cluster L3 Sourced Writes", 132 "BriefDescription": "L1D On-Cluster L3 Sourced Writes",
114 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Cluster Level-3 cache withountervention" 133 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Cluster Level-3 cache withountervention"
115 }, 134 },
116 { 135 {
136 "Unit": "CPU-M-CF",
117 "EventCode": "148", 137 "EventCode": "148",
118 "EventName": "L1D_ONCLUSTER_MEMORY_SOURCED_WRITES", 138 "EventName": "L1D_ONCLUSTER_MEMORY_SOURCED_WRITES",
119 "BriefDescription": "L1D On-Cluster Memory Sourced Writes", 139 "BriefDescription": "L1D On-Cluster Memory Sourced Writes",
120 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster memory" 140 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster memory"
121 }, 141 },
122 { 142 {
143 "Unit": "CPU-M-CF",
123 "EventCode": "149", 144 "EventCode": "149",
124 "EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES_IV", 145 "EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES_IV",
125 "BriefDescription": "L1D On-Cluster L3 Sourced Writes with Intervention", 146 "BriefDescription": "L1D On-Cluster L3 Sourced Writes with Intervention",
126 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster Level-3 cache with intervention" 147 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster Level-3 cache with intervention"
127 }, 148 },
128 { 149 {
150 "Unit": "CPU-M-CF",
129 "EventCode": "150", 151 "EventCode": "150",
130 "EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES", 152 "EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES",
131 "BriefDescription": "L1D Off-Cluster L3 Sourced Writes", 153 "BriefDescription": "L1D Off-Cluster L3 Sourced Writes",
132 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache without intervention" 154 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache without intervention"
133 }, 155 },
134 { 156 {
157 "Unit": "CPU-M-CF",
135 "EventCode": "151", 158 "EventCode": "151",
136 "EventName": "L1D_OFFCLUSTER_MEMORY_SOURCED_WRITES", 159 "EventName": "L1D_OFFCLUSTER_MEMORY_SOURCED_WRITES",
137 "BriefDescription": "L1D Off-Cluster Memory Sourced Writes", 160 "BriefDescription": "L1D Off-Cluster Memory Sourced Writes",
138 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Cluster memory" 161 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Cluster memory"
139 }, 162 },
140 { 163 {
164 "Unit": "CPU-M-CF",
141 "EventCode": "152", 165 "EventCode": "152",
142 "EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES_IV", 166 "EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES_IV",
143 "BriefDescription": "L1D Off-Cluster L3 Sourced Writes with Intervention", 167 "BriefDescription": "L1D Off-Cluster L3 Sourced Writes with Intervention",
144 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache with intervention" 168 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache with intervention"
145 }, 169 },
146 { 170 {
171 "Unit": "CPU-M-CF",
147 "EventCode": "153", 172 "EventCode": "153",
148 "EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES", 173 "EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES",
149 "BriefDescription": "L1D Off-Drawer L3 Sourced Writes", 174 "BriefDescription": "L1D Off-Drawer L3 Sourced Writes",
150 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache without intervention" 175 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache without intervention"
151 }, 176 },
152 { 177 {
178 "Unit": "CPU-M-CF",
153 "EventCode": "154", 179 "EventCode": "154",
154 "EventName": "L1D_OFFDRAWER_MEMORY_SOURCED_WRITES", 180 "EventName": "L1D_OFFDRAWER_MEMORY_SOURCED_WRITES",
155 "BriefDescription": "L1D Off-Drawer Memory Sourced Writes", 181 "BriefDescription": "L1D Off-Drawer Memory Sourced Writes",
156 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer memory" 182 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer memory"
157 }, 183 },
158 { 184 {
185 "Unit": "CPU-M-CF",
159 "EventCode": "155", 186 "EventCode": "155",
160 "EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES_IV", 187 "EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES_IV",
161 "BriefDescription": "L1D Off-Drawer L3 Sourced Writes with Intervention", 188 "BriefDescription": "L1D Off-Drawer L3 Sourced Writes with Intervention",
162 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache with intervention" 189 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache with intervention"
163 }, 190 },
164 { 191 {
192 "Unit": "CPU-M-CF",
165 "EventCode": "156", 193 "EventCode": "156",
166 "EventName": "L1D_ONDRAWER_L4_SOURCED_WRITES", 194 "EventName": "L1D_ONDRAWER_L4_SOURCED_WRITES",
167 "BriefDescription": "L1D On-Drawer L4 Sourced Writes", 195 "BriefDescription": "L1D On-Drawer L4 Sourced Writes",
168 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Drawer Level-4 cache" 196 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Drawer Level-4 cache"
169 }, 197 },
170 { 198 {
199 "Unit": "CPU-M-CF",
171 "EventCode": "157", 200 "EventCode": "157",
172 "EventName": "L1D_OFFDRAWER_L4_SOURCED_WRITES", 201 "EventName": "L1D_OFFDRAWER_L4_SOURCED_WRITES",
173 "BriefDescription": "L1D Off-Drawer L4 Sourced Writes", 202 "BriefDescription": "L1D Off-Drawer L4 Sourced Writes",
174 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer Level-4 cache" 203 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer Level-4 cache"
175 }, 204 },
176 { 205 {
206 "Unit": "CPU-M-CF",
177 "EventCode": "158", 207 "EventCode": "158",
178 "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_RO", 208 "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_RO",
179 "BriefDescription": "L1D On-Chip L3 Sourced Writes read-only", 209 "BriefDescription": "L1D On-Chip L3 Sourced Writes read-only",
180 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip L3 but a read-only invalidate was done to remove other copies of the cache line" 210 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip L3 but a read-only invalidate was done to remove other copies of the cache line"
181 }, 211 },
182 { 212 {
213 "Unit": "CPU-M-CF",
183 "EventCode": "162", 214 "EventCode": "162",
184 "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES", 215 "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES",
185 "BriefDescription": "L1I On-Chip L3 Sourced Writes", 216 "BriefDescription": "L1I On-Chip L3 Sourced Writes",
186 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from an On-Chip Level-3 cache without intervention" 217 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from an On-Chip Level-3 cache without intervention"
187 }, 218 },
188 { 219 {
220 "Unit": "CPU-M-CF",
189 "EventCode": "163", 221 "EventCode": "163",
190 "EventName": "L1I_ONCHIP_MEMORY_SOURCED_WRITES", 222 "EventName": "L1I_ONCHIP_MEMORY_SOURCED_WRITES",
191 "BriefDescription": "L1I On-Chip Memory Sourced Writes", 223 "BriefDescription": "L1I On-Chip Memory Sourced Writes",
192 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from On-Chip memory" 224 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from On-Chip memory"
193 }, 225 },
194 { 226 {
227 "Unit": "CPU-M-CF",
195 "EventCode": "164", 228 "EventCode": "164",
196 "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES_IV", 229 "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES_IV",
197 "BriefDescription": "L1I On-Chip L3 Sourced Writes with Intervention", 230 "BriefDescription": "L1I On-Chip L3 Sourced Writes with Intervention",
198 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from an On-Chip Level-3 cache with intervention" 231 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from an On-Chip Level-3 cache with intervention"
199 }, 232 },
200 { 233 {
234 "Unit": "CPU-M-CF",
201 "EventCode": "165", 235 "EventCode": "165",
202 "EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES", 236 "EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES",
203 "BriefDescription": "L1I On-Cluster L3 Sourced Writes", 237 "BriefDescription": "L1I On-Cluster L3 Sourced Writes",
204 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster Level-3 cache without intervention" 238 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster Level-3 cache without intervention"
205 }, 239 },
206 { 240 {
241 "Unit": "CPU-M-CF",
207 "EventCode": "166", 242 "EventCode": "166",
208 "EventName": "L1I_ONCLUSTER_MEMORY_SOURCED_WRITES", 243 "EventName": "L1I_ONCLUSTER_MEMORY_SOURCED_WRITES",
209 "BriefDescription": "L1I On-Cluster Memory Sourced Writes", 244 "BriefDescription": "L1I On-Cluster Memory Sourced Writes",
210 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster memory" 245 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster memory"
211 }, 246 },
212 { 247 {
248 "Unit": "CPU-M-CF",
213 "EventCode": "167", 249 "EventCode": "167",
214 "EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES_IV", 250 "EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES_IV",
215 "BriefDescription": "L1I On-Cluster L3 Sourced Writes with Intervention", 251 "BriefDescription": "L1I On-Cluster L3 Sourced Writes with Intervention",
216 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Cluster Level-3 cache with intervention" 252 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Cluster Level-3 cache with intervention"
217 }, 253 },
218 { 254 {
255 "Unit": "CPU-M-CF",
219 "EventCode": "168", 256 "EventCode": "168",
220 "EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES", 257 "EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES",
221 "BriefDescription": "L1I Off-Cluster L3 Sourced Writes", 258 "BriefDescription": "L1I Off-Cluster L3 Sourced Writes",
222 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache without intervention" 259 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache without intervention"
223 }, 260 },
224 { 261 {
262 "Unit": "CPU-M-CF",
225 "EventCode": "169", 263 "EventCode": "169",
226 "EventName": "L1I_OFFCLUSTER_MEMORY_SOURCED_WRITES", 264 "EventName": "L1I_OFFCLUSTER_MEMORY_SOURCED_WRITES",
227 "BriefDescription": "L1I Off-Cluster Memory Sourced Writes", 265 "BriefDescription": "L1I Off-Cluster Memory Sourced Writes",
228 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Cluster memory" 266 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Cluster memory"
229 }, 267 },
230 { 268 {
269 "Unit": "CPU-M-CF",
231 "EventCode": "170", 270 "EventCode": "170",
232 "EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES_IV", 271 "EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES_IV",
233 "BriefDescription": "L1I Off-Cluster L3 Sourced Writes with Intervention", 272 "BriefDescription": "L1I Off-Cluster L3 Sourced Writes with Intervention",
234 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache with intervention" 273 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache with intervention"
235 }, 274 },
236 { 275 {
276 "Unit": "CPU-M-CF",
237 "EventCode": "171", 277 "EventCode": "171",
238 "EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES", 278 "EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES",
239 "BriefDescription": "L1I Off-Drawer L3 Sourced Writes", 279 "BriefDescription": "L1I Off-Drawer L3 Sourced Writes",
240 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache without intervention" 280 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache without intervention"
241 }, 281 },
242 { 282 {
283 "Unit": "CPU-M-CF",
243 "EventCode": "172", 284 "EventCode": "172",
244 "EventName": "L1I_OFFDRAWER_MEMORY_SOURCED_WRITES", 285 "EventName": "L1I_OFFDRAWER_MEMORY_SOURCED_WRITES",
245 "BriefDescription": "L1I Off-Drawer Memory Sourced Writes", 286 "BriefDescription": "L1I Off-Drawer Memory Sourced Writes",
246 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer memory" 287 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer memory"
247 }, 288 },
248 { 289 {
290 "Unit": "CPU-M-CF",
249 "EventCode": "173", 291 "EventCode": "173",
250 "EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES_IV", 292 "EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES_IV",
251 "BriefDescription": "L1I Off-Drawer L3 Sourced Writes with Intervention", 293 "BriefDescription": "L1I Off-Drawer L3 Sourced Writes with Intervention",
252 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache with intervention" 294 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache with intervention"
253 }, 295 },
254 { 296 {
297 "Unit": "CPU-M-CF",
255 "EventCode": "174", 298 "EventCode": "174",
256 "EventName": "L1I_ONDRAWER_L4_SOURCED_WRITES", 299 "EventName": "L1I_ONDRAWER_L4_SOURCED_WRITES",
257 "BriefDescription": "L1I On-Drawer L4 Sourced Writes", 300 "BriefDescription": "L1I On-Drawer L4 Sourced Writes",
258 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Drawer Level-4 cache" 301 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Drawer Level-4 cache"
259 }, 302 },
260 { 303 {
304 "Unit": "CPU-M-CF",
261 "EventCode": "175", 305 "EventCode": "175",
262 "EventName": "L1I_OFFDRAWER_L4_SOURCED_WRITES", 306 "EventName": "L1I_OFFDRAWER_L4_SOURCED_WRITES",
263 "BriefDescription": "L1I Off-Drawer L4 Sourced Writes", 307 "BriefDescription": "L1I Off-Drawer L4 Sourced Writes",
264 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer Level-4 cache" 308 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer Level-4 cache"
265 }, 309 },
266 { 310 {
311 "Unit": "CPU-M-CF",
267 "EventCode": "224", 312 "EventCode": "224",
268 "EventName": "BCD_DFP_EXECUTION_SLOTS", 313 "EventName": "BCD_DFP_EXECUTION_SLOTS",
269 "BriefDescription": "BCD DFP Execution Slots", 314 "BriefDescription": "BCD DFP Execution Slots",
270 "PublicDescription": "Count of floating point execution slots used for finished Binary Coded Decimal to Decimal Floating Point conversions. Instructions: CDZT, CXZT, CZDT, CZXT" 315 "PublicDescription": "Count of floating point execution slots used for finished Binary Coded Decimal to Decimal Floating Point conversions. Instructions: CDZT, CXZT, CZDT, CZXT"
271 }, 316 },
272 { 317 {
318 "Unit": "CPU-M-CF",
273 "EventCode": "225", 319 "EventCode": "225",
274 "EventName": "VX_BCD_EXECUTION_SLOTS", 320 "EventName": "VX_BCD_EXECUTION_SLOTS",
275 "BriefDescription": "VX BCD Execution Slots", 321 "BriefDescription": "VX BCD Execution Slots",
276 "PublicDescription": "Count of floating point execution slots used for finished vector arithmetic Binary Coded Decimal instructions. Instructions: VAP, VSP, VMPVMSP, VDP, VSDP, VRP, VLIP, VSRP, VPSOPVCP, VTP, VPKZ, VUPKZ, VCVB, VCVBG, VCVDVCVDG" 322 "PublicDescription": "Count of floating point execution slots used for finished vector arithmetic Binary Coded Decimal instructions. Instructions: VAP, VSP, VMPVMSP, VDP, VSDP, VRP, VLIP, VSRP, VPSOPVCP, VTP, VPKZ, VUPKZ, VCVB, VCVBG, VCVDVCVDG"
277 }, 323 },
278 { 324 {
325 "Unit": "CPU-M-CF",
279 "EventCode": "226", 326 "EventCode": "226",
280 "EventName": "DECIMAL_INSTRUCTIONS", 327 "EventName": "DECIMAL_INSTRUCTIONS",
281 "BriefDescription": "Decimal Instructions", 328 "BriefDescription": "Decimal Instructions",
282 "PublicDescription": "Decimal instructions dispatched. Instructions: CVB, CVD, AP, CP, DP, ED, EDMK, MP, SRP, SP, ZAP" 329 "PublicDescription": "Decimal instructions dispatched. Instructions: CVB, CVD, AP, CP, DP, ED, EDMK, MP, SRP, SP, ZAP"
283 }, 330 },
284 { 331 {
332 "Unit": "CPU-M-CF",
285 "EventCode": "232", 333 "EventCode": "232",
286 "EventName": "LAST_HOST_TRANSLATIONS", 334 "EventName": "LAST_HOST_TRANSLATIONS",
287 "BriefDescription": "Last host translation done", 335 "BriefDescription": "Last host translation done",
288 "PublicDescription": "Last Host Translation done" 336 "PublicDescription": "Last Host Translation done"
289 }, 337 },
290 { 338 {
339 "Unit": "CPU-M-CF",
291 "EventCode": "243", 340 "EventCode": "243",
292 "EventName": "TX_NC_TABORT", 341 "EventName": "TX_NC_TABORT",
293 "BriefDescription": "Aborted transactions in non-constrained TX mode", 342 "BriefDescription": "Aborted transactions in non-constrained TX mode",
294 "PublicDescription": "A transaction abort has occurred in a non-constrained transactional-execution mode" 343 "PublicDescription": "A transaction abort has occurred in a non-constrained transactional-execution mode"
295 }, 344 },
296 { 345 {
346 "Unit": "CPU-M-CF",
297 "EventCode": "244", 347 "EventCode": "244",
298 "EventName": "TX_C_TABORT_NO_SPECIAL", 348 "EventName": "TX_C_TABORT_NO_SPECIAL",
299 "BriefDescription": "Aborted transactions in constrained TX mode not using special completion logic", 349 "BriefDescription": "Aborted transactions in constrained TX mode not using special completion logic",
300 "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is not using any special logic to allow the transaction to complete" 350 "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is not using any special logic to allow the transaction to complete"
301 }, 351 },
302 { 352 {
353 "Unit": "CPU-M-CF",
303 "EventCode": "245", 354 "EventCode": "245",
304 "EventName": "TX_C_TABORT_SPECIAL", 355 "EventName": "TX_C_TABORT_SPECIAL",
305 "BriefDescription": "Aborted transactions in constrained TX mode using special completion logic", 356 "BriefDescription": "Aborted transactions in constrained TX mode using special completion logic",
306 "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is using special logic to allow the transaction to complete" 357 "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is using special logic to allow the transaction to complete"
307 }, 358 },
308 { 359 {
360 "Unit": "CPU-M-CF",
309 "EventCode": "448", 361 "EventCode": "448",
310 "EventName": "MT_DIAG_CYCLES_ONE_THR_ACTIVE", 362 "EventName": "MT_DIAG_CYCLES_ONE_THR_ACTIVE",
311 "BriefDescription": "Cycle count with one thread active", 363 "BriefDescription": "Cycle count with one thread active",
312 "PublicDescription": "Cycle count with one thread active" 364 "PublicDescription": "Cycle count with one thread active"
313 }, 365 },
314 { 366 {
367 "Unit": "CPU-M-CF",
315 "EventCode": "449", 368 "EventCode": "449",
316 "EventName": "MT_DIAG_CYCLES_TWO_THR_ACTIVE", 369 "EventName": "MT_DIAG_CYCLES_TWO_THR_ACTIVE",
317 "BriefDescription": "Cycle count with two threads active", 370 "BriefDescription": "Cycle count with two threads active",
diff --git a/tools/perf/pmu-events/arch/s390/cf_z14/transaction.json b/tools/perf/pmu-events/arch/s390/cf_z14/transaction.json
new file mode 100644
index 000000000000..1a0034f79f73
--- /dev/null
+++ b/tools/perf/pmu-events/arch/s390/cf_z14/transaction.json
@@ -0,0 +1,7 @@
1[
2 {
3 "BriefDescription": "Transaction count",
4 "MetricName": "transaction",
5 "MetricExpr": "TX_C_TEND + TX_NC_TEND + TX_NC_TABORT + TX_C_TABORT_SPECIAL + TX_C_TABORT_NO_SPECIAL"
6 }
7]
diff --git a/tools/perf/pmu-events/arch/s390/cf_z196/basic.json b/tools/perf/pmu-events/arch/s390/cf_z196/basic.json
index 8bf16759ca53..2dd8dafff2ef 100644
--- a/tools/perf/pmu-events/arch/s390/cf_z196/basic.json
+++ b/tools/perf/pmu-events/arch/s390/cf_z196/basic.json
@@ -1,71 +1,83 @@
1[ 1[
2 { 2 {
3 "Unit": "CPU-M-CF",
3 "EventCode": "0", 4 "EventCode": "0",
4 "EventName": "CPU_CYCLES", 5 "EventName": "CPU_CYCLES",
5 "BriefDescription": "CPU Cycles", 6 "BriefDescription": "CPU Cycles",
6 "PublicDescription": "Cycle Count" 7 "PublicDescription": "Cycle Count"
7 }, 8 },
8 { 9 {
10 "Unit": "CPU-M-CF",
9 "EventCode": "1", 11 "EventCode": "1",
10 "EventName": "INSTRUCTIONS", 12 "EventName": "INSTRUCTIONS",
11 "BriefDescription": "Instructions", 13 "BriefDescription": "Instructions",
12 "PublicDescription": "Instruction Count" 14 "PublicDescription": "Instruction Count"
13 }, 15 },
14 { 16 {
17 "Unit": "CPU-M-CF",
15 "EventCode": "2", 18 "EventCode": "2",
16 "EventName": "L1I_DIR_WRITES", 19 "EventName": "L1I_DIR_WRITES",
17 "BriefDescription": "L1I Directory Writes", 20 "BriefDescription": "L1I Directory Writes",
18 "PublicDescription": "Level-1 I-Cache Directory Write Count" 21 "PublicDescription": "Level-1 I-Cache Directory Write Count"
19 }, 22 },
20 { 23 {
24 "Unit": "CPU-M-CF",
21 "EventCode": "3", 25 "EventCode": "3",
22 "EventName": "L1I_PENALTY_CYCLES", 26 "EventName": "L1I_PENALTY_CYCLES",
23 "BriefDescription": "L1I Penalty Cycles", 27 "BriefDescription": "L1I Penalty Cycles",
24 "PublicDescription": "Level-1 I-Cache Penalty Cycle Count" 28 "PublicDescription": "Level-1 I-Cache Penalty Cycle Count"
25 }, 29 },
26 { 30 {
31 "Unit": "CPU-M-CF",
27 "EventCode": "4", 32 "EventCode": "4",
28 "EventName": "L1D_DIR_WRITES", 33 "EventName": "L1D_DIR_WRITES",
29 "BriefDescription": "L1D Directory Writes", 34 "BriefDescription": "L1D Directory Writes",
30 "PublicDescription": "Level-1 D-Cache Directory Write Count" 35 "PublicDescription": "Level-1 D-Cache Directory Write Count"
31 }, 36 },
32 { 37 {
38 "Unit": "CPU-M-CF",
33 "EventCode": "5", 39 "EventCode": "5",
34 "EventName": "L1D_PENALTY_CYCLES", 40 "EventName": "L1D_PENALTY_CYCLES",
35 "BriefDescription": "L1D Penalty Cycles", 41 "BriefDescription": "L1D Penalty Cycles",
36 "PublicDescription": "Level-1 D-Cache Penalty Cycle Count" 42 "PublicDescription": "Level-1 D-Cache Penalty Cycle Count"
37 }, 43 },
38 { 44 {
45 "Unit": "CPU-M-CF",
39 "EventCode": "32", 46 "EventCode": "32",
40 "EventName": "PROBLEM_STATE_CPU_CYCLES", 47 "EventName": "PROBLEM_STATE_CPU_CYCLES",
41 "BriefDescription": "Problem-State CPU Cycles", 48 "BriefDescription": "Problem-State CPU Cycles",
42 "PublicDescription": "Problem-State Cycle Count" 49 "PublicDescription": "Problem-State Cycle Count"
43 }, 50 },
44 { 51 {
52 "Unit": "CPU-M-CF",
45 "EventCode": "33", 53 "EventCode": "33",
46 "EventName": "PROBLEM_STATE_INSTRUCTIONS", 54 "EventName": "PROBLEM_STATE_INSTRUCTIONS",
47 "BriefDescription": "Problem-State Instructions", 55 "BriefDescription": "Problem-State Instructions",
48 "PublicDescription": "Problem-State Instruction Count" 56 "PublicDescription": "Problem-State Instruction Count"
49 }, 57 },
50 { 58 {
59 "Unit": "CPU-M-CF",
51 "EventCode": "34", 60 "EventCode": "34",
52 "EventName": "PROBLEM_STATE_L1I_DIR_WRITES", 61 "EventName": "PROBLEM_STATE_L1I_DIR_WRITES",
53 "BriefDescription": "Problem-State L1I Directory Writes", 62 "BriefDescription": "Problem-State L1I Directory Writes",
54 "PublicDescription": "Problem-State Level-1 I-Cache Directory Write Count" 63 "PublicDescription": "Problem-State Level-1 I-Cache Directory Write Count"
55 }, 64 },
56 { 65 {
66 "Unit": "CPU-M-CF",
57 "EventCode": "35", 67 "EventCode": "35",
58 "EventName": "PROBLEM_STATE_L1I_PENALTY_CYCLES", 68 "EventName": "PROBLEM_STATE_L1I_PENALTY_CYCLES",
59 "BriefDescription": "Problem-State L1I Penalty Cycles", 69 "BriefDescription": "Problem-State L1I Penalty Cycles",
60 "PublicDescription": "Problem-State Level-1 I-Cache Penalty Cycle Count" 70 "PublicDescription": "Problem-State Level-1 I-Cache Penalty Cycle Count"
61 }, 71 },
62 { 72 {
73 "Unit": "CPU-M-CF",
63 "EventCode": "36", 74 "EventCode": "36",
64 "EventName": "PROBLEM_STATE_L1D_DIR_WRITES", 75 "EventName": "PROBLEM_STATE_L1D_DIR_WRITES",
65 "BriefDescription": "Problem-State L1D Directory Writes", 76 "BriefDescription": "Problem-State L1D Directory Writes",
66 "PublicDescription": "Problem-State Level-1 D-Cache Directory Write Count" 77 "PublicDescription": "Problem-State Level-1 D-Cache Directory Write Count"
67 }, 78 },
68 { 79 {
80 "Unit": "CPU-M-CF",
69 "EventCode": "37", 81 "EventCode": "37",
70 "EventName": "PROBLEM_STATE_L1D_PENALTY_CYCLES", 82 "EventName": "PROBLEM_STATE_L1D_PENALTY_CYCLES",
71 "BriefDescription": "Problem-State L1D Penalty Cycles", 83 "BriefDescription": "Problem-State L1D Penalty Cycles",
diff --git a/tools/perf/pmu-events/arch/s390/cf_z196/crypto.json b/tools/perf/pmu-events/arch/s390/cf_z196/crypto.json
index 7e5b72492141..db286f19e7b6 100644
--- a/tools/perf/pmu-events/arch/s390/cf_z196/crypto.json
+++ b/tools/perf/pmu-events/arch/s390/cf_z196/crypto.json
@@ -1,95 +1,111 @@
1[ 1[
2 { 2 {
3 "Unit": "CPU-M-CF",
3 "EventCode": "64", 4 "EventCode": "64",
4 "EventName": "PRNG_FUNCTIONS", 5 "EventName": "PRNG_FUNCTIONS",
5 "BriefDescription": "PRNG Functions", 6 "BriefDescription": "PRNG Functions",
6 "PublicDescription": "Total number of the PRNG functions issued by the CPU" 7 "PublicDescription": "Total number of the PRNG functions issued by the CPU"
7 }, 8 },
8 { 9 {
10 "Unit": "CPU-M-CF",
9 "EventCode": "65", 11 "EventCode": "65",
10 "EventName": "PRNG_CYCLES", 12 "EventName": "PRNG_CYCLES",
11 "BriefDescription": "PRNG Cycles", 13 "BriefDescription": "PRNG Cycles",
12 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU" 14 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU"
13 }, 15 },
14 { 16 {
17 "Unit": "CPU-M-CF",
15 "EventCode": "66", 18 "EventCode": "66",
16 "EventName": "PRNG_BLOCKED_FUNCTIONS", 19 "EventName": "PRNG_BLOCKED_FUNCTIONS",
17 "BriefDescription": "PRNG Blocked Functions", 20 "BriefDescription": "PRNG Blocked Functions",
18 "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" 21 "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
19 }, 22 },
20 { 23 {
24 "Unit": "CPU-M-CF",
21 "EventCode": "67", 25 "EventCode": "67",
22 "EventName": "PRNG_BLOCKED_CYCLES", 26 "EventName": "PRNG_BLOCKED_CYCLES",
23 "BriefDescription": "PRNG Blocked Cycles", 27 "BriefDescription": "PRNG Blocked Cycles",
24 "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" 28 "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
25 }, 29 },
26 { 30 {
31 "Unit": "CPU-M-CF",
27 "EventCode": "68", 32 "EventCode": "68",
28 "EventName": "SHA_FUNCTIONS", 33 "EventName": "SHA_FUNCTIONS",
29 "BriefDescription": "SHA Functions", 34 "BriefDescription": "SHA Functions",
30 "PublicDescription": "Total number of SHA functions issued by the CPU" 35 "PublicDescription": "Total number of SHA functions issued by the CPU"
31 }, 36 },
32 { 37 {
38 "Unit": "CPU-M-CF",
33 "EventCode": "69", 39 "EventCode": "69",
34 "EventName": "SHA_CYCLES", 40 "EventName": "SHA_CYCLES",
35 "BriefDescription": "SHA Cycles", 41 "BriefDescription": "SHA Cycles",
36 "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU" 42 "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU"
37 }, 43 },
38 { 44 {
45 "Unit": "CPU-M-CF",
39 "EventCode": "70", 46 "EventCode": "70",
40 "EventName": "SHA_BLOCKED_FUNCTIONS", 47 "EventName": "SHA_BLOCKED_FUNCTIONS",
41 "BriefDescription": "SHA Blocked Functions", 48 "BriefDescription": "SHA Blocked Functions",
42 "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU" 49 "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU"
43 }, 50 },
44 { 51 {
52 "Unit": "CPU-M-CF",
45 "EventCode": "71", 53 "EventCode": "71",
46 "EventName": "SHA_BLOCKED_CYCLES", 54 "EventName": "SHA_BLOCKED_CYCLES",
47 "BriefDescription": "SHA Bloced Cycles", 55 "BriefDescription": "SHA Bloced Cycles",
48 "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU" 56 "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU"
49 }, 57 },
50 { 58 {
59 "Unit": "CPU-M-CF",
51 "EventCode": "72", 60 "EventCode": "72",
52 "EventName": "DEA_FUNCTIONS", 61 "EventName": "DEA_FUNCTIONS",
53 "BriefDescription": "DEA Functions", 62 "BriefDescription": "DEA Functions",
54 "PublicDescription": "Total number of the DEA functions issued by the CPU" 63 "PublicDescription": "Total number of the DEA functions issued by the CPU"
55 }, 64 },
56 { 65 {
66 "Unit": "CPU-M-CF",
57 "EventCode": "73", 67 "EventCode": "73",
58 "EventName": "DEA_CYCLES", 68 "EventName": "DEA_CYCLES",
59 "BriefDescription": "DEA Cycles", 69 "BriefDescription": "DEA Cycles",
60 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU" 70 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU"
61 }, 71 },
62 { 72 {
73 "Unit": "CPU-M-CF",
63 "EventCode": "74", 74 "EventCode": "74",
64 "EventName": "DEA_BLOCKED_FUNCTIONS", 75 "EventName": "DEA_BLOCKED_FUNCTIONS",
65 "BriefDescription": "DEA Blocked Functions", 76 "BriefDescription": "DEA Blocked Functions",
66 "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" 77 "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
67 }, 78 },
68 { 79 {
80 "Unit": "CPU-M-CF",
69 "EventCode": "75", 81 "EventCode": "75",
70 "EventName": "DEA_BLOCKED_CYCLES", 82 "EventName": "DEA_BLOCKED_CYCLES",
71 "BriefDescription": "DEA Blocked Cycles", 83 "BriefDescription": "DEA Blocked Cycles",
72 "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" 84 "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
73 }, 85 },
74 { 86 {
87 "Unit": "CPU-M-CF",
75 "EventCode": "76", 88 "EventCode": "76",
76 "EventName": "AES_FUNCTIONS", 89 "EventName": "AES_FUNCTIONS",
77 "BriefDescription": "AES Functions", 90 "BriefDescription": "AES Functions",
78 "PublicDescription": "Total number of AES functions issued by the CPU" 91 "PublicDescription": "Total number of AES functions issued by the CPU"
79 }, 92 },
80 { 93 {
94 "Unit": "CPU-M-CF",
81 "EventCode": "77", 95 "EventCode": "77",
82 "EventName": "AES_CYCLES", 96 "EventName": "AES_CYCLES",
83 "BriefDescription": "AES Cycles", 97 "BriefDescription": "AES Cycles",
84 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU" 98 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU"
85 }, 99 },
86 { 100 {
101 "Unit": "CPU-M-CF",
87 "EventCode": "78", 102 "EventCode": "78",
88 "EventName": "AES_BLOCKED_FUNCTIONS", 103 "EventName": "AES_BLOCKED_FUNCTIONS",
89 "BriefDescription": "AES Blocked Functions", 104 "BriefDescription": "AES Blocked Functions",
90 "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" 105 "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
91 }, 106 },
92 { 107 {
108 "Unit": "CPU-M-CF",
93 "EventCode": "79", 109 "EventCode": "79",
94 "EventName": "AES_BLOCKED_CYCLES", 110 "EventName": "AES_BLOCKED_CYCLES",
95 "BriefDescription": "AES Blocked Cycles", 111 "BriefDescription": "AES Blocked Cycles",
diff --git a/tools/perf/pmu-events/arch/s390/cf_z196/extended.json b/tools/perf/pmu-events/arch/s390/cf_z196/extended.json
index b6d7fec7c2e7..b7b42a870bb0 100644
--- a/tools/perf/pmu-events/arch/s390/cf_z196/extended.json
+++ b/tools/perf/pmu-events/arch/s390/cf_z196/extended.json
@@ -1,143 +1,167 @@
1[ 1[
2 { 2 {
3 "Unit": "CPU-M-CF",
3 "EventCode": "128", 4 "EventCode": "128",
4 "EventName": "L1D_L2_SOURCED_WRITES", 5 "EventName": "L1D_L2_SOURCED_WRITES",
5 "BriefDescription": "L1D L2 Sourced Writes", 6 "BriefDescription": "L1D L2 Sourced Writes",
6 "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from the Level-2 cache" 7 "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from the Level-2 cache"
7 }, 8 },
8 { 9 {
10 "Unit": "CPU-M-CF",
9 "EventCode": "129", 11 "EventCode": "129",
10 "EventName": "L1I_L2_SOURCED_WRITES", 12 "EventName": "L1I_L2_SOURCED_WRITES",
11 "BriefDescription": "L1I L2 Sourced Writes", 13 "BriefDescription": "L1I L2 Sourced Writes",
12 "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from the Level-2 cache" 14 "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from the Level-2 cache"
13 }, 15 },
14 { 16 {
17 "Unit": "CPU-M-CF",
15 "EventCode": "130", 18 "EventCode": "130",
16 "EventName": "DTLB1_MISSES", 19 "EventName": "DTLB1_MISSES",
17 "BriefDescription": "DTLB1 Misses", 20 "BriefDescription": "DTLB1 Misses",
18 "PublicDescription": "Level-1 Data TLB miss in progress. Incremented by one for every cycle a DTLB1 miss is in progress." 21 "PublicDescription": "Level-1 Data TLB miss in progress. Incremented by one for every cycle a DTLB1 miss is in progress."
19 }, 22 },
20 { 23 {
24 "Unit": "CPU-M-CF",
21 "EventCode": "131", 25 "EventCode": "131",
22 "EventName": "ITLB1_MISSES", 26 "EventName": "ITLB1_MISSES",
23 "BriefDescription": "ITLB1 Misses", 27 "BriefDescription": "ITLB1 Misses",
24 "PublicDescription": "Level-1 Instruction TLB miss in progress. Incremented by one for every cycle a ITLB1 miss is in progress." 28 "PublicDescription": "Level-1 Instruction TLB miss in progress. Incremented by one for every cycle a ITLB1 miss is in progress."
25 }, 29 },
26 { 30 {
31 "Unit": "CPU-M-CF",
27 "EventCode": "133", 32 "EventCode": "133",
28 "EventName": "L2C_STORES_SENT", 33 "EventName": "L2C_STORES_SENT",
29 "BriefDescription": "L2C Stores Sent", 34 "BriefDescription": "L2C Stores Sent",
30 "PublicDescription": "Incremented by one for every store sent to Level-2 cache" 35 "PublicDescription": "Incremented by one for every store sent to Level-2 cache"
31 }, 36 },
32 { 37 {
38 "Unit": "CPU-M-CF",
33 "EventCode": "134", 39 "EventCode": "134",
34 "EventName": "L1D_OFFBOOK_L3_SOURCED_WRITES", 40 "EventName": "L1D_OFFBOOK_L3_SOURCED_WRITES",
35 "BriefDescription": "L1D Off-Book L3 Sourced Writes", 41 "BriefDescription": "L1D Off-Book L3 Sourced Writes",
36 "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an Off Book Level-3 cache" 42 "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an Off Book Level-3 cache"
37 }, 43 },
38 { 44 {
45 "Unit": "CPU-M-CF",
39 "EventCode": "135", 46 "EventCode": "135",
40 "EventName": "L1D_ONBOOK_L4_SOURCED_WRITES", 47 "EventName": "L1D_ONBOOK_L4_SOURCED_WRITES",
41 "BriefDescription": "L1D On-Book L4 Sourced Writes", 48 "BriefDescription": "L1D On-Book L4 Sourced Writes",
42 "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an On Book Level-4 cache" 49 "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an On Book Level-4 cache"
43 }, 50 },
44 { 51 {
52 "Unit": "CPU-M-CF",
45 "EventCode": "136", 53 "EventCode": "136",
46 "EventName": "L1I_ONBOOK_L4_SOURCED_WRITES", 54 "EventName": "L1I_ONBOOK_L4_SOURCED_WRITES",
47 "BriefDescription": "L1I On-Book L4 Sourced Writes", 55 "BriefDescription": "L1I On-Book L4 Sourced Writes",
48 "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from an On Book Level-4 cache" 56 "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from an On Book Level-4 cache"
49 }, 57 },
50 { 58 {
59 "Unit": "CPU-M-CF",
51 "EventCode": "137", 60 "EventCode": "137",
52 "EventName": "L1D_RO_EXCL_WRITES", 61 "EventName": "L1D_RO_EXCL_WRITES",
53 "BriefDescription": "L1D Read-only Exclusive Writes", 62 "BriefDescription": "L1D Read-only Exclusive Writes",
54 "PublicDescription": "A directory write to the Level-1 D-Cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line" 63 "PublicDescription": "A directory write to the Level-1 D-Cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line"
55 }, 64 },
56 { 65 {
66 "Unit": "CPU-M-CF",
57 "EventCode": "138", 67 "EventCode": "138",
58 "EventName": "L1D_OFFBOOK_L4_SOURCED_WRITES", 68 "EventName": "L1D_OFFBOOK_L4_SOURCED_WRITES",
59 "BriefDescription": "L1D Off-Book L4 Sourced Writes", 69 "BriefDescription": "L1D Off-Book L4 Sourced Writes",
60 "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an Off Book Level-4 cache" 70 "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an Off Book Level-4 cache"
61 }, 71 },
62 { 72 {
73 "Unit": "CPU-M-CF",
63 "EventCode": "139", 74 "EventCode": "139",
64 "EventName": "L1I_OFFBOOK_L4_SOURCED_WRITES", 75 "EventName": "L1I_OFFBOOK_L4_SOURCED_WRITES",
65 "BriefDescription": "L1I Off-Book L4 Sourced Writes", 76 "BriefDescription": "L1I Off-Book L4 Sourced Writes",
66 "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from an Off Book Level-4 cache" 77 "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from an Off Book Level-4 cache"
67 }, 78 },
68 { 79 {
80 "Unit": "CPU-M-CF",
69 "EventCode": "140", 81 "EventCode": "140",
70 "EventName": "DTLB1_HPAGE_WRITES", 82 "EventName": "DTLB1_HPAGE_WRITES",
71 "BriefDescription": "DTLB1 One-Megabyte Page Writes", 83 "BriefDescription": "DTLB1 One-Megabyte Page Writes",
72 "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer for a one-megabyte page" 84 "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer for a one-megabyte page"
73 }, 85 },
74 { 86 {
87 "Unit": "CPU-M-CF",
75 "EventCode": "141", 88 "EventCode": "141",
76 "EventName": "L1D_LMEM_SOURCED_WRITES", 89 "EventName": "L1D_LMEM_SOURCED_WRITES",
77 "BriefDescription": "L1D Local Memory Sourced Writes", 90 "BriefDescription": "L1D Local Memory Sourced Writes",
78 "PublicDescription": "A directory write to the Level-1 D-Cache where the installed cache line was sourced from memory that is attached to the same book as the Data cache (Local Memory)" 91 "PublicDescription": "A directory write to the Level-1 D-Cache where the installed cache line was sourced from memory that is attached to the same book as the Data cache (Local Memory)"
79 }, 92 },
80 { 93 {
94 "Unit": "CPU-M-CF",
81 "EventCode": "142", 95 "EventCode": "142",
82 "EventName": "L1I_LMEM_SOURCED_WRITES", 96 "EventName": "L1I_LMEM_SOURCED_WRITES",
83 "BriefDescription": "L1I Local Memory Sourced Writes", 97 "BriefDescription": "L1I Local Memory Sourced Writes",
84 "PublicDescription": "A directory write to the Level-1 I-Cache where the installed cache line was sourced from memory that is attached to the same book as the Instruction cache (Local Memory)" 98 "PublicDescription": "A directory write to the Level-1 I-Cache where the installed cache line was sourced from memory that is attached to the same book as the Instruction cache (Local Memory)"
85 }, 99 },
86 { 100 {
101 "Unit": "CPU-M-CF",
87 "EventCode": "143", 102 "EventCode": "143",
88 "EventName": "L1I_OFFBOOK_L3_SOURCED_WRITES", 103 "EventName": "L1I_OFFBOOK_L3_SOURCED_WRITES",
89 "BriefDescription": "L1I Off-Book L3 Sourced Writes", 104 "BriefDescription": "L1I Off-Book L3 Sourced Writes",
90 "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from an Off Book Level-3 cache" 105 "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from an Off Book Level-3 cache"
91 }, 106 },
92 { 107 {
108 "Unit": "CPU-M-CF",
93 "EventCode": "144", 109 "EventCode": "144",
94 "EventName": "DTLB1_WRITES", 110 "EventName": "DTLB1_WRITES",
95 "BriefDescription": "DTLB1 Writes", 111 "BriefDescription": "DTLB1 Writes",
96 "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer" 112 "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer"
97 }, 113 },
98 { 114 {
115 "Unit": "CPU-M-CF",
99 "EventCode": "145", 116 "EventCode": "145",
100 "EventName": "ITLB1_WRITES", 117 "EventName": "ITLB1_WRITES",
101 "BriefDescription": "ITLB1 Writes", 118 "BriefDescription": "ITLB1 Writes",
102 "PublicDescription": "A translation entry has been written to the Level-1 Instruction Translation Lookaside Buffer" 119 "PublicDescription": "A translation entry has been written to the Level-1 Instruction Translation Lookaside Buffer"
103 }, 120 },
104 { 121 {
122 "Unit": "CPU-M-CF",
105 "EventCode": "146", 123 "EventCode": "146",
106 "EventName": "TLB2_PTE_WRITES", 124 "EventName": "TLB2_PTE_WRITES",
107 "BriefDescription": "TLB2 PTE Writes", 125 "BriefDescription": "TLB2 PTE Writes",
108 "PublicDescription": "A translation entry has been written to the Level-2 TLB Page Table Entry arrays" 126 "PublicDescription": "A translation entry has been written to the Level-2 TLB Page Table Entry arrays"
109 }, 127 },
110 { 128 {
129 "Unit": "CPU-M-CF",
111 "EventCode": "147", 130 "EventCode": "147",
112 "EventName": "TLB2_CRSTE_HPAGE_WRITES", 131 "EventName": "TLB2_CRSTE_HPAGE_WRITES",
113 "BriefDescription": "TLB2 CRSTE One-Megabyte Page Writes", 132 "BriefDescription": "TLB2 CRSTE One-Megabyte Page Writes",
114 "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays for a one-megabyte large page translation" 133 "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays for a one-megabyte large page translation"
115 }, 134 },
116 { 135 {
136 "Unit": "CPU-M-CF",
117 "EventCode": "148", 137 "EventCode": "148",
118 "EventName": "TLB2_CRSTE_WRITES", 138 "EventName": "TLB2_CRSTE_WRITES",
119 "BriefDescription": "TLB2 CRSTE Writes", 139 "BriefDescription": "TLB2 CRSTE Writes",
120 "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays" 140 "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays"
121 }, 141 },
122 { 142 {
143 "Unit": "CPU-M-CF",
123 "EventCode": "150", 144 "EventCode": "150",
124 "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES", 145 "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES",
125 "BriefDescription": "L1D On-Chip L3 Sourced Writes", 146 "BriefDescription": "L1D On-Chip L3 Sourced Writes",
126 "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an On Chip Level-3 cache" 147 "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an On Chip Level-3 cache"
127 }, 148 },
128 { 149 {
150 "Unit": "CPU-M-CF",
129 "EventCode": "152", 151 "EventCode": "152",
130 "EventName": "L1D_OFFCHIP_L3_SOURCED_WRITES", 152 "EventName": "L1D_OFFCHIP_L3_SOURCED_WRITES",
131 "BriefDescription": "L1D Off-Chip L3 Sourced Writes", 153 "BriefDescription": "L1D Off-Chip L3 Sourced Writes",
132 "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache" 154 "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache"
133 }, 155 },
134 { 156 {
157 "Unit": "CPU-M-CF",
135 "EventCode": "153", 158 "EventCode": "153",
136 "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES", 159 "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES",
137 "BriefDescription": "L1I On-Chip L3 Sourced Writes", 160 "BriefDescription": "L1I On-Chip L3 Sourced Writes",
138 "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from an On Chip Level-3 cache" 161 "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from an On Chip Level-3 cache"
139 }, 162 },
140 { 163 {
164 "Unit": "CPU-M-CF",
141 "EventCode": "155", 165 "EventCode": "155",
142 "EventName": "L1I_OFFCHIP_L3_SOURCED_WRITES", 166 "EventName": "L1I_OFFCHIP_L3_SOURCED_WRITES",
143 "BriefDescription": "L1I Off-Chip L3 Sourced Writes", 167 "BriefDescription": "L1I Off-Chip L3 Sourced Writes",
diff --git a/tools/perf/pmu-events/arch/s390/cf_zec12/basic.json b/tools/perf/pmu-events/arch/s390/cf_zec12/basic.json
index 8bf16759ca53..2dd8dafff2ef 100644
--- a/tools/perf/pmu-events/arch/s390/cf_zec12/basic.json
+++ b/tools/perf/pmu-events/arch/s390/cf_zec12/basic.json
@@ -1,71 +1,83 @@
1[ 1[
2 { 2 {
3 "Unit": "CPU-M-CF",
3 "EventCode": "0", 4 "EventCode": "0",
4 "EventName": "CPU_CYCLES", 5 "EventName": "CPU_CYCLES",
5 "BriefDescription": "CPU Cycles", 6 "BriefDescription": "CPU Cycles",
6 "PublicDescription": "Cycle Count" 7 "PublicDescription": "Cycle Count"
7 }, 8 },
8 { 9 {
10 "Unit": "CPU-M-CF",
9 "EventCode": "1", 11 "EventCode": "1",
10 "EventName": "INSTRUCTIONS", 12 "EventName": "INSTRUCTIONS",
11 "BriefDescription": "Instructions", 13 "BriefDescription": "Instructions",
12 "PublicDescription": "Instruction Count" 14 "PublicDescription": "Instruction Count"
13 }, 15 },
14 { 16 {
17 "Unit": "CPU-M-CF",
15 "EventCode": "2", 18 "EventCode": "2",
16 "EventName": "L1I_DIR_WRITES", 19 "EventName": "L1I_DIR_WRITES",
17 "BriefDescription": "L1I Directory Writes", 20 "BriefDescription": "L1I Directory Writes",
18 "PublicDescription": "Level-1 I-Cache Directory Write Count" 21 "PublicDescription": "Level-1 I-Cache Directory Write Count"
19 }, 22 },
20 { 23 {
24 "Unit": "CPU-M-CF",
21 "EventCode": "3", 25 "EventCode": "3",
22 "EventName": "L1I_PENALTY_CYCLES", 26 "EventName": "L1I_PENALTY_CYCLES",
23 "BriefDescription": "L1I Penalty Cycles", 27 "BriefDescription": "L1I Penalty Cycles",
24 "PublicDescription": "Level-1 I-Cache Penalty Cycle Count" 28 "PublicDescription": "Level-1 I-Cache Penalty Cycle Count"
25 }, 29 },
26 { 30 {
31 "Unit": "CPU-M-CF",
27 "EventCode": "4", 32 "EventCode": "4",
28 "EventName": "L1D_DIR_WRITES", 33 "EventName": "L1D_DIR_WRITES",
29 "BriefDescription": "L1D Directory Writes", 34 "BriefDescription": "L1D Directory Writes",
30 "PublicDescription": "Level-1 D-Cache Directory Write Count" 35 "PublicDescription": "Level-1 D-Cache Directory Write Count"
31 }, 36 },
32 { 37 {
38 "Unit": "CPU-M-CF",
33 "EventCode": "5", 39 "EventCode": "5",
34 "EventName": "L1D_PENALTY_CYCLES", 40 "EventName": "L1D_PENALTY_CYCLES",
35 "BriefDescription": "L1D Penalty Cycles", 41 "BriefDescription": "L1D Penalty Cycles",
36 "PublicDescription": "Level-1 D-Cache Penalty Cycle Count" 42 "PublicDescription": "Level-1 D-Cache Penalty Cycle Count"
37 }, 43 },
38 { 44 {
45 "Unit": "CPU-M-CF",
39 "EventCode": "32", 46 "EventCode": "32",
40 "EventName": "PROBLEM_STATE_CPU_CYCLES", 47 "EventName": "PROBLEM_STATE_CPU_CYCLES",
41 "BriefDescription": "Problem-State CPU Cycles", 48 "BriefDescription": "Problem-State CPU Cycles",
42 "PublicDescription": "Problem-State Cycle Count" 49 "PublicDescription": "Problem-State Cycle Count"
43 }, 50 },
44 { 51 {
52 "Unit": "CPU-M-CF",
45 "EventCode": "33", 53 "EventCode": "33",
46 "EventName": "PROBLEM_STATE_INSTRUCTIONS", 54 "EventName": "PROBLEM_STATE_INSTRUCTIONS",
47 "BriefDescription": "Problem-State Instructions", 55 "BriefDescription": "Problem-State Instructions",
48 "PublicDescription": "Problem-State Instruction Count" 56 "PublicDescription": "Problem-State Instruction Count"
49 }, 57 },
50 { 58 {
59 "Unit": "CPU-M-CF",
51 "EventCode": "34", 60 "EventCode": "34",
52 "EventName": "PROBLEM_STATE_L1I_DIR_WRITES", 61 "EventName": "PROBLEM_STATE_L1I_DIR_WRITES",
53 "BriefDescription": "Problem-State L1I Directory Writes", 62 "BriefDescription": "Problem-State L1I Directory Writes",
54 "PublicDescription": "Problem-State Level-1 I-Cache Directory Write Count" 63 "PublicDescription": "Problem-State Level-1 I-Cache Directory Write Count"
55 }, 64 },
56 { 65 {
66 "Unit": "CPU-M-CF",
57 "EventCode": "35", 67 "EventCode": "35",
58 "EventName": "PROBLEM_STATE_L1I_PENALTY_CYCLES", 68 "EventName": "PROBLEM_STATE_L1I_PENALTY_CYCLES",
59 "BriefDescription": "Problem-State L1I Penalty Cycles", 69 "BriefDescription": "Problem-State L1I Penalty Cycles",
60 "PublicDescription": "Problem-State Level-1 I-Cache Penalty Cycle Count" 70 "PublicDescription": "Problem-State Level-1 I-Cache Penalty Cycle Count"
61 }, 71 },
62 { 72 {
73 "Unit": "CPU-M-CF",
63 "EventCode": "36", 74 "EventCode": "36",
64 "EventName": "PROBLEM_STATE_L1D_DIR_WRITES", 75 "EventName": "PROBLEM_STATE_L1D_DIR_WRITES",
65 "BriefDescription": "Problem-State L1D Directory Writes", 76 "BriefDescription": "Problem-State L1D Directory Writes",
66 "PublicDescription": "Problem-State Level-1 D-Cache Directory Write Count" 77 "PublicDescription": "Problem-State Level-1 D-Cache Directory Write Count"
67 }, 78 },
68 { 79 {
80 "Unit": "CPU-M-CF",
69 "EventCode": "37", 81 "EventCode": "37",
70 "EventName": "PROBLEM_STATE_L1D_PENALTY_CYCLES", 82 "EventName": "PROBLEM_STATE_L1D_PENALTY_CYCLES",
71 "BriefDescription": "Problem-State L1D Penalty Cycles", 83 "BriefDescription": "Problem-State L1D Penalty Cycles",
diff --git a/tools/perf/pmu-events/arch/s390/cf_zec12/crypto.json b/tools/perf/pmu-events/arch/s390/cf_zec12/crypto.json
index 7e5b72492141..db286f19e7b6 100644
--- a/tools/perf/pmu-events/arch/s390/cf_zec12/crypto.json
+++ b/tools/perf/pmu-events/arch/s390/cf_zec12/crypto.json
@@ -1,95 +1,111 @@
1[ 1[
2 { 2 {
3 "Unit": "CPU-M-CF",
3 "EventCode": "64", 4 "EventCode": "64",
4 "EventName": "PRNG_FUNCTIONS", 5 "EventName": "PRNG_FUNCTIONS",
5 "BriefDescription": "PRNG Functions", 6 "BriefDescription": "PRNG Functions",
6 "PublicDescription": "Total number of the PRNG functions issued by the CPU" 7 "PublicDescription": "Total number of the PRNG functions issued by the CPU"
7 }, 8 },
8 { 9 {
10 "Unit": "CPU-M-CF",
9 "EventCode": "65", 11 "EventCode": "65",
10 "EventName": "PRNG_CYCLES", 12 "EventName": "PRNG_CYCLES",
11 "BriefDescription": "PRNG Cycles", 13 "BriefDescription": "PRNG Cycles",
12 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU" 14 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU"
13 }, 15 },
14 { 16 {
17 "Unit": "CPU-M-CF",
15 "EventCode": "66", 18 "EventCode": "66",
16 "EventName": "PRNG_BLOCKED_FUNCTIONS", 19 "EventName": "PRNG_BLOCKED_FUNCTIONS",
17 "BriefDescription": "PRNG Blocked Functions", 20 "BriefDescription": "PRNG Blocked Functions",
18 "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" 21 "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
19 }, 22 },
20 { 23 {
24 "Unit": "CPU-M-CF",
21 "EventCode": "67", 25 "EventCode": "67",
22 "EventName": "PRNG_BLOCKED_CYCLES", 26 "EventName": "PRNG_BLOCKED_CYCLES",
23 "BriefDescription": "PRNG Blocked Cycles", 27 "BriefDescription": "PRNG Blocked Cycles",
24 "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" 28 "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
25 }, 29 },
26 { 30 {
31 "Unit": "CPU-M-CF",
27 "EventCode": "68", 32 "EventCode": "68",
28 "EventName": "SHA_FUNCTIONS", 33 "EventName": "SHA_FUNCTIONS",
29 "BriefDescription": "SHA Functions", 34 "BriefDescription": "SHA Functions",
30 "PublicDescription": "Total number of SHA functions issued by the CPU" 35 "PublicDescription": "Total number of SHA functions issued by the CPU"
31 }, 36 },
32 { 37 {
38 "Unit": "CPU-M-CF",
33 "EventCode": "69", 39 "EventCode": "69",
34 "EventName": "SHA_CYCLES", 40 "EventName": "SHA_CYCLES",
35 "BriefDescription": "SHA Cycles", 41 "BriefDescription": "SHA Cycles",
36 "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU" 42 "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU"
37 }, 43 },
38 { 44 {
45 "Unit": "CPU-M-CF",
39 "EventCode": "70", 46 "EventCode": "70",
40 "EventName": "SHA_BLOCKED_FUNCTIONS", 47 "EventName": "SHA_BLOCKED_FUNCTIONS",
41 "BriefDescription": "SHA Blocked Functions", 48 "BriefDescription": "SHA Blocked Functions",
42 "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU" 49 "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU"
43 }, 50 },
44 { 51 {
52 "Unit": "CPU-M-CF",
45 "EventCode": "71", 53 "EventCode": "71",
46 "EventName": "SHA_BLOCKED_CYCLES", 54 "EventName": "SHA_BLOCKED_CYCLES",
47 "BriefDescription": "SHA Bloced Cycles", 55 "BriefDescription": "SHA Bloced Cycles",
48 "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU" 56 "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU"
49 }, 57 },
50 { 58 {
59 "Unit": "CPU-M-CF",
51 "EventCode": "72", 60 "EventCode": "72",
52 "EventName": "DEA_FUNCTIONS", 61 "EventName": "DEA_FUNCTIONS",
53 "BriefDescription": "DEA Functions", 62 "BriefDescription": "DEA Functions",
54 "PublicDescription": "Total number of the DEA functions issued by the CPU" 63 "PublicDescription": "Total number of the DEA functions issued by the CPU"
55 }, 64 },
56 { 65 {
66 "Unit": "CPU-M-CF",
57 "EventCode": "73", 67 "EventCode": "73",
58 "EventName": "DEA_CYCLES", 68 "EventName": "DEA_CYCLES",
59 "BriefDescription": "DEA Cycles", 69 "BriefDescription": "DEA Cycles",
60 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU" 70 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU"
61 }, 71 },
62 { 72 {
73 "Unit": "CPU-M-CF",
63 "EventCode": "74", 74 "EventCode": "74",
64 "EventName": "DEA_BLOCKED_FUNCTIONS", 75 "EventName": "DEA_BLOCKED_FUNCTIONS",
65 "BriefDescription": "DEA Blocked Functions", 76 "BriefDescription": "DEA Blocked Functions",
66 "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" 77 "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
67 }, 78 },
68 { 79 {
80 "Unit": "CPU-M-CF",
69 "EventCode": "75", 81 "EventCode": "75",
70 "EventName": "DEA_BLOCKED_CYCLES", 82 "EventName": "DEA_BLOCKED_CYCLES",
71 "BriefDescription": "DEA Blocked Cycles", 83 "BriefDescription": "DEA Blocked Cycles",
72 "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" 84 "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
73 }, 85 },
74 { 86 {
87 "Unit": "CPU-M-CF",
75 "EventCode": "76", 88 "EventCode": "76",
76 "EventName": "AES_FUNCTIONS", 89 "EventName": "AES_FUNCTIONS",
77 "BriefDescription": "AES Functions", 90 "BriefDescription": "AES Functions",
78 "PublicDescription": "Total number of AES functions issued by the CPU" 91 "PublicDescription": "Total number of AES functions issued by the CPU"
79 }, 92 },
80 { 93 {
94 "Unit": "CPU-M-CF",
81 "EventCode": "77", 95 "EventCode": "77",
82 "EventName": "AES_CYCLES", 96 "EventName": "AES_CYCLES",
83 "BriefDescription": "AES Cycles", 97 "BriefDescription": "AES Cycles",
84 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU" 98 "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU"
85 }, 99 },
86 { 100 {
101 "Unit": "CPU-M-CF",
87 "EventCode": "78", 102 "EventCode": "78",
88 "EventName": "AES_BLOCKED_FUNCTIONS", 103 "EventName": "AES_BLOCKED_FUNCTIONS",
89 "BriefDescription": "AES Blocked Functions", 104 "BriefDescription": "AES Blocked Functions",
90 "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" 105 "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
91 }, 106 },
92 { 107 {
108 "Unit": "CPU-M-CF",
93 "EventCode": "79", 109 "EventCode": "79",
94 "EventName": "AES_BLOCKED_CYCLES", 110 "EventName": "AES_BLOCKED_CYCLES",
95 "BriefDescription": "AES Blocked Cycles", 111 "BriefDescription": "AES Blocked Cycles",
diff --git a/tools/perf/pmu-events/arch/s390/cf_zec12/extended.json b/tools/perf/pmu-events/arch/s390/cf_zec12/extended.json
index 8682126aabb2..162251037219 100644
--- a/tools/perf/pmu-events/arch/s390/cf_zec12/extended.json
+++ b/tools/perf/pmu-events/arch/s390/cf_zec12/extended.json
@@ -1,209 +1,244 @@
1[ 1[
2 { 2 {
3 "Unit": "CPU-M-CF",
3 "EventCode": "128", 4 "EventCode": "128",
4 "EventName": "DTLB1_MISSES", 5 "EventName": "DTLB1_MISSES",
5 "BriefDescription": "DTLB1 Misses", 6 "BriefDescription": "DTLB1 Misses",
6 "PublicDescription": "Level-1 Data TLB miss in progress. Incremented by one for every cycle a DTLB1 miss is in progress." 7 "PublicDescription": "Level-1 Data TLB miss in progress. Incremented by one for every cycle a DTLB1 miss is in progress."
7 }, 8 },
8 { 9 {
10 "Unit": "CPU-M-CF",
9 "EventCode": "129", 11 "EventCode": "129",
10 "EventName": "ITLB1_MISSES", 12 "EventName": "ITLB1_MISSES",
11 "BriefDescription": "ITLB1 Misses", 13 "BriefDescription": "ITLB1 Misses",
12 "PublicDescription": "Level-1 Instruction TLB miss in progress. Incremented by one for every cycle a ITLB1 miss is in progress." 14 "PublicDescription": "Level-1 Instruction TLB miss in progress. Incremented by one for every cycle a ITLB1 miss is in progress."
13 }, 15 },
14 { 16 {
17 "Unit": "CPU-M-CF",
15 "EventCode": "130", 18 "EventCode": "130",
16 "EventName": "L1D_L2I_SOURCED_WRITES", 19 "EventName": "L1D_L2I_SOURCED_WRITES",
17 "BriefDescription": "L1D L2I Sourced Writes", 20 "BriefDescription": "L1D L2I Sourced Writes",
18 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Instruction cache" 21 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Instruction cache"
19 }, 22 },
20 { 23 {
24 "Unit": "CPU-M-CF",
21 "EventCode": "131", 25 "EventCode": "131",
22 "EventName": "L1I_L2I_SOURCED_WRITES", 26 "EventName": "L1I_L2I_SOURCED_WRITES",
23 "BriefDescription": "L1I L2I Sourced Writes", 27 "BriefDescription": "L1I L2I Sourced Writes",
24 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from the Level-2 Instruction cache" 28 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from the Level-2 Instruction cache"
25 }, 29 },
26 { 30 {
31 "Unit": "CPU-M-CF",
27 "EventCode": "132", 32 "EventCode": "132",
28 "EventName": "L1D_L2D_SOURCED_WRITES", 33 "EventName": "L1D_L2D_SOURCED_WRITES",
29 "BriefDescription": "L1D L2D Sourced Writes", 34 "BriefDescription": "L1D L2D Sourced Writes",
30 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Data cache" 35 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Data cache"
31 }, 36 },
32 { 37 {
38 "Unit": "CPU-M-CF",
33 "EventCode": "133", 39 "EventCode": "133",
34 "EventName": "DTLB1_WRITES", 40 "EventName": "DTLB1_WRITES",
35 "BriefDescription": "DTLB1 Writes", 41 "BriefDescription": "DTLB1 Writes",
36 "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer" 42 "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer"
37 }, 43 },
38 { 44 {
45 "Unit": "CPU-M-CF",
39 "EventCode": "135", 46 "EventCode": "135",
40 "EventName": "L1D_LMEM_SOURCED_WRITES", 47 "EventName": "L1D_LMEM_SOURCED_WRITES",
41 "BriefDescription": "L1D Local Memory Sourced Writes", 48 "BriefDescription": "L1D Local Memory Sourced Writes",
42 "PublicDescription": "A directory write to the Level-1 Data cache where the installed cache line was sourced from memory that is attached to the same book as the Data cache (Local Memory)" 49 "PublicDescription": "A directory write to the Level-1 Data cache where the installed cache line was sourced from memory that is attached to the same book as the Data cache (Local Memory)"
43 }, 50 },
44 { 51 {
52 "Unit": "CPU-M-CF",
45 "EventCode": "137", 53 "EventCode": "137",
46 "EventName": "L1I_LMEM_SOURCED_WRITES", 54 "EventName": "L1I_LMEM_SOURCED_WRITES",
47 "BriefDescription": "L1I Local Memory Sourced Writes", 55 "BriefDescription": "L1I Local Memory Sourced Writes",
48 "PublicDescription": "A directory write to the Level-1 Instruction cache where the installed cache line was sourced from memory that is attached to the same book as the Instruction cache (Local Memory)" 56 "PublicDescription": "A directory write to the Level-1 Instruction cache where the installed cache line was sourced from memory that is attached to the same book as the Instruction cache (Local Memory)"
49 }, 57 },
50 { 58 {
59 "Unit": "CPU-M-CF",
51 "EventCode": "138", 60 "EventCode": "138",
52 "EventName": "L1D_RO_EXCL_WRITES", 61 "EventName": "L1D_RO_EXCL_WRITES",
53 "BriefDescription": "L1D Read-only Exclusive Writes", 62 "BriefDescription": "L1D Read-only Exclusive Writes",
54 "PublicDescription": "A directory write to the Level-1 D-Cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line" 63 "PublicDescription": "A directory write to the Level-1 D-Cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line"
55 }, 64 },
56 { 65 {
66 "Unit": "CPU-M-CF",
57 "EventCode": "139", 67 "EventCode": "139",
58 "EventName": "DTLB1_HPAGE_WRITES", 68 "EventName": "DTLB1_HPAGE_WRITES",
59 "BriefDescription": "DTLB1 One-Megabyte Page Writes", 69 "BriefDescription": "DTLB1 One-Megabyte Page Writes",
60 "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer for a one-megabyte page" 70 "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer for a one-megabyte page"
61 }, 71 },
62 { 72 {
73 "Unit": "CPU-M-CF",
63 "EventCode": "140", 74 "EventCode": "140",
64 "EventName": "ITLB1_WRITES", 75 "EventName": "ITLB1_WRITES",
65 "BriefDescription": "ITLB1 Writes", 76 "BriefDescription": "ITLB1 Writes",
66 "PublicDescription": "A translation entry has been written to the Level-1 Instruction Translation Lookaside Buffer" 77 "PublicDescription": "A translation entry has been written to the Level-1 Instruction Translation Lookaside Buffer"
67 }, 78 },
68 { 79 {
80 "Unit": "CPU-M-CF",
69 "EventCode": "141", 81 "EventCode": "141",
70 "EventName": "TLB2_PTE_WRITES", 82 "EventName": "TLB2_PTE_WRITES",
71 "BriefDescription": "TLB2 PTE Writes", 83 "BriefDescription": "TLB2 PTE Writes",
72 "PublicDescription": "A translation entry has been written to the Level-2 TLB Page Table Entry arrays" 84 "PublicDescription": "A translation entry has been written to the Level-2 TLB Page Table Entry arrays"
73 }, 85 },
74 { 86 {
87 "Unit": "CPU-M-CF",
75 "EventCode": "142", 88 "EventCode": "142",
76 "EventName": "TLB2_CRSTE_HPAGE_WRITES", 89 "EventName": "TLB2_CRSTE_HPAGE_WRITES",
77 "BriefDescription": "TLB2 CRSTE One-Megabyte Page Writes", 90 "BriefDescription": "TLB2 CRSTE One-Megabyte Page Writes",
78 "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays for a one-megabyte large page translation" 91 "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays for a one-megabyte large page translation"
79 }, 92 },
80 { 93 {
94 "Unit": "CPU-M-CF",
81 "EventCode": "143", 95 "EventCode": "143",
82 "EventName": "TLB2_CRSTE_WRITES", 96 "EventName": "TLB2_CRSTE_WRITES",
83 "BriefDescription": "TLB2 CRSTE Writes", 97 "BriefDescription": "TLB2 CRSTE Writes",
84 "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays" 98 "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays"
85 }, 99 },
86 { 100 {
101 "Unit": "CPU-M-CF",
87 "EventCode": "144", 102 "EventCode": "144",
88 "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES", 103 "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES",
89 "BriefDescription": "L1D On-Chip L3 Sourced Writes", 104 "BriefDescription": "L1D On-Chip L3 Sourced Writes",
90 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On Chip Level-3 cache without intervention" 105 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On Chip Level-3 cache without intervention"
91 }, 106 },
92 { 107 {
108 "Unit": "CPU-M-CF",
93 "EventCode": "145", 109 "EventCode": "145",
94 "EventName": "L1D_OFFCHIP_L3_SOURCED_WRITES", 110 "EventName": "L1D_OFFCHIP_L3_SOURCED_WRITES",
95 "BriefDescription": "L1D Off-Chip L3 Sourced Writes", 111 "BriefDescription": "L1D Off-Chip L3 Sourced Writes",
96 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache without intervention" 112 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache without intervention"
97 }, 113 },
98 { 114 {
115 "Unit": "CPU-M-CF",
99 "EventCode": "146", 116 "EventCode": "146",
100 "EventName": "L1D_OFFBOOK_L3_SOURCED_WRITES", 117 "EventName": "L1D_OFFBOOK_L3_SOURCED_WRITES",
101 "BriefDescription": "L1D Off-Book L3 Sourced Writes", 118 "BriefDescription": "L1D Off-Book L3 Sourced Writes",
102 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Book Level-3 cache without intervention" 119 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Book Level-3 cache without intervention"
103 }, 120 },
104 { 121 {
122 "Unit": "CPU-M-CF",
105 "EventCode": "147", 123 "EventCode": "147",
106 "EventName": "L1D_ONBOOK_L4_SOURCED_WRITES", 124 "EventName": "L1D_ONBOOK_L4_SOURCED_WRITES",
107 "BriefDescription": "L1D On-Book L4 Sourced Writes", 125 "BriefDescription": "L1D On-Book L4 Sourced Writes",
108 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On Book Level-4 cache" 126 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On Book Level-4 cache"
109 }, 127 },
110 { 128 {
129 "Unit": "CPU-M-CF",
111 "EventCode": "148", 130 "EventCode": "148",
112 "EventName": "L1D_OFFBOOK_L4_SOURCED_WRITES", 131 "EventName": "L1D_OFFBOOK_L4_SOURCED_WRITES",
113 "BriefDescription": "L1D Off-Book L4 Sourced Writes", 132 "BriefDescription": "L1D Off-Book L4 Sourced Writes",
114 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Book Level-4 cache" 133 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Book Level-4 cache"
115 }, 134 },
116 { 135 {
136 "Unit": "CPU-M-CF",
117 "EventCode": "149", 137 "EventCode": "149",
118 "EventName": "TX_NC_TEND", 138 "EventName": "TX_NC_TEND",
119 "BriefDescription": "Completed TEND instructions in non-constrained TX mode", 139 "BriefDescription": "Completed TEND instructions in non-constrained TX mode",
120 "PublicDescription": "A TEND instruction has completed in a nonconstrained transactional-execution mode" 140 "PublicDescription": "A TEND instruction has completed in a nonconstrained transactional-execution mode"
121 }, 141 },
122 { 142 {
143 "Unit": "CPU-M-CF",
123 "EventCode": "150", 144 "EventCode": "150",
124 "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_IV", 145 "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_IV",
125 "BriefDescription": "L1D On-Chip L3 Sourced Writes with Intervention", 146 "BriefDescription": "L1D On-Chip L3 Sourced Writes with Intervention",
126 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from a On Chip Level-3 cache with intervention" 147 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from a On Chip Level-3 cache with intervention"
127 }, 148 },
128 { 149 {
150 "Unit": "CPU-M-CF",
129 "EventCode": "151", 151 "EventCode": "151",
130 "EventName": "L1D_OFFCHIP_L3_SOURCED_WRITES_IV", 152 "EventName": "L1D_OFFCHIP_L3_SOURCED_WRITES_IV",
131 "BriefDescription": "L1D Off-Chip L3 Sourced Writes with Intervention", 153 "BriefDescription": "L1D Off-Chip L3 Sourced Writes with Intervention",
132 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache with intervention" 154 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache with intervention"
133 }, 155 },
134 { 156 {
157 "Unit": "CPU-M-CF",
135 "EventCode": "152", 158 "EventCode": "152",
136 "EventName": "L1D_OFFBOOK_L3_SOURCED_WRITES_IV", 159 "EventName": "L1D_OFFBOOK_L3_SOURCED_WRITES_IV",
137 "BriefDescription": "L1D Off-Book L3 Sourced Writes with Intervention", 160 "BriefDescription": "L1D Off-Book L3 Sourced Writes with Intervention",
138 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Book Level-3 cache with intervention" 161 "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Book Level-3 cache with intervention"
139 }, 162 },
140 { 163 {
164 "Unit": "CPU-M-CF",
141 "EventCode": "153", 165 "EventCode": "153",
142 "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES", 166 "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES",
143 "BriefDescription": "L1I On-Chip L3 Sourced Writes", 167 "BriefDescription": "L1I On-Chip L3 Sourced Writes",
144 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On Chip Level-3 cache without intervention" 168 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On Chip Level-3 cache without intervention"
145 }, 169 },
146 { 170 {
171 "Unit": "CPU-M-CF",
147 "EventCode": "154", 172 "EventCode": "154",
148 "EventName": "L1I_OFFCHIP_L3_SOURCED_WRITES", 173 "EventName": "L1I_OFFCHIP_L3_SOURCED_WRITES",
149 "BriefDescription": "L1I Off-Chip L3 Sourced Writes", 174 "BriefDescription": "L1I Off-Chip L3 Sourced Writes",
150 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache without intervention" 175 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache without intervention"
151 }, 176 },
152 { 177 {
178 "Unit": "CPU-M-CF",
153 "EventCode": "155", 179 "EventCode": "155",
154 "EventName": "L1I_OFFBOOK_L3_SOURCED_WRITES", 180 "EventName": "L1I_OFFBOOK_L3_SOURCED_WRITES",
155 "BriefDescription": "L1I Off-Book L3 Sourced Writes", 181 "BriefDescription": "L1I Off-Book L3 Sourced Writes",
156 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Book Level-3 cache without intervention" 182 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Book Level-3 cache without intervention"
157 }, 183 },
158 { 184 {
185 "Unit": "CPU-M-CF",
159 "EventCode": "156", 186 "EventCode": "156",
160 "EventName": "L1I_ONBOOK_L4_SOURCED_WRITES", 187 "EventName": "L1I_ONBOOK_L4_SOURCED_WRITES",
161 "BriefDescription": "L1I On-Book L4 Sourced Writes", 188 "BriefDescription": "L1I On-Book L4 Sourced Writes",
162 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On Book Level-4 cache" 189 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On Book Level-4 cache"
163 }, 190 },
164 { 191 {
192 "Unit": "CPU-M-CF",
165 "EventCode": "157", 193 "EventCode": "157",
166 "EventName": "L1I_OFFBOOK_L4_SOURCED_WRITES", 194 "EventName": "L1I_OFFBOOK_L4_SOURCED_WRITES",
167 "BriefDescription": "L1I Off-Book L4 Sourced Writes", 195 "BriefDescription": "L1I Off-Book L4 Sourced Writes",
168 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Book Level-4 cache" 196 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Book Level-4 cache"
169 }, 197 },
170 { 198 {
199 "Unit": "CPU-M-CF",
171 "EventCode": "158", 200 "EventCode": "158",
172 "EventName": "TX_C_TEND", 201 "EventName": "TX_C_TEND",
173 "BriefDescription": "Completed TEND instructions in constrained TX mode", 202 "BriefDescription": "Completed TEND instructions in constrained TX mode",
174 "PublicDescription": "A TEND instruction has completed in a constrained transactional-execution mode" 203 "PublicDescription": "A TEND instruction has completed in a constrained transactional-execution mode"
175 }, 204 },
176 { 205 {
206 "Unit": "CPU-M-CF",
177 "EventCode": "159", 207 "EventCode": "159",
178 "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES_IV", 208 "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES_IV",
179 "BriefDescription": "L1I On-Chip L3 Sourced Writes with Intervention", 209 "BriefDescription": "L1I On-Chip L3 Sourced Writes with Intervention",
180 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On Chip Level-3 cache with intervention" 210 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On Chip Level-3 cache with intervention"
181 }, 211 },
182 { 212 {
213 "Unit": "CPU-M-CF",
183 "EventCode": "160", 214 "EventCode": "160",
184 "EventName": "L1I_OFFCHIP_L3_SOURCED_WRITES_IV", 215 "EventName": "L1I_OFFCHIP_L3_SOURCED_WRITES_IV",
185 "BriefDescription": "L1I Off-Chip L3 Sourced Writes with Intervention", 216 "BriefDescription": "L1I Off-Chip L3 Sourced Writes with Intervention",
186 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache with intervention" 217 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache with intervention"
187 }, 218 },
188 { 219 {
220 "Unit": "CPU-M-CF",
189 "EventCode": "161", 221 "EventCode": "161",
190 "EventName": "L1I_OFFBOOK_L3_SOURCED_WRITES_IV", 222 "EventName": "L1I_OFFBOOK_L3_SOURCED_WRITES_IV",
191 "BriefDescription": "L1I Off-Book L3 Sourced Writes with Intervention", 223 "BriefDescription": "L1I Off-Book L3 Sourced Writes with Intervention",
192 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Book Level-3 cache with intervention" 224 "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Book Level-3 cache with intervention"
193 }, 225 },
194 { 226 {
227 "Unit": "CPU-M-CF",
195 "EventCode": "177", 228 "EventCode": "177",
196 "EventName": "TX_NC_TABORT", 229 "EventName": "TX_NC_TABORT",
197 "BriefDescription": "Aborted transactions in non-constrained TX mode", 230 "BriefDescription": "Aborted transactions in non-constrained TX mode",
198 "PublicDescription": "A transaction abort has occurred in a nonconstrained transactional-execution mode" 231 "PublicDescription": "A transaction abort has occurred in a nonconstrained transactional-execution mode"
199 }, 232 },
200 { 233 {
234 "Unit": "CPU-M-CF",
201 "EventCode": "178", 235 "EventCode": "178",
202 "EventName": "TX_C_TABORT_NO_SPECIAL", 236 "EventName": "TX_C_TABORT_NO_SPECIAL",
203 "BriefDescription": "Aborted transactions in constrained TX mode not using special completion logic", 237 "BriefDescription": "Aborted transactions in constrained TX mode not using special completion logic",
204 "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is not using any special logic to allow the transaction to complete" 238 "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is not using any special logic to allow the transaction to complete"
205 }, 239 },
206 { 240 {
241 "Unit": "CPU-M-CF",
207 "EventCode": "179", 242 "EventCode": "179",
208 "EventName": "TX_C_TABORT_SPECIAL", 243 "EventName": "TX_C_TABORT_SPECIAL",
209 "BriefDescription": "Aborted transactions in constrained TX mode using special completion logic", 244 "BriefDescription": "Aborted transactions in constrained TX mode using special completion logic",
diff --git a/tools/perf/pmu-events/arch/s390/cf_zec12/transaction.json b/tools/perf/pmu-events/arch/s390/cf_zec12/transaction.json
new file mode 100644
index 000000000000..1a0034f79f73
--- /dev/null
+++ b/tools/perf/pmu-events/arch/s390/cf_zec12/transaction.json
@@ -0,0 +1,7 @@
1[
2 {
3 "BriefDescription": "Transaction count",
4 "MetricName": "transaction",
5 "MetricExpr": "TX_C_TEND + TX_NC_TEND + TX_NC_TABORT + TX_C_TABORT_SPECIAL + TX_C_TABORT_NO_SPECIAL"
6 }
7]
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index db3a594ee1e4..68c92bb599ee 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -233,6 +233,8 @@ static struct map {
233 { "QPI LL", "uncore_qpi" }, 233 { "QPI LL", "uncore_qpi" },
234 { "SBO", "uncore_sbox" }, 234 { "SBO", "uncore_sbox" },
235 { "iMPH-U", "uncore_arb" }, 235 { "iMPH-U", "uncore_arb" },
236 { "CPU-M-CF", "cpum_cf" },
237 { "CPU-M-SF", "cpum_sf" },
236 {} 238 {}
237}; 239};
238 240
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index dd850a26d579..d7a5e1b9aa6f 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -385,7 +385,7 @@ static int test_and_print(struct test *t, bool force_skip, int subtest)
385 if (!t->subtest.get_nr) 385 if (!t->subtest.get_nr)
386 pr_debug("%s:", t->desc); 386 pr_debug("%s:", t->desc);
387 else 387 else
388 pr_debug("%s subtest %d:", t->desc, subtest); 388 pr_debug("%s subtest %d:", t->desc, subtest + 1);
389 389
390 switch (err) { 390 switch (err) {
391 case TEST_OK: 391 case TEST_OK:
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index 61211918bfba..3b97ac018d5a 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -1322,6 +1322,14 @@ static int test__intel_pt(struct perf_evlist *evlist)
1322 return 0; 1322 return 0;
1323} 1323}
1324 1324
1325static int test__checkevent_complex_name(struct perf_evlist *evlist)
1326{
1327 struct perf_evsel *evsel = perf_evlist__first(evlist);
1328
1329 TEST_ASSERT_VAL("wrong complex name parsing", strcmp(evsel->name, "COMPLEX_CYCLES_NAME:orig=cycles,desc=chip-clock-ticks") == 0);
1330 return 0;
1331}
1332
1325static int count_tracepoints(void) 1333static int count_tracepoints(void)
1326{ 1334{
1327 struct dirent *events_ent; 1335 struct dirent *events_ent;
@@ -1658,6 +1666,11 @@ static struct evlist_test test__events[] = {
1658 .check = test__intel_pt, 1666 .check = test__intel_pt,
1659 .id = 52, 1667 .id = 52,
1660 }, 1668 },
1669 {
1670 .name = "cycles/name='COMPLEX_CYCLES_NAME:orig=cycles,desc=chip-clock-ticks'/Duk",
1671 .check = test__checkevent_complex_name,
1672 .id = 53
1673 }
1661}; 1674};
1662 1675
1663static struct evlist_test test__events_pmu[] = { 1676static struct evlist_test test__events_pmu[] = {
@@ -1676,6 +1689,11 @@ static struct evlist_test test__events_pmu[] = {
1676 .check = test__checkevent_pmu_partial_time_callgraph, 1689 .check = test__checkevent_pmu_partial_time_callgraph,
1677 .id = 2, 1690 .id = 2,
1678 }, 1691 },
1692 {
1693 .name = "cpu/name='COMPLEX_CYCLES_NAME:orig=cycles,desc=chip-clock-ticks',period=0x1,event=0x2/ukp",
1694 .check = test__checkevent_complex_name,
1695 .id = 3,
1696 }
1679}; 1697};
1680 1698
1681struct terms_test { 1699struct terms_test {
diff --git a/tools/perf/tests/shell/record+probe_libc_inet_pton.sh b/tools/perf/tests/shell/record+probe_libc_inet_pton.sh
index 94e513e62b34..3013ac8f83d0 100755
--- a/tools/perf/tests/shell/record+probe_libc_inet_pton.sh
+++ b/tools/perf/tests/shell/record+probe_libc_inet_pton.sh
@@ -13,11 +13,24 @@
13libc=$(grep -w libc /proc/self/maps | head -1 | sed -r 's/.*[[:space:]](\/.*)/\1/g') 13libc=$(grep -w libc /proc/self/maps | head -1 | sed -r 's/.*[[:space:]](\/.*)/\1/g')
14nm -Dg $libc 2>/dev/null | fgrep -q inet_pton || exit 254 14nm -Dg $libc 2>/dev/null | fgrep -q inet_pton || exit 254
15 15
16event_pattern='probe_libc:inet_pton(\_[[:digit:]]+)?'
17
18add_libc_inet_pton_event() {
19
20 event_name=$(perf probe -f -x $libc -a inet_pton 2>&1 | tail -n +2 | head -n -5 | \
21 grep -P -o "$event_pattern(?=[[:space:]]\(on inet_pton in $libc\))")
22
23 if [ $? -ne 0 -o -z "$event_name" ] ; then
24 printf "FAIL: could not add event\n"
25 return 1
26 fi
27}
28
16trace_libc_inet_pton_backtrace() { 29trace_libc_inet_pton_backtrace() {
17 30
18 expected=`mktemp -u /tmp/expected.XXX` 31 expected=`mktemp -u /tmp/expected.XXX`
19 32
20 echo "ping[][0-9 \.:]+probe_libc:inet_pton: \([[:xdigit:]]+\)" > $expected 33 echo "ping[][0-9 \.:]+$event_name: \([[:xdigit:]]+\)" > $expected
21 echo ".*inet_pton\+0x[[:xdigit:]]+[[:space:]]\($libc|inlined\)$" >> $expected 34 echo ".*inet_pton\+0x[[:xdigit:]]+[[:space:]]\($libc|inlined\)$" >> $expected
22 case "$(uname -m)" in 35 case "$(uname -m)" in
23 s390x) 36 s390x)
@@ -26,6 +39,12 @@ trace_libc_inet_pton_backtrace() {
26 echo "(__GI_)?getaddrinfo\+0x[[:xdigit:]]+[[:space:]]\($libc|inlined\)$" >> $expected 39 echo "(__GI_)?getaddrinfo\+0x[[:xdigit:]]+[[:space:]]\($libc|inlined\)$" >> $expected
27 echo "main\+0x[[:xdigit:]]+[[:space:]]\(.*/bin/ping.*\)$" >> $expected 40 echo "main\+0x[[:xdigit:]]+[[:space:]]\(.*/bin/ping.*\)$" >> $expected
28 ;; 41 ;;
42 ppc64|ppc64le)
43 eventattr='max-stack=4'
44 echo "gaih_inet.*\+0x[[:xdigit:]]+[[:space:]]\($libc\)$" >> $expected
45 echo "getaddrinfo\+0x[[:xdigit:]]+[[:space:]]\($libc\)$" >> $expected
46 echo ".*\+0x[[:xdigit:]]+[[:space:]]\(.*/bin/ping.*\)$" >> $expected
47 ;;
29 *) 48 *)
30 eventattr='max-stack=3' 49 eventattr='max-stack=3'
31 echo "getaddrinfo\+0x[[:xdigit:]]+[[:space:]]\($libc\)$" >> $expected 50 echo "getaddrinfo\+0x[[:xdigit:]]+[[:space:]]\($libc\)$" >> $expected
@@ -35,7 +54,7 @@ trace_libc_inet_pton_backtrace() {
35 54
36 perf_data=`mktemp -u /tmp/perf.data.XXX` 55 perf_data=`mktemp -u /tmp/perf.data.XXX`
37 perf_script=`mktemp -u /tmp/perf.script.XXX` 56 perf_script=`mktemp -u /tmp/perf.script.XXX`
38 perf record -e probe_libc:inet_pton/$eventattr/ -o $perf_data ping -6 -c 1 ::1 > /dev/null 2>&1 57 perf record -e $event_name/$eventattr/ -o $perf_data ping -6 -c 1 ::1 > /dev/null 2>&1
39 perf script -i $perf_data > $perf_script 58 perf script -i $perf_data > $perf_script
40 59
41 exec 3<$perf_script 60 exec 3<$perf_script
@@ -46,7 +65,7 @@ trace_libc_inet_pton_backtrace() {
46 echo "$line" | egrep -q "$pattern" 65 echo "$line" | egrep -q "$pattern"
47 if [ $? -ne 0 ] ; then 66 if [ $? -ne 0 ] ; then
48 printf "FAIL: expected backtrace entry \"%s\" got \"%s\"\n" "$pattern" "$line" 67 printf "FAIL: expected backtrace entry \"%s\" got \"%s\"\n" "$pattern" "$line"
49 exit 1 68 return 1
50 fi 69 fi
51 done 70 done
52 71
@@ -56,13 +75,20 @@ trace_libc_inet_pton_backtrace() {
56 # even if the perf script output does not match. 75 # even if the perf script output does not match.
57} 76}
58 77
78delete_libc_inet_pton_event() {
79
80 if [ -n "$event_name" ] ; then
81 perf probe -q -d $event_name
82 fi
83}
84
59# Check for IPv6 interface existence 85# Check for IPv6 interface existence
60ip a sh lo | fgrep -q inet6 || exit 2 86ip a sh lo | fgrep -q inet6 || exit 2
61 87
62skip_if_no_perf_probe && \ 88skip_if_no_perf_probe && \
63perf probe -q $libc inet_pton && \ 89add_libc_inet_pton_event && \
64trace_libc_inet_pton_backtrace 90trace_libc_inet_pton_backtrace
65err=$? 91err=$?
66rm -f ${perf_data} ${perf_script} ${expected} 92rm -f ${perf_data} ${perf_script} ${expected}
67perf probe -q -d probe_libc:inet_pton 93delete_libc_inet_pton_event
68exit $err 94exit $err
diff --git a/tools/perf/trace/beauty/Build b/tools/perf/trace/beauty/Build
index 66330d4b739b..f528ba35e140 100644
--- a/tools/perf/trace/beauty/Build
+++ b/tools/perf/trace/beauty/Build
@@ -7,4 +7,5 @@ endif
7libperf-y += kcmp.o 7libperf-y += kcmp.o
8libperf-y += pkey_alloc.o 8libperf-y += pkey_alloc.o
9libperf-y += prctl.o 9libperf-y += prctl.o
10libperf-y += socket.o
10libperf-y += statx.o 11libperf-y += statx.o
diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h
index 984a504d335c..9615af5d412b 100644
--- a/tools/perf/trace/beauty/beauty.h
+++ b/tools/perf/trace/beauty/beauty.h
@@ -106,6 +106,9 @@ size_t syscall_arg__scnprintf_prctl_arg2(char *bf, size_t size, struct syscall_a
106size_t syscall_arg__scnprintf_prctl_arg3(char *bf, size_t size, struct syscall_arg *arg); 106size_t syscall_arg__scnprintf_prctl_arg3(char *bf, size_t size, struct syscall_arg *arg);
107#define SCA_PRCTL_ARG3 syscall_arg__scnprintf_prctl_arg3 107#define SCA_PRCTL_ARG3 syscall_arg__scnprintf_prctl_arg3
108 108
109size_t syscall_arg__scnprintf_socket_protocol(char *bf, size_t size, struct syscall_arg *arg);
110#define SCA_SK_PROTO syscall_arg__scnprintf_socket_protocol
111
109size_t syscall_arg__scnprintf_statx_flags(char *bf, size_t size, struct syscall_arg *arg); 112size_t syscall_arg__scnprintf_statx_flags(char *bf, size_t size, struct syscall_arg *arg);
110#define SCA_STATX_FLAGS syscall_arg__scnprintf_statx_flags 113#define SCA_STATX_FLAGS syscall_arg__scnprintf_statx_flags
111 114
diff --git a/tools/perf/trace/beauty/drm_ioctl.sh b/tools/perf/trace/beauty/drm_ioctl.sh
index 2149d3a98e42..9d3816815e60 100755
--- a/tools/perf/trace/beauty/drm_ioctl.sh
+++ b/tools/perf/trace/beauty/drm_ioctl.sh
@@ -1,13 +1,14 @@
1#!/bin/sh 1#!/bin/sh
2 2
3drm_header_dir=$1 3[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/drm/
4
4printf "#ifndef DRM_COMMAND_BASE\n" 5printf "#ifndef DRM_COMMAND_BASE\n"
5grep "#define DRM_COMMAND_BASE" $drm_header_dir/drm.h 6grep "#define DRM_COMMAND_BASE" $header_dir/drm.h
6printf "#endif\n" 7printf "#endif\n"
7 8
8printf "static const char *drm_ioctl_cmds[] = {\n" 9printf "static const char *drm_ioctl_cmds[] = {\n"
9grep "^#define DRM_IOCTL.*DRM_IO" $drm_header_dir/drm.h | \ 10grep "^#define DRM_IOCTL.*DRM_IO" $header_dir/drm.h | \
10 sed -r 's/^#define +DRM_IOCTL_([A-Z0-9_]+)[ ]+DRM_IO[A-Z]* *\( *(0x[[:xdigit:]]+),*.*/ [\2] = "\1",/g' 11 sed -r 's/^#define +DRM_IOCTL_([A-Z0-9_]+)[ ]+DRM_IO[A-Z]* *\( *(0x[[:xdigit:]]+),*.*/ [\2] = "\1",/g'
11grep "^#define DRM_I915_[A-Z_0-9]\+[ ]\+0x" $drm_header_dir/i915_drm.h | \ 12grep "^#define DRM_I915_[A-Z_0-9]\+[ ]\+0x" $header_dir/i915_drm.h | \
12 sed -r 's/^#define +DRM_I915_([A-Z0-9_]+)[ ]+(0x[[:xdigit:]]+)/\t[DRM_COMMAND_BASE + \2] = "I915_\1",/g' 13 sed -r 's/^#define +DRM_I915_([A-Z0-9_]+)[ ]+(0x[[:xdigit:]]+)/\t[DRM_COMMAND_BASE + \2] = "I915_\1",/g'
13printf "};\n" 14printf "};\n"
diff --git a/tools/perf/trace/beauty/kcmp_type.sh b/tools/perf/trace/beauty/kcmp_type.sh
index 40d063b8c082..a3c304caa336 100755
--- a/tools/perf/trace/beauty/kcmp_type.sh
+++ b/tools/perf/trace/beauty/kcmp_type.sh
@@ -1,6 +1,6 @@
1#!/bin/sh 1#!/bin/sh
2 2
3header_dir=$1 3[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/
4 4
5printf "static const char *kcmp_types[] = {\n" 5printf "static const char *kcmp_types[] = {\n"
6regex='^[[:space:]]+(KCMP_(\w+)),' 6regex='^[[:space:]]+(KCMP_(\w+)),'
diff --git a/tools/perf/trace/beauty/kvm_ioctl.sh b/tools/perf/trace/beauty/kvm_ioctl.sh
index bd28817afced..c4699fd46bb6 100755
--- a/tools/perf/trace/beauty/kvm_ioctl.sh
+++ b/tools/perf/trace/beauty/kvm_ioctl.sh
@@ -1,10 +1,10 @@
1#!/bin/sh 1#!/bin/sh
2 2
3kvm_header_dir=$1 3[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/
4 4
5printf "static const char *kvm_ioctl_cmds[] = {\n" 5printf "static const char *kvm_ioctl_cmds[] = {\n"
6regex='^#[[:space:]]*define[[:space:]]+KVM_(\w+)[[:space:]]+_IO[RW]*\([[:space:]]*KVMIO[[:space:]]*,[[:space:]]*(0x[[:xdigit:]]+).*' 6regex='^#[[:space:]]*define[[:space:]]+KVM_(\w+)[[:space:]]+_IO[RW]*\([[:space:]]*KVMIO[[:space:]]*,[[:space:]]*(0x[[:xdigit:]]+).*'
7egrep $regex ${kvm_header_dir}/kvm.h | \ 7egrep $regex ${header_dir}/kvm.h | \
8 sed -r "s/$regex/\2 \1/g" | \ 8 sed -r "s/$regex/\2 \1/g" | \
9 egrep -v " ((ARM|PPC|S390)_|[GS]ET_(DEBUGREGS|PIT2|XSAVE|TSC_KHZ)|CREATE_SPAPR_TCE_64)" | \ 9 egrep -v " ((ARM|PPC|S390)_|[GS]ET_(DEBUGREGS|PIT2|XSAVE|TSC_KHZ)|CREATE_SPAPR_TCE_64)" | \
10 sort | xargs printf "\t[%s] = \"%s\",\n" 10 sort | xargs printf "\t[%s] = \"%s\",\n"
diff --git a/tools/perf/trace/beauty/madvise_behavior.sh b/tools/perf/trace/beauty/madvise_behavior.sh
index 60ef8640ee70..431639eb4d29 100755
--- a/tools/perf/trace/beauty/madvise_behavior.sh
+++ b/tools/perf/trace/beauty/madvise_behavior.sh
@@ -1,6 +1,6 @@
1#!/bin/sh 1#!/bin/sh
2 2
3header_dir=$1 3[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/asm-generic/
4 4
5printf "static const char *madvise_advices[] = {\n" 5printf "static const char *madvise_advices[] = {\n"
6regex='^[[:space:]]*#[[:space:]]*define[[:space:]]+MADV_([[:alnum:]_]+)[[:space:]]+([[:digit:]]+)[[:space:]]*.*' 6regex='^[[:space:]]*#[[:space:]]*define[[:space:]]+MADV_([[:alnum:]_]+)[[:space:]]+([[:digit:]]+)[[:space:]]*.*'
diff --git a/tools/perf/trace/beauty/perf_ioctl.sh b/tools/perf/trace/beauty/perf_ioctl.sh
index faea4237c793..6492c74df928 100755
--- a/tools/perf/trace/beauty/perf_ioctl.sh
+++ b/tools/perf/trace/beauty/perf_ioctl.sh
@@ -1,6 +1,6 @@
1#!/bin/sh 1#!/bin/sh
2 2
3header_dir=$1 3[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/
4 4
5printf "static const char *perf_ioctl_cmds[] = {\n" 5printf "static const char *perf_ioctl_cmds[] = {\n"
6regex='^#[[:space:]]*define[[:space:]]+PERF_EVENT_IOC_(\w+)[[:space:]]+_IO[RW]*[[:space:]]*\([[:space:]]*.\$.[[:space:]]*,[[:space:]]*([[:digit:]]+).*' 6regex='^#[[:space:]]*define[[:space:]]+PERF_EVENT_IOC_(\w+)[[:space:]]+_IO[RW]*[[:space:]]*\([[:space:]]*.\$.[[:space:]]*,[[:space:]]*([[:digit:]]+).*'
diff --git a/tools/perf/trace/beauty/pkey_alloc_access_rights.sh b/tools/perf/trace/beauty/pkey_alloc_access_rights.sh
index 62e51a02b839..e0a51aeb20b2 100755
--- a/tools/perf/trace/beauty/pkey_alloc_access_rights.sh
+++ b/tools/perf/trace/beauty/pkey_alloc_access_rights.sh
@@ -1,6 +1,6 @@
1#!/bin/sh 1#!/bin/sh
2 2
3header_dir=$1 3[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/asm-generic/
4 4
5printf "static const char *pkey_alloc_access_rights[] = {\n" 5printf "static const char *pkey_alloc_access_rights[] = {\n"
6regex='^[[:space:]]*#[[:space:]]*define[[:space:]]+PKEY_([[:alnum:]_]+)[[:space:]]+(0x[[:xdigit:]]+)[[:space:]]*' 6regex='^[[:space:]]*#[[:space:]]*define[[:space:]]+PKEY_([[:alnum:]_]+)[[:space:]]+(0x[[:xdigit:]]+)[[:space:]]*'
diff --git a/tools/perf/trace/beauty/sndrv_ctl_ioctl.sh b/tools/perf/trace/beauty/sndrv_ctl_ioctl.sh
index aad5ab130539..eb511bb5fbd3 100755
--- a/tools/perf/trace/beauty/sndrv_ctl_ioctl.sh
+++ b/tools/perf/trace/beauty/sndrv_ctl_ioctl.sh
@@ -1,8 +1,8 @@
1#!/bin/sh 1#!/bin/sh
2 2
3sound_header_dir=$1 3[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/sound/
4 4
5printf "static const char *sndrv_ctl_ioctl_cmds[] = {\n" 5printf "static const char *sndrv_ctl_ioctl_cmds[] = {\n"
6grep "^#define[\t ]\+SNDRV_CTL_IOCTL_" $sound_header_dir/asound.h | \ 6grep "^#define[\t ]\+SNDRV_CTL_IOCTL_" $header_dir/asound.h | \
7 sed -r 's/^#define +SNDRV_CTL_IOCTL_([A-Z0-9_]+)[\t ]+_IO[RW]*\( *.U., *(0x[[:xdigit:]]+),?.*/\t[\2] = \"\1\",/g' 7 sed -r 's/^#define +SNDRV_CTL_IOCTL_([A-Z0-9_]+)[\t ]+_IO[RW]*\( *.U., *(0x[[:xdigit:]]+),?.*/\t[\2] = \"\1\",/g'
8printf "};\n" 8printf "};\n"
diff --git a/tools/perf/trace/beauty/sndrv_pcm_ioctl.sh b/tools/perf/trace/beauty/sndrv_pcm_ioctl.sh
index b7e9ef6b2f55..6818392968b2 100755
--- a/tools/perf/trace/beauty/sndrv_pcm_ioctl.sh
+++ b/tools/perf/trace/beauty/sndrv_pcm_ioctl.sh
@@ -1,8 +1,8 @@
1#!/bin/sh 1#!/bin/sh
2 2
3sound_header_dir=$1 3[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/sound/
4 4
5printf "static const char *sndrv_pcm_ioctl_cmds[] = {\n" 5printf "static const char *sndrv_pcm_ioctl_cmds[] = {\n"
6grep "^#define[\t ]\+SNDRV_PCM_IOCTL_" $sound_header_dir/asound.h | \ 6grep "^#define[\t ]\+SNDRV_PCM_IOCTL_" $header_dir/asound.h | \
7 sed -r 's/^#define +SNDRV_PCM_IOCTL_([A-Z0-9_]+)[\t ]+_IO[RW]*\( *.A., *(0x[[:xdigit:]]+),?.*/\t[\2] = \"\1\",/g' 7 sed -r 's/^#define +SNDRV_PCM_IOCTL_([A-Z0-9_]+)[\t ]+_IO[RW]*\( *.A., *(0x[[:xdigit:]]+),?.*/\t[\2] = \"\1\",/g'
8printf "};\n" 8printf "};\n"
diff --git a/tools/perf/trace/beauty/socket.c b/tools/perf/trace/beauty/socket.c
new file mode 100644
index 000000000000..65227269384b
--- /dev/null
+++ b/tools/perf/trace/beauty/socket.c
@@ -0,0 +1,28 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * trace/beauty/socket.c
4 *
5 * Copyright (C) 2018, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
6 */
7
8#include "trace/beauty/beauty.h"
9#include <sys/types.h>
10#include <sys/socket.h>
11
12static size_t socket__scnprintf_ipproto(int protocol, char *bf, size_t size)
13{
14#include "trace/beauty/generated/socket_ipproto_array.c"
15 static DEFINE_STRARRAY(socket_ipproto);
16
17 return strarray__scnprintf(&strarray__socket_ipproto, bf, size, "%d", protocol);
18}
19
20size_t syscall_arg__scnprintf_socket_protocol(char *bf, size_t size, struct syscall_arg *arg)
21{
22 int domain = syscall_arg__val(arg, 0);
23
24 if (domain == AF_INET || domain == AF_INET6)
25 return socket__scnprintf_ipproto(arg->val, bf, size);
26
27 return syscall_arg__scnprintf_int(bf, size, arg);
28}
diff --git a/tools/perf/trace/beauty/socket_ipproto.sh b/tools/perf/trace/beauty/socket_ipproto.sh
new file mode 100755
index 000000000000..a3cc24633bec
--- /dev/null
+++ b/tools/perf/trace/beauty/socket_ipproto.sh
@@ -0,0 +1,11 @@
1#!/bin/sh
2
3[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/
4
5printf "static const char *socket_ipproto[] = {\n"
6regex='^[[:space:]]+IPPROTO_(\w+)[[:space:]]+=[[:space:]]+([[:digit:]]+),.*'
7
8egrep $regex ${header_dir}/in.h | \
9 sed -r "s/$regex/\2 \1/g" | \
10 sort | xargs printf "\t[%s] = \"%s\",\n"
11printf "};\n"
diff --git a/tools/perf/trace/beauty/vhost_virtio_ioctl.sh b/tools/perf/trace/beauty/vhost_virtio_ioctl.sh
index 76f1de697787..0f6a5197d0be 100755
--- a/tools/perf/trace/beauty/vhost_virtio_ioctl.sh
+++ b/tools/perf/trace/beauty/vhost_virtio_ioctl.sh
@@ -1,17 +1,17 @@
1#!/bin/sh 1#!/bin/sh
2 2
3vhost_virtio_header_dir=$1 3[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/
4 4
5printf "static const char *vhost_virtio_ioctl_cmds[] = {\n" 5printf "static const char *vhost_virtio_ioctl_cmds[] = {\n"
6regex='^#[[:space:]]*define[[:space:]]+VHOST_(\w+)[[:space:]]+_IOW?\([[:space:]]*VHOST_VIRTIO[[:space:]]*,[[:space:]]*(0x[[:xdigit:]]+).*' 6regex='^#[[:space:]]*define[[:space:]]+VHOST_(\w+)[[:space:]]+_IOW?\([[:space:]]*VHOST_VIRTIO[[:space:]]*,[[:space:]]*(0x[[:xdigit:]]+).*'
7egrep $regex ${vhost_virtio_header_dir}/vhost.h | \ 7egrep $regex ${header_dir}/vhost.h | \
8 sed -r "s/$regex/\2 \1/g" | \ 8 sed -r "s/$regex/\2 \1/g" | \
9 sort | xargs printf "\t[%s] = \"%s\",\n" 9 sort | xargs printf "\t[%s] = \"%s\",\n"
10printf "};\n" 10printf "};\n"
11 11
12printf "static const char *vhost_virtio_ioctl_read_cmds[] = {\n" 12printf "static const char *vhost_virtio_ioctl_read_cmds[] = {\n"
13regex='^#[[:space:]]*define[[:space:]]+VHOST_(\w+)[[:space:]]+_IOW?R\([[:space:]]*VHOST_VIRTIO[[:space:]]*,[[:space:]]*(0x[[:xdigit:]]+).*' 13regex='^#[[:space:]]*define[[:space:]]+VHOST_(\w+)[[:space:]]+_IOW?R\([[:space:]]*VHOST_VIRTIO[[:space:]]*,[[:space:]]*(0x[[:xdigit:]]+).*'
14egrep $regex ${vhost_virtio_header_dir}/vhost.h | \ 14egrep $regex ${header_dir}/vhost.h | \
15 sed -r "s/$regex/\2 \1/g" | \ 15 sed -r "s/$regex/\2 \1/g" | \
16 sort | xargs printf "\t[%s] = \"%s\",\n" 16 sort | xargs printf "\t[%s] = \"%s\",\n"
17printf "};\n" 17printf "};\n"
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 69b7a28f7a1c..74c4ae1f0a05 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -529,7 +529,7 @@ out:
529 529
530static int hist_entry__fprintf(struct hist_entry *he, size_t size, 530static int hist_entry__fprintf(struct hist_entry *he, size_t size,
531 char *bf, size_t bfsz, FILE *fp, 531 char *bf, size_t bfsz, FILE *fp,
532 bool use_callchain) 532 bool ignore_callchains)
533{ 533{
534 int ret; 534 int ret;
535 int callchain_ret = 0; 535 int callchain_ret = 0;
@@ -550,7 +550,7 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size,
550 550
551 ret = fprintf(fp, "%s\n", bf); 551 ret = fprintf(fp, "%s\n", bf);
552 552
553 if (hist_entry__has_callchains(he) && use_callchain) 553 if (hist_entry__has_callchains(he) && !ignore_callchains)
554 callchain_ret = hist_entry_callchain__fprintf(he, total_period, 554 callchain_ret = hist_entry_callchain__fprintf(he, total_period,
555 0, fp); 555 0, fp);
556 556
@@ -755,7 +755,7 @@ int hists__fprintf_headers(struct hists *hists, FILE *fp)
755 755
756size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, 756size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
757 int max_cols, float min_pcnt, FILE *fp, 757 int max_cols, float min_pcnt, FILE *fp,
758 bool use_callchain) 758 bool ignore_callchains)
759{ 759{
760 struct rb_node *nd; 760 struct rb_node *nd;
761 size_t ret = 0; 761 size_t ret = 0;
@@ -799,7 +799,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
799 if (percent < min_pcnt) 799 if (percent < min_pcnt)
800 continue; 800 continue;
801 801
802 ret += hist_entry__fprintf(h, max_cols, line, linesz, fp, use_callchain); 802 ret += hist_entry__fprintf(h, max_cols, line, linesz, fp, ignore_callchains);
803 803
804 if (max_rows && ++nr_rows >= max_rows) 804 if (max_rows && ++nr_rows >= max_rows)
805 break; 805 break;
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index cee658733e2c..3d02ae38ec56 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -747,7 +747,9 @@ int bpf__load(struct bpf_object *obj)
747 747
748 err = bpf_object__load(obj); 748 err = bpf_object__load(obj);
749 if (err) { 749 if (err) {
750 pr_debug("bpf: load objects failed\n"); 750 char bf[128];
751 libbpf_strerror(err, bf, sizeof(bf));
752 pr_debug("bpf: load objects failed: err=%d: (%s)\n", err, bf);
751 return err; 753 return err;
752 } 754 }
753 return 0; 755 return 0;
diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c
index 7798a2cc8a86..31279a7bd919 100644
--- a/tools/perf/util/comm.c
+++ b/tools/perf/util/comm.c
@@ -20,9 +20,10 @@ static struct rw_semaphore comm_str_lock = {.lock = PTHREAD_RWLOCK_INITIALIZER,}
20 20
21static struct comm_str *comm_str__get(struct comm_str *cs) 21static struct comm_str *comm_str__get(struct comm_str *cs)
22{ 22{
23 if (cs) 23 if (cs && refcount_inc_not_zero(&cs->refcnt))
24 refcount_inc(&cs->refcnt); 24 return cs;
25 return cs; 25
26 return NULL;
26} 27}
27 28
28static void comm_str__put(struct comm_str *cs) 29static void comm_str__put(struct comm_str *cs)
@@ -67,9 +68,14 @@ struct comm_str *__comm_str__findnew(const char *str, struct rb_root *root)
67 parent = *p; 68 parent = *p;
68 iter = rb_entry(parent, struct comm_str, rb_node); 69 iter = rb_entry(parent, struct comm_str, rb_node);
69 70
71 /*
72 * If we race with comm_str__put, iter->refcnt is 0
73 * and it will be removed within comm_str__put call
74 * shortly, ignore it in this search.
75 */
70 cmp = strcmp(str, iter->str); 76 cmp = strcmp(str, iter->str);
71 if (!cmp) 77 if (!cmp && comm_str__get(iter))
72 return comm_str__get(iter); 78 return iter;
73 79
74 if (cmp < 0) 80 if (cmp < 0)
75 p = &(*p)->rb_left; 81 p = &(*p)->rb_left;
diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
index 4d5fc374e730..938def6d0bb9 100644
--- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
+++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
@@ -31,6 +31,8 @@
31#endif 31#endif
32#endif 32#endif
33 33
34#define CS_ETM_INVAL_ADDR 0xdeadbeefdeadbeefUL
35
34struct cs_etm_decoder { 36struct cs_etm_decoder {
35 void *data; 37 void *data;
36 void (*packet_printer)(const char *msg); 38 void (*packet_printer)(const char *msg);
@@ -261,8 +263,8 @@ static void cs_etm_decoder__clear_buffer(struct cs_etm_decoder *decoder)
261 decoder->tail = 0; 263 decoder->tail = 0;
262 decoder->packet_count = 0; 264 decoder->packet_count = 0;
263 for (i = 0; i < MAX_BUFFER; i++) { 265 for (i = 0; i < MAX_BUFFER; i++) {
264 decoder->packet_buffer[i].start_addr = 0xdeadbeefdeadbeefUL; 266 decoder->packet_buffer[i].start_addr = CS_ETM_INVAL_ADDR;
265 decoder->packet_buffer[i].end_addr = 0xdeadbeefdeadbeefUL; 267 decoder->packet_buffer[i].end_addr = CS_ETM_INVAL_ADDR;
266 decoder->packet_buffer[i].last_instr_taken_branch = false; 268 decoder->packet_buffer[i].last_instr_taken_branch = false;
267 decoder->packet_buffer[i].exc = false; 269 decoder->packet_buffer[i].exc = false;
268 decoder->packet_buffer[i].exc_ret = false; 270 decoder->packet_buffer[i].exc_ret = false;
@@ -295,8 +297,8 @@ cs_etm_decoder__buffer_packet(struct cs_etm_decoder *decoder,
295 decoder->packet_buffer[et].exc = false; 297 decoder->packet_buffer[et].exc = false;
296 decoder->packet_buffer[et].exc_ret = false; 298 decoder->packet_buffer[et].exc_ret = false;
297 decoder->packet_buffer[et].cpu = *((int *)inode->priv); 299 decoder->packet_buffer[et].cpu = *((int *)inode->priv);
298 decoder->packet_buffer[et].start_addr = 0xdeadbeefdeadbeefUL; 300 decoder->packet_buffer[et].start_addr = CS_ETM_INVAL_ADDR;
299 decoder->packet_buffer[et].end_addr = 0xdeadbeefdeadbeefUL; 301 decoder->packet_buffer[et].end_addr = CS_ETM_INVAL_ADDR;
300 302
301 if (decoder->packet_count == MAX_BUFFER - 1) 303 if (decoder->packet_count == MAX_BUFFER - 1)
302 return OCSD_RESP_WAIT; 304 return OCSD_RESP_WAIT;
diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h
index 743f5f444304..612b5755f742 100644
--- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h
+++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h
@@ -23,6 +23,7 @@ struct cs_etm_buffer {
23}; 23};
24 24
25enum cs_etm_sample_type { 25enum cs_etm_sample_type {
26 CS_ETM_EMPTY = 0,
26 CS_ETM_RANGE = 1 << 0, 27 CS_ETM_RANGE = 1 << 0,
27 CS_ETM_TRACE_ON = 1 << 1, 28 CS_ETM_TRACE_ON = 1 << 1,
28}; 29};
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index 822ba915d144..2ae640257fdb 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -494,6 +494,10 @@ static inline void cs_etm__reset_last_branch_rb(struct cs_etm_queue *etmq)
494 494
495static inline u64 cs_etm__last_executed_instr(struct cs_etm_packet *packet) 495static inline u64 cs_etm__last_executed_instr(struct cs_etm_packet *packet)
496{ 496{
497 /* Returns 0 for the CS_ETM_TRACE_ON packet */
498 if (packet->sample_type == CS_ETM_TRACE_ON)
499 return 0;
500
497 /* 501 /*
498 * The packet records the execution range with an exclusive end address 502 * The packet records the execution range with an exclusive end address
499 * 503 *
@@ -505,6 +509,15 @@ static inline u64 cs_etm__last_executed_instr(struct cs_etm_packet *packet)
505 return packet->end_addr - A64_INSTR_SIZE; 509 return packet->end_addr - A64_INSTR_SIZE;
506} 510}
507 511
512static inline u64 cs_etm__first_executed_instr(struct cs_etm_packet *packet)
513{
514 /* Returns 0 for the CS_ETM_TRACE_ON packet */
515 if (packet->sample_type == CS_ETM_TRACE_ON)
516 return 0;
517
518 return packet->start_addr;
519}
520
508static inline u64 cs_etm__instr_count(const struct cs_etm_packet *packet) 521static inline u64 cs_etm__instr_count(const struct cs_etm_packet *packet)
509{ 522{
510 /* 523 /*
@@ -546,7 +559,7 @@ static void cs_etm__update_last_branch_rb(struct cs_etm_queue *etmq)
546 559
547 be = &bs->entries[etmq->last_branch_pos]; 560 be = &bs->entries[etmq->last_branch_pos];
548 be->from = cs_etm__last_executed_instr(etmq->prev_packet); 561 be->from = cs_etm__last_executed_instr(etmq->prev_packet);
549 be->to = etmq->packet->start_addr; 562 be->to = cs_etm__first_executed_instr(etmq->packet);
550 /* No support for mispredict */ 563 /* No support for mispredict */
551 be->flags.mispred = 0; 564 be->flags.mispred = 0;
552 be->flags.predicted = 1; 565 be->flags.predicted = 1;
@@ -701,7 +714,7 @@ static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq)
701 sample.ip = cs_etm__last_executed_instr(etmq->prev_packet); 714 sample.ip = cs_etm__last_executed_instr(etmq->prev_packet);
702 sample.pid = etmq->pid; 715 sample.pid = etmq->pid;
703 sample.tid = etmq->tid; 716 sample.tid = etmq->tid;
704 sample.addr = etmq->packet->start_addr; 717 sample.addr = cs_etm__first_executed_instr(etmq->packet);
705 sample.id = etmq->etm->branches_id; 718 sample.id = etmq->etm->branches_id;
706 sample.stream_id = etmq->etm->branches_id; 719 sample.stream_id = etmq->etm->branches_id;
707 sample.period = 1; 720 sample.period = 1;
@@ -897,13 +910,23 @@ static int cs_etm__sample(struct cs_etm_queue *etmq)
897 etmq->period_instructions = instrs_over; 910 etmq->period_instructions = instrs_over;
898 } 911 }
899 912
900 if (etm->sample_branches && 913 if (etm->sample_branches && etmq->prev_packet) {
901 etmq->prev_packet && 914 bool generate_sample = false;
902 etmq->prev_packet->sample_type == CS_ETM_RANGE && 915
903 etmq->prev_packet->last_instr_taken_branch) { 916 /* Generate sample for tracing on packet */
904 ret = cs_etm__synth_branch_sample(etmq); 917 if (etmq->prev_packet->sample_type == CS_ETM_TRACE_ON)
905 if (ret) 918 generate_sample = true;
906 return ret; 919
920 /* Generate sample for branch taken packet */
921 if (etmq->prev_packet->sample_type == CS_ETM_RANGE &&
922 etmq->prev_packet->last_instr_taken_branch)
923 generate_sample = true;
924
925 if (generate_sample) {
926 ret = cs_etm__synth_branch_sample(etmq);
927 if (ret)
928 return ret;
929 }
907 } 930 }
908 931
909 if (etm->sample_branches || etm->synth_opts.last_branch) { 932 if (etm->sample_branches || etm->synth_opts.last_branch) {
@@ -922,10 +945,17 @@ static int cs_etm__sample(struct cs_etm_queue *etmq)
922static int cs_etm__flush(struct cs_etm_queue *etmq) 945static int cs_etm__flush(struct cs_etm_queue *etmq)
923{ 946{
924 int err = 0; 947 int err = 0;
948 struct cs_etm_auxtrace *etm = etmq->etm;
925 struct cs_etm_packet *tmp; 949 struct cs_etm_packet *tmp;
926 950
951 if (!etmq->prev_packet)
952 return 0;
953
954 /* Handle start tracing packet */
955 if (etmq->prev_packet->sample_type == CS_ETM_EMPTY)
956 goto swap_packet;
957
927 if (etmq->etm->synth_opts.last_branch && 958 if (etmq->etm->synth_opts.last_branch &&
928 etmq->prev_packet &&
929 etmq->prev_packet->sample_type == CS_ETM_RANGE) { 959 etmq->prev_packet->sample_type == CS_ETM_RANGE) {
930 /* 960 /*
931 * Generate a last branch event for the branches left in the 961 * Generate a last branch event for the branches left in the
@@ -939,8 +969,22 @@ static int cs_etm__flush(struct cs_etm_queue *etmq)
939 err = cs_etm__synth_instruction_sample( 969 err = cs_etm__synth_instruction_sample(
940 etmq, addr, 970 etmq, addr,
941 etmq->period_instructions); 971 etmq->period_instructions);
972 if (err)
973 return err;
974
942 etmq->period_instructions = 0; 975 etmq->period_instructions = 0;
943 976
977 }
978
979 if (etm->sample_branches &&
980 etmq->prev_packet->sample_type == CS_ETM_RANGE) {
981 err = cs_etm__synth_branch_sample(etmq);
982 if (err)
983 return err;
984 }
985
986swap_packet:
987 if (etmq->etm->synth_opts.last_branch) {
944 /* 988 /*
945 * Swap PACKET with PREV_PACKET: PACKET becomes PREV_PACKET for 989 * Swap PACKET with PREV_PACKET: PACKET becomes PREV_PACKET for
946 * the next incoming packet. 990 * the next incoming packet.
@@ -1020,6 +1064,13 @@ static int cs_etm__run_decoder(struct cs_etm_queue *etmq)
1020 */ 1064 */
1021 cs_etm__flush(etmq); 1065 cs_etm__flush(etmq);
1022 break; 1066 break;
1067 case CS_ETM_EMPTY:
1068 /*
1069 * Should not receive empty packet,
1070 * report error.
1071 */
1072 pr_err("CS ETM Trace: empty packet\n");
1073 return -EINVAL;
1023 default: 1074 default:
1024 break; 1075 break;
1025 } 1076 }
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 94fce4f537e9..ddf84b941abf 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -260,6 +260,17 @@ struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx)
260 evsel->attr.sample_period = 1; 260 evsel->attr.sample_period = 1;
261 } 261 }
262 262
263 if (perf_evsel__is_clock(evsel)) {
264 /*
265 * The evsel->unit points to static alias->unit
266 * so it's ok to use static string in here.
267 */
268 static const char *unit = "msec";
269
270 evsel->unit = unit;
271 evsel->scale = 1e-6;
272 }
273
263 return evsel; 274 return evsel;
264} 275}
265 276
@@ -848,6 +859,12 @@ static void apply_config_terms(struct perf_evsel *evsel,
848 } 859 }
849} 860}
850 861
862static bool is_dummy_event(struct perf_evsel *evsel)
863{
864 return (evsel->attr.type == PERF_TYPE_SOFTWARE) &&
865 (evsel->attr.config == PERF_COUNT_SW_DUMMY);
866}
867
851/* 868/*
852 * The enable_on_exec/disabled value strategy: 869 * The enable_on_exec/disabled value strategy:
853 * 870 *
@@ -1086,6 +1103,14 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts,
1086 else 1103 else
1087 perf_evsel__reset_sample_bit(evsel, PERIOD); 1104 perf_evsel__reset_sample_bit(evsel, PERIOD);
1088 } 1105 }
1106
1107 /*
1108 * For initial_delay, a dummy event is added implicitly.
1109 * The software event will trigger -EOPNOTSUPP error out,
1110 * if BRANCH_STACK bit is set.
1111 */
1112 if (opts->initial_delay && is_dummy_event(evsel))
1113 perf_evsel__reset_sample_bit(evsel, BRANCH_STACK);
1089} 1114}
1090 1115
1091static int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) 1116static int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index d277930b19a1..973c03167947 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -402,10 +402,13 @@ bool perf_evsel__is_function_event(struct perf_evsel *evsel);
402 402
403static inline bool perf_evsel__is_bpf_output(struct perf_evsel *evsel) 403static inline bool perf_evsel__is_bpf_output(struct perf_evsel *evsel)
404{ 404{
405 struct perf_event_attr *attr = &evsel->attr; 405 return perf_evsel__match(evsel, SOFTWARE, SW_BPF_OUTPUT);
406}
406 407
407 return (attr->config == PERF_COUNT_SW_BPF_OUTPUT) && 408static inline bool perf_evsel__is_clock(struct perf_evsel *evsel)
408 (attr->type == PERF_TYPE_SOFTWARE); 409{
410 return perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) ||
411 perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK);
409} 412}
410 413
411struct perf_attr_details { 414struct perf_attr_details {
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 653ff65aa2c3..5af58aac91ad 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -2587,7 +2587,7 @@ static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = {
2587 FEAT_OPR(NUMA_TOPOLOGY, numa_topology, true), 2587 FEAT_OPR(NUMA_TOPOLOGY, numa_topology, true),
2588 FEAT_OPN(BRANCH_STACK, branch_stack, false), 2588 FEAT_OPN(BRANCH_STACK, branch_stack, false),
2589 FEAT_OPR(PMU_MAPPINGS, pmu_mappings, false), 2589 FEAT_OPR(PMU_MAPPINGS, pmu_mappings, false),
2590 FEAT_OPN(GROUP_DESC, group_desc, false), 2590 FEAT_OPR(GROUP_DESC, group_desc, false),
2591 FEAT_OPN(AUXTRACE, auxtrace, false), 2591 FEAT_OPN(AUXTRACE, auxtrace, false),
2592 FEAT_OPN(STAT, stat, false), 2592 FEAT_OPN(STAT, stat, false),
2593 FEAT_OPN(CACHE, cache, true), 2593 FEAT_OPN(CACHE, cache, true),
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 73049f7f0f60..3badd7f1e1b8 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -181,7 +181,7 @@ size_t events_stats__fprintf(struct events_stats *stats, FILE *fp);
181 181
182size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, 182size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
183 int max_cols, float min_pcnt, FILE *fp, 183 int max_cols, float min_pcnt, FILE *fp,
184 bool use_callchain); 184 bool ignore_callchains);
185size_t perf_evlist__fprintf_nr_events(struct perf_evlist *evlist, FILE *fp); 185size_t perf_evlist__fprintf_nr_events(struct perf_evlist *evlist, FILE *fp);
186 186
187void hists__filter_by_dso(struct hists *hists); 187void hists__filter_by_dso(struct hists *hists);
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index e7b4a8b513f2..b300a3973448 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -408,23 +408,16 @@ out_err:
408} 408}
409 409
410/* 410/*
411 * Caller must eventually drop thread->refcnt returned with a successful 411 * Front-end cache - TID lookups come in blocks,
412 * lookup/new thread inserted. 412 * so most of the time we dont have to look up
413 * the full rbtree:
413 */ 414 */
414static struct thread *____machine__findnew_thread(struct machine *machine, 415static struct thread*
415 struct threads *threads, 416__threads__get_last_match(struct threads *threads, struct machine *machine,
416 pid_t pid, pid_t tid, 417 int pid, int tid)
417 bool create)
418{ 418{
419 struct rb_node **p = &threads->entries.rb_node;
420 struct rb_node *parent = NULL;
421 struct thread *th; 419 struct thread *th;
422 420
423 /*
424 * Front-end cache - TID lookups come in blocks,
425 * so most of the time we dont have to look up
426 * the full rbtree:
427 */
428 th = threads->last_match; 421 th = threads->last_match;
429 if (th != NULL) { 422 if (th != NULL) {
430 if (th->tid == tid) { 423 if (th->tid == tid) {
@@ -435,12 +428,57 @@ static struct thread *____machine__findnew_thread(struct machine *machine,
435 threads->last_match = NULL; 428 threads->last_match = NULL;
436 } 429 }
437 430
431 return NULL;
432}
433
434static struct thread*
435threads__get_last_match(struct threads *threads, struct machine *machine,
436 int pid, int tid)
437{
438 struct thread *th = NULL;
439
440 if (perf_singlethreaded)
441 th = __threads__get_last_match(threads, machine, pid, tid);
442
443 return th;
444}
445
446static void
447__threads__set_last_match(struct threads *threads, struct thread *th)
448{
449 threads->last_match = th;
450}
451
452static void
453threads__set_last_match(struct threads *threads, struct thread *th)
454{
455 if (perf_singlethreaded)
456 __threads__set_last_match(threads, th);
457}
458
459/*
460 * Caller must eventually drop thread->refcnt returned with a successful
461 * lookup/new thread inserted.
462 */
463static struct thread *____machine__findnew_thread(struct machine *machine,
464 struct threads *threads,
465 pid_t pid, pid_t tid,
466 bool create)
467{
468 struct rb_node **p = &threads->entries.rb_node;
469 struct rb_node *parent = NULL;
470 struct thread *th;
471
472 th = threads__get_last_match(threads, machine, pid, tid);
473 if (th)
474 return th;
475
438 while (*p != NULL) { 476 while (*p != NULL) {
439 parent = *p; 477 parent = *p;
440 th = rb_entry(parent, struct thread, rb_node); 478 th = rb_entry(parent, struct thread, rb_node);
441 479
442 if (th->tid == tid) { 480 if (th->tid == tid) {
443 threads->last_match = th; 481 threads__set_last_match(threads, th);
444 machine__update_thread_pid(machine, th, pid); 482 machine__update_thread_pid(machine, th, pid);
445 return thread__get(th); 483 return thread__get(th);
446 } 484 }
@@ -477,7 +515,7 @@ static struct thread *____machine__findnew_thread(struct machine *machine,
477 * It is now in the rbtree, get a ref 515 * It is now in the rbtree, get a ref
478 */ 516 */
479 thread__get(th); 517 thread__get(th);
480 threads->last_match = th; 518 threads__set_last_match(threads, th);
481 ++threads->nr; 519 ++threads->nr;
482 } 520 }
483 521
@@ -1635,7 +1673,7 @@ static void __machine__remove_thread(struct machine *machine, struct thread *th,
1635 struct threads *threads = machine__threads(machine, th->tid); 1673 struct threads *threads = machine__threads(machine, th->tid);
1636 1674
1637 if (threads->last_match == th) 1675 if (threads->last_match == th)
1638 threads->last_match = NULL; 1676 threads__set_last_match(threads, NULL);
1639 1677
1640 BUG_ON(refcount_read(&th->refcnt) == 0); 1678 BUG_ON(refcount_read(&th->refcnt) == 0);
1641 if (lock) 1679 if (lock)
@@ -2272,6 +2310,7 @@ static int unwind_entry(struct unwind_entry *entry, void *arg)
2272{ 2310{
2273 struct callchain_cursor *cursor = arg; 2311 struct callchain_cursor *cursor = arg;
2274 const char *srcline = NULL; 2312 const char *srcline = NULL;
2313 u64 addr;
2275 2314
2276 if (symbol_conf.hide_unresolved && entry->sym == NULL) 2315 if (symbol_conf.hide_unresolved && entry->sym == NULL)
2277 return 0; 2316 return 0;
@@ -2279,7 +2318,13 @@ static int unwind_entry(struct unwind_entry *entry, void *arg)
2279 if (append_inlines(cursor, entry->map, entry->sym, entry->ip) == 0) 2318 if (append_inlines(cursor, entry->map, entry->sym, entry->ip) == 0)
2280 return 0; 2319 return 0;
2281 2320
2282 srcline = callchain_srcline(entry->map, entry->sym, entry->ip); 2321 /*
2322 * Convert entry->ip from a virtual address to an offset in
2323 * its corresponding binary.
2324 */
2325 addr = map__map_ip(entry->map, entry->ip);
2326
2327 srcline = callchain_srcline(entry->map, entry->sym, addr);
2283 return callchain_cursor_append(cursor, entry->ip, 2328 return callchain_cursor_append(cursor, entry->ip,
2284 entry->map, entry->sym, 2329 entry->map, entry->sym,
2285 false, NULL, 0, 0, 0, srcline); 2330 false, NULL, 0, 0, 0, srcline);
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
index 1ddc3d1d0147..a28f9b5cc4ff 100644
--- a/tools/perf/util/metricgroup.c
+++ b/tools/perf/util/metricgroup.c
@@ -326,8 +326,8 @@ void metricgroup__print(bool metrics, bool metricgroups, char *filter,
326 if (raw) 326 if (raw)
327 s = (char *)pe->metric_name; 327 s = (char *)pe->metric_name;
328 else { 328 else {
329 if (asprintf(&s, "%s\n\t[%s]", 329 if (asprintf(&s, "%s\n%*s%s]",
330 pe->metric_name, pe->desc) < 0) 330 pe->metric_name, 8, "[", pe->desc) < 0)
331 return; 331 return;
332 } 332 }
333 333
@@ -490,3 +490,25 @@ out:
490 metricgroup__free_egroups(&group_list); 490 metricgroup__free_egroups(&group_list);
491 return ret; 491 return ret;
492} 492}
493
494bool metricgroup__has_metric(const char *metric)
495{
496 struct pmu_events_map *map = perf_pmu__find_map(NULL);
497 struct pmu_event *pe;
498 int i;
499
500 if (!map)
501 return false;
502
503 for (i = 0; ; i++) {
504 pe = &map->table[i];
505
506 if (!pe->name && !pe->metric_group && !pe->metric_name)
507 break;
508 if (!pe->metric_expr)
509 continue;
510 if (match_metric(pe->metric_name, metric))
511 return true;
512 }
513 return false;
514}
diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h
index 06854e125ee7..8a155dba0581 100644
--- a/tools/perf/util/metricgroup.h
+++ b/tools/perf/util/metricgroup.h
@@ -28,4 +28,5 @@ int metricgroup__parse_groups(const struct option *opt,
28 struct rblist *metric_events); 28 struct rblist *metric_events);
29 29
30void metricgroup__print(bool metrics, bool groups, char *filter, bool raw); 30void metricgroup__print(bool metrics, bool groups, char *filter, bool raw);
31bool metricgroup__has_metric(const char *metric);
31#endif 32#endif
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 3ba6a1742f91..afd68524ffa9 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -652,12 +652,6 @@ static int is_arm_pmu_core(const char *name)
652 if (stat(path, &st) == 0) 652 if (stat(path, &st) == 0)
653 return 1; 653 return 1;
654 654
655 /* Look for cpu sysfs (specific to s390) */
656 scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s",
657 sysfs, name);
658 if (stat(path, &st) == 0 && !strncmp(name, "cpum_", 5))
659 return 1;
660
661 return 0; 655 return 0;
662} 656}
663 657
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index 594d14a02b67..99990f5f2512 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -913,11 +913,10 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
913 ratio = total / avg; 913 ratio = total / avg;
914 914
915 print_metric(ctxp, NULL, "%8.0f", "cycles / elision", ratio); 915 print_metric(ctxp, NULL, "%8.0f", "cycles / elision", ratio);
916 } else if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK) || 916 } else if (perf_evsel__is_clock(evsel)) {
917 perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK)) {
918 if ((ratio = avg_stats(&walltime_nsecs_stats)) != 0) 917 if ((ratio = avg_stats(&walltime_nsecs_stats)) != 0)
919 print_metric(ctxp, NULL, "%8.3f", "CPUs utilized", 918 print_metric(ctxp, NULL, "%8.3f", "CPUs utilized",
920 avg / ratio); 919 avg / (ratio * evsel->scale));
921 else 920 else
922 print_metric(ctxp, NULL, NULL, "CPUs utilized", 0); 921 print_metric(ctxp, NULL, NULL, "CPUs utilized", 0);
923 } else if (perf_stat_evsel__is(evsel, TOPDOWN_FETCH_BUBBLES)) { 922 } else if (perf_stat_evsel__is(evsel, TOPDOWN_FETCH_BUBBLES)) {
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 0ee7f568d60c..3393d7ee9401 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -38,6 +38,10 @@ static const char **syscalltbl_native = syscalltbl_powerpc_64;
38#include <asm/syscalls_32.c> 38#include <asm/syscalls_32.c>
39const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_32_MAX_ID; 39const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_32_MAX_ID;
40static const char **syscalltbl_native = syscalltbl_powerpc_32; 40static const char **syscalltbl_native = syscalltbl_powerpc_32;
41#elif defined(__aarch64__)
42#include <asm/syscalls.c>
43const int syscalltbl_native_max_id = SYSCALLTBL_ARM64_MAX_ID;
44static const char **syscalltbl_native = syscalltbl_arm64;
41#endif 45#endif
42 46
43struct syscall { 47struct syscall {
diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c
index 538db4e5d1e6..6f318b15950e 100644
--- a/tools/perf/util/unwind-libdw.c
+++ b/tools/perf/util/unwind-libdw.c
@@ -77,7 +77,7 @@ static int entry(u64 ip, struct unwind_info *ui)
77 if (__report_module(&al, ip, ui)) 77 if (__report_module(&al, ip, ui))
78 return -1; 78 return -1;
79 79
80 e->ip = al.addr; 80 e->ip = ip;
81 e->map = al.map; 81 e->map = al.map;
82 e->sym = al.sym; 82 e->sym = al.sym;
83 83
diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c
index 6a11bc7e6b27..79f521a552cf 100644
--- a/tools/perf/util/unwind-libunwind-local.c
+++ b/tools/perf/util/unwind-libunwind-local.c
@@ -575,7 +575,7 @@ static int entry(u64 ip, struct thread *thread,
575 struct addr_location al; 575 struct addr_location al;
576 576
577 e.sym = thread__find_symbol(thread, PERF_RECORD_MISC_USER, ip, &al); 577 e.sym = thread__find_symbol(thread, PERF_RECORD_MISC_USER, ip, &al);
578 e.ip = al.addr; 578 e.ip = ip;
579 e.map = al.map; 579 e.map = al.map;
580 580
581 pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n", 581 pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n",
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index a362e3d7abc6..fff7fb1285fc 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -22,7 +22,8 @@ $(TEST_CUSTOM_PROGS): $(OUTPUT)/%: %.c
22# Order correspond to 'make run_tests' order 22# Order correspond to 'make run_tests' order
23TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \ 23TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \
24 test_align test_verifier_log test_dev_cgroup test_tcpbpf_user \ 24 test_align test_verifier_log test_dev_cgroup test_tcpbpf_user \
25 test_sock test_btf test_sockmap test_lirc_mode2_user get_cgroup_id_user 25 test_sock test_btf test_sockmap test_lirc_mode2_user get_cgroup_id_user \
26 test_socket_cookie test_cgroup_storage test_select_reuseport
26 27
27TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test_obj_id.o \ 28TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test_obj_id.o \
28 test_pkt_md_access.o test_xdp_redirect.o test_xdp_meta.o sockmap_parse_prog.o \ 29 test_pkt_md_access.o test_xdp_redirect.o test_xdp_meta.o sockmap_parse_prog.o \
@@ -33,7 +34,8 @@ TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test
33 test_btf_haskv.o test_btf_nokv.o test_sockmap_kern.o test_tunnel_kern.o \ 34 test_btf_haskv.o test_btf_nokv.o test_sockmap_kern.o test_tunnel_kern.o \
34 test_get_stack_rawtp.o test_sockmap_kern.o test_sockhash_kern.o \ 35 test_get_stack_rawtp.o test_sockmap_kern.o test_sockhash_kern.o \
35 test_lwt_seg6local.o sendmsg4_prog.o sendmsg6_prog.o test_lirc_mode2_kern.o \ 36 test_lwt_seg6local.o sendmsg4_prog.o sendmsg6_prog.o test_lirc_mode2_kern.o \
36 get_cgroup_id_kern.o 37 get_cgroup_id_kern.o socket_cookie_prog.o test_select_reuseport_kern.o \
38 test_skb_cgroup_id_kern.o
37 39
38# Order correspond to 'make run_tests' order 40# Order correspond to 'make run_tests' order
39TEST_PROGS := test_kmod.sh \ 41TEST_PROGS := test_kmod.sh \
@@ -44,10 +46,11 @@ TEST_PROGS := test_kmod.sh \
44 test_sock_addr.sh \ 46 test_sock_addr.sh \
45 test_tunnel.sh \ 47 test_tunnel.sh \
46 test_lwt_seg6local.sh \ 48 test_lwt_seg6local.sh \
47 test_lirc_mode2.sh 49 test_lirc_mode2.sh \
50 test_skb_cgroup_id.sh
48 51
49# Compile but not part of 'make run_tests' 52# Compile but not part of 'make run_tests'
50TEST_GEN_PROGS_EXTENDED = test_libbpf_open test_sock_addr 53TEST_GEN_PROGS_EXTENDED = test_libbpf_open test_sock_addr test_skb_cgroup_id_user
51 54
52include ../lib.mk 55include ../lib.mk
53 56
@@ -58,11 +61,15 @@ $(TEST_GEN_PROGS): $(BPFOBJ)
58$(TEST_GEN_PROGS_EXTENDED): $(OUTPUT)/libbpf.a 61$(TEST_GEN_PROGS_EXTENDED): $(OUTPUT)/libbpf.a
59 62
60$(OUTPUT)/test_dev_cgroup: cgroup_helpers.c 63$(OUTPUT)/test_dev_cgroup: cgroup_helpers.c
64$(OUTPUT)/test_skb_cgroup_id_user: cgroup_helpers.c
61$(OUTPUT)/test_sock: cgroup_helpers.c 65$(OUTPUT)/test_sock: cgroup_helpers.c
62$(OUTPUT)/test_sock_addr: cgroup_helpers.c 66$(OUTPUT)/test_sock_addr: cgroup_helpers.c
67$(OUTPUT)/test_socket_cookie: cgroup_helpers.c
63$(OUTPUT)/test_sockmap: cgroup_helpers.c 68$(OUTPUT)/test_sockmap: cgroup_helpers.c
69$(OUTPUT)/test_tcpbpf_user: cgroup_helpers.c
64$(OUTPUT)/test_progs: trace_helpers.c 70$(OUTPUT)/test_progs: trace_helpers.c
65$(OUTPUT)/get_cgroup_id_user: cgroup_helpers.c 71$(OUTPUT)/get_cgroup_id_user: cgroup_helpers.c
72$(OUTPUT)/test_cgroup_storage: cgroup_helpers.c
66 73
67.PHONY: force 74.PHONY: force
68 75
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
index 810de20e8e26..e4be7730222d 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -65,6 +65,8 @@ static int (*bpf_xdp_adjust_head)(void *ctx, int offset) =
65 (void *) BPF_FUNC_xdp_adjust_head; 65 (void *) BPF_FUNC_xdp_adjust_head;
66static int (*bpf_xdp_adjust_meta)(void *ctx, int offset) = 66static int (*bpf_xdp_adjust_meta)(void *ctx, int offset) =
67 (void *) BPF_FUNC_xdp_adjust_meta; 67 (void *) BPF_FUNC_xdp_adjust_meta;
68static int (*bpf_get_socket_cookie)(void *ctx) =
69 (void *) BPF_FUNC_get_socket_cookie;
68static int (*bpf_setsockopt)(void *ctx, int level, int optname, void *optval, 70static int (*bpf_setsockopt)(void *ctx, int level, int optname, void *optval,
69 int optlen) = 71 int optlen) =
70 (void *) BPF_FUNC_setsockopt; 72 (void *) BPF_FUNC_setsockopt;
@@ -109,6 +111,8 @@ static int (*bpf_xdp_adjust_tail)(void *ctx, int offset) =
109static int (*bpf_skb_get_xfrm_state)(void *ctx, int index, void *state, 111static int (*bpf_skb_get_xfrm_state)(void *ctx, int index, void *state,
110 int size, int flags) = 112 int size, int flags) =
111 (void *) BPF_FUNC_skb_get_xfrm_state; 113 (void *) BPF_FUNC_skb_get_xfrm_state;
114static int (*bpf_sk_select_reuseport)(void *ctx, void *map, void *key, __u32 flags) =
115 (void *) BPF_FUNC_sk_select_reuseport;
112static int (*bpf_get_stack)(void *ctx, void *buf, int size, int flags) = 116static int (*bpf_get_stack)(void *ctx, void *buf, int size, int flags) =
113 (void *) BPF_FUNC_get_stack; 117 (void *) BPF_FUNC_get_stack;
114static int (*bpf_fib_lookup)(void *ctx, struct bpf_fib_lookup *params, 118static int (*bpf_fib_lookup)(void *ctx, struct bpf_fib_lookup *params,
@@ -133,6 +137,12 @@ static int (*bpf_rc_keydown)(void *ctx, unsigned int protocol,
133 (void *) BPF_FUNC_rc_keydown; 137 (void *) BPF_FUNC_rc_keydown;
134static unsigned long long (*bpf_get_current_cgroup_id)(void) = 138static unsigned long long (*bpf_get_current_cgroup_id)(void) =
135 (void *) BPF_FUNC_get_current_cgroup_id; 139 (void *) BPF_FUNC_get_current_cgroup_id;
140static void *(*bpf_get_local_storage)(void *map, unsigned long long flags) =
141 (void *) BPF_FUNC_get_local_storage;
142static unsigned long long (*bpf_skb_cgroup_id)(void *ctx) =
143 (void *) BPF_FUNC_skb_cgroup_id;
144static unsigned long long (*bpf_skb_ancestor_cgroup_id)(void *ctx, int level) =
145 (void *) BPF_FUNC_skb_ancestor_cgroup_id;
136 146
137/* llvm builtin functions that eBPF C program may use to 147/* llvm builtin functions that eBPF C program may use to
138 * emit BPF_LD_ABS and BPF_LD_IND instructions 148 * emit BPF_LD_ABS and BPF_LD_IND instructions
@@ -169,6 +179,8 @@ struct bpf_map_def {
169 179
170static int (*bpf_skb_load_bytes)(void *ctx, int off, void *to, int len) = 180static int (*bpf_skb_load_bytes)(void *ctx, int off, void *to, int len) =
171 (void *) BPF_FUNC_skb_load_bytes; 181 (void *) BPF_FUNC_skb_load_bytes;
182static int (*bpf_skb_load_bytes_relative)(void *ctx, int off, void *to, int len, __u32 start_header) =
183 (void *) BPF_FUNC_skb_load_bytes_relative;
172static int (*bpf_skb_store_bytes)(void *ctx, int off, void *from, int len, int flags) = 184static int (*bpf_skb_store_bytes)(void *ctx, int off, void *from, int len, int flags) =
173 (void *) BPF_FUNC_skb_store_bytes; 185 (void *) BPF_FUNC_skb_store_bytes;
174static int (*bpf_l3_csum_replace)(void *ctx, int off, int from, int to, int flags) = 186static int (*bpf_l3_csum_replace)(void *ctx, int off, int from, int to, int flags) =
diff --git a/tools/testing/selftests/bpf/bpf_util.h b/tools/testing/selftests/bpf/bpf_util.h
index d0811b3d6a6f..315a44fa32af 100644
--- a/tools/testing/selftests/bpf/bpf_util.h
+++ b/tools/testing/selftests/bpf/bpf_util.h
@@ -44,4 +44,8 @@ static inline unsigned int bpf_num_possible_cpus(void)
44 name[bpf_num_possible_cpus()] 44 name[bpf_num_possible_cpus()]
45#define bpf_percpu(name, cpu) name[(cpu)].v 45#define bpf_percpu(name, cpu) name[(cpu)].v
46 46
47#ifndef ARRAY_SIZE
48# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
49#endif
50
47#endif /* __BPF_UTIL__ */ 51#endif /* __BPF_UTIL__ */
diff --git a/tools/testing/selftests/bpf/cgroup_helpers.c b/tools/testing/selftests/bpf/cgroup_helpers.c
index c87b4e052ce9..cf16948aad4a 100644
--- a/tools/testing/selftests/bpf/cgroup_helpers.c
+++ b/tools/testing/selftests/bpf/cgroup_helpers.c
@@ -118,7 +118,7 @@ static int join_cgroup_from_top(char *cgroup_path)
118 * 118 *
119 * On success, it returns 0, otherwise on failure it returns 1. 119 * On success, it returns 0, otherwise on failure it returns 1.
120 */ 120 */
121int join_cgroup(char *path) 121int join_cgroup(const char *path)
122{ 122{
123 char cgroup_path[PATH_MAX + 1]; 123 char cgroup_path[PATH_MAX + 1];
124 124
@@ -158,7 +158,7 @@ void cleanup_cgroup_environment(void)
158 * On success, it returns the file descriptor. On failure it returns 0. 158 * On success, it returns the file descriptor. On failure it returns 0.
159 * If there is a failure, it prints the error to stderr. 159 * If there is a failure, it prints the error to stderr.
160 */ 160 */
161int create_and_get_cgroup(char *path) 161int create_and_get_cgroup(const char *path)
162{ 162{
163 char cgroup_path[PATH_MAX + 1]; 163 char cgroup_path[PATH_MAX + 1];
164 int fd; 164 int fd;
@@ -186,7 +186,7 @@ int create_and_get_cgroup(char *path)
186 * which is an invalid cgroup id. 186 * which is an invalid cgroup id.
187 * If there is a failure, it prints the error to stderr. 187 * If there is a failure, it prints the error to stderr.
188 */ 188 */
189unsigned long long get_cgroup_id(char *path) 189unsigned long long get_cgroup_id(const char *path)
190{ 190{
191 int dirfd, err, flags, mount_id, fhsize; 191 int dirfd, err, flags, mount_id, fhsize;
192 union { 192 union {
diff --git a/tools/testing/selftests/bpf/cgroup_helpers.h b/tools/testing/selftests/bpf/cgroup_helpers.h
index 20a4a5dcd469..d64bb8957090 100644
--- a/tools/testing/selftests/bpf/cgroup_helpers.h
+++ b/tools/testing/selftests/bpf/cgroup_helpers.h
@@ -9,10 +9,10 @@
9 __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__) 9 __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)
10 10
11 11
12int create_and_get_cgroup(char *path); 12int create_and_get_cgroup(const char *path);
13int join_cgroup(char *path); 13int join_cgroup(const char *path);
14int setup_cgroup_environment(void); 14int setup_cgroup_environment(void);
15void cleanup_cgroup_environment(void); 15void cleanup_cgroup_environment(void);
16unsigned long long get_cgroup_id(char *path); 16unsigned long long get_cgroup_id(const char *path);
17 17
18#endif 18#endif
diff --git a/tools/testing/selftests/bpf/socket_cookie_prog.c b/tools/testing/selftests/bpf/socket_cookie_prog.c
new file mode 100644
index 000000000000..9ff8ac4b0bf6
--- /dev/null
+++ b/tools/testing/selftests/bpf/socket_cookie_prog.c
@@ -0,0 +1,60 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2018 Facebook
3
4#include <linux/bpf.h>
5#include <sys/socket.h>
6
7#include "bpf_helpers.h"
8#include "bpf_endian.h"
9
10struct bpf_map_def SEC("maps") socket_cookies = {
11 .type = BPF_MAP_TYPE_HASH,
12 .key_size = sizeof(__u64),
13 .value_size = sizeof(__u32),
14 .max_entries = 1 << 8,
15};
16
17SEC("cgroup/connect6")
18int set_cookie(struct bpf_sock_addr *ctx)
19{
20 __u32 cookie_value = 0xFF;
21 __u64 cookie_key;
22
23 if (ctx->family != AF_INET6 || ctx->user_family != AF_INET6)
24 return 1;
25
26 cookie_key = bpf_get_socket_cookie(ctx);
27 if (bpf_map_update_elem(&socket_cookies, &cookie_key, &cookie_value, 0))
28 return 0;
29
30 return 1;
31}
32
33SEC("sockops")
34int update_cookie(struct bpf_sock_ops *ctx)
35{
36 __u32 new_cookie_value;
37 __u32 *cookie_value;
38 __u64 cookie_key;
39
40 if (ctx->family != AF_INET6)
41 return 1;
42
43 if (ctx->op != BPF_SOCK_OPS_TCP_CONNECT_CB)
44 return 1;
45
46 cookie_key = bpf_get_socket_cookie(ctx);
47
48 cookie_value = bpf_map_lookup_elem(&socket_cookies, &cookie_key);
49 if (!cookie_value)
50 return 1;
51
52 new_cookie_value = (ctx->local_port << 8) | *cookie_value;
53 bpf_map_update_elem(&socket_cookies, &cookie_key, &new_cookie_value, 0);
54
55 return 1;
56}
57
58int _version SEC("version") = 1;
59
60char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/tcp_client.py b/tools/testing/selftests/bpf/tcp_client.py
index 481dccdf140c..7f8200a8702b 100755
--- a/tools/testing/selftests/bpf/tcp_client.py
+++ b/tools/testing/selftests/bpf/tcp_client.py
@@ -1,4 +1,4 @@
1#!/usr/bin/env python2 1#!/usr/bin/env python3
2# 2#
3# SPDX-License-Identifier: GPL-2.0 3# SPDX-License-Identifier: GPL-2.0
4# 4#
@@ -9,11 +9,11 @@ import subprocess
9import select 9import select
10 10
11def read(sock, n): 11def read(sock, n):
12 buf = '' 12 buf = b''
13 while len(buf) < n: 13 while len(buf) < n:
14 rem = n - len(buf) 14 rem = n - len(buf)
15 try: s = sock.recv(rem) 15 try: s = sock.recv(rem)
16 except (socket.error), e: return '' 16 except (socket.error) as e: return b''
17 buf += s 17 buf += s
18 return buf 18 return buf
19 19
@@ -22,7 +22,7 @@ def send(sock, s):
22 count = 0 22 count = 0
23 while count < total: 23 while count < total:
24 try: n = sock.send(s) 24 try: n = sock.send(s)
25 except (socket.error), e: n = 0 25 except (socket.error) as e: n = 0
26 if n == 0: 26 if n == 0:
27 return count; 27 return count;
28 count += n 28 count += n
@@ -39,10 +39,10 @@ try:
39except socket.error as e: 39except socket.error as e:
40 sys.exit(1) 40 sys.exit(1)
41 41
42buf = '' 42buf = b''
43n = 0 43n = 0
44while n < 1000: 44while n < 1000:
45 buf += '+' 45 buf += b'+'
46 n += 1 46 n += 1
47 47
48sock.settimeout(1); 48sock.settimeout(1);
diff --git a/tools/testing/selftests/bpf/tcp_server.py b/tools/testing/selftests/bpf/tcp_server.py
index bc454d7d0be2..b39903fca4c8 100755
--- a/tools/testing/selftests/bpf/tcp_server.py
+++ b/tools/testing/selftests/bpf/tcp_server.py
@@ -1,4 +1,4 @@
1#!/usr/bin/env python2 1#!/usr/bin/env python3
2# 2#
3# SPDX-License-Identifier: GPL-2.0 3# SPDX-License-Identifier: GPL-2.0
4# 4#
@@ -9,11 +9,11 @@ import subprocess
9import select 9import select
10 10
11def read(sock, n): 11def read(sock, n):
12 buf = '' 12 buf = b''
13 while len(buf) < n: 13 while len(buf) < n:
14 rem = n - len(buf) 14 rem = n - len(buf)
15 try: s = sock.recv(rem) 15 try: s = sock.recv(rem)
16 except (socket.error), e: return '' 16 except (socket.error) as e: return b''
17 buf += s 17 buf += s
18 return buf 18 return buf
19 19
@@ -22,7 +22,7 @@ def send(sock, s):
22 count = 0 22 count = 0
23 while count < total: 23 while count < total:
24 try: n = sock.send(s) 24 try: n = sock.send(s)
25 except (socket.error), e: n = 0 25 except (socket.error) as e: n = 0
26 if n == 0: 26 if n == 0:
27 return count; 27 return count;
28 count += n 28 count += n
@@ -43,7 +43,7 @@ host = socket.gethostname()
43 43
44try: serverSocket.bind((host, 0)) 44try: serverSocket.bind((host, 0))
45except socket.error as msg: 45except socket.error as msg:
46 print 'bind fails: ', msg 46 print('bind fails: ' + str(msg))
47 47
48sn = serverSocket.getsockname() 48sn = serverSocket.getsockname()
49serverPort = sn[1] 49serverPort = sn[1]
@@ -51,10 +51,10 @@ serverPort = sn[1]
51cmdStr = ("./tcp_client.py %d &") % (serverPort) 51cmdStr = ("./tcp_client.py %d &") % (serverPort)
52os.system(cmdStr) 52os.system(cmdStr)
53 53
54buf = '' 54buf = b''
55n = 0 55n = 0
56while n < 500: 56while n < 500:
57 buf += '.' 57 buf += b'.'
58 n += 1 58 n += 1
59 59
60serverSocket.listen(MAX_PORTS) 60serverSocket.listen(MAX_PORTS)
@@ -79,5 +79,5 @@ while True:
79 serverSocket.close() 79 serverSocket.close()
80 sys.exit(0) 80 sys.exit(0)
81 else: 81 else:
82 print 'Select timeout!' 82 print('Select timeout!')
83 sys.exit(1) 83 sys.exit(1)
diff --git a/tools/testing/selftests/bpf/test_align.c b/tools/testing/selftests/bpf/test_align.c
index 6b1b302310fe..5f377ec53f2f 100644
--- a/tools/testing/selftests/bpf/test_align.c
+++ b/tools/testing/selftests/bpf/test_align.c
@@ -18,10 +18,7 @@
18 18
19#include "../../../include/linux/filter.h" 19#include "../../../include/linux/filter.h"
20#include "bpf_rlimit.h" 20#include "bpf_rlimit.h"
21 21#include "bpf_util.h"
22#ifndef ARRAY_SIZE
23# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
24#endif
25 22
26#define MAX_INSNS 512 23#define MAX_INSNS 512
27#define MAX_MATCHES 16 24#define MAX_MATCHES 16
diff --git a/tools/testing/selftests/bpf/test_btf.c b/tools/testing/selftests/bpf/test_btf.c
index ffdd27737c9e..6b5cfeb7a9cc 100644
--- a/tools/testing/selftests/bpf/test_btf.c
+++ b/tools/testing/selftests/bpf/test_btf.c
@@ -19,6 +19,7 @@
19#include <bpf/btf.h> 19#include <bpf/btf.h>
20 20
21#include "bpf_rlimit.h" 21#include "bpf_rlimit.h"
22#include "bpf_util.h"
22 23
23static uint32_t pass_cnt; 24static uint32_t pass_cnt;
24static uint32_t error_cnt; 25static uint32_t error_cnt;
@@ -93,10 +94,6 @@ static int __base_pr(const char *format, ...)
93#define MAX_NR_RAW_TYPES 1024 94#define MAX_NR_RAW_TYPES 1024
94#define BTF_LOG_BUF_SIZE 65535 95#define BTF_LOG_BUF_SIZE 65535
95 96
96#ifndef ARRAY_SIZE
97# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
98#endif
99
100static struct args { 97static struct args {
101 unsigned int raw_test_num; 98 unsigned int raw_test_num;
102 unsigned int file_test_num; 99 unsigned int file_test_num;
@@ -131,6 +128,8 @@ struct btf_raw_test {
131 __u32 max_entries; 128 __u32 max_entries;
132 bool btf_load_err; 129 bool btf_load_err;
133 bool map_create_err; 130 bool map_create_err;
131 bool ordered_map;
132 bool lossless_map;
134 int hdr_len_delta; 133 int hdr_len_delta;
135 int type_off_delta; 134 int type_off_delta;
136 int str_off_delta; 135 int str_off_delta;
@@ -2093,8 +2092,7 @@ struct pprint_mapv {
2093 } aenum; 2092 } aenum;
2094}; 2093};
2095 2094
2096static struct btf_raw_test pprint_test = { 2095static struct btf_raw_test pprint_test_template = {
2097 .descr = "BTF pretty print test #1",
2098 .raw_types = { 2096 .raw_types = {
2099 /* unsighed char */ /* [1] */ 2097 /* unsighed char */ /* [1] */
2100 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1), 2098 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
@@ -2146,8 +2144,6 @@ static struct btf_raw_test pprint_test = {
2146 }, 2144 },
2147 .str_sec = "\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum", 2145 .str_sec = "\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum",
2148 .str_sec_size = sizeof("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum"), 2146 .str_sec_size = sizeof("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum"),
2149 .map_type = BPF_MAP_TYPE_ARRAY,
2150 .map_name = "pprint_test",
2151 .key_size = sizeof(unsigned int), 2147 .key_size = sizeof(unsigned int),
2152 .value_size = sizeof(struct pprint_mapv), 2148 .value_size = sizeof(struct pprint_mapv),
2153 .key_type_id = 3, /* unsigned int */ 2149 .key_type_id = 3, /* unsigned int */
@@ -2155,6 +2151,40 @@ static struct btf_raw_test pprint_test = {
2155 .max_entries = 128 * 1024, 2151 .max_entries = 128 * 1024,
2156}; 2152};
2157 2153
2154static struct btf_pprint_test_meta {
2155 const char *descr;
2156 enum bpf_map_type map_type;
2157 const char *map_name;
2158 bool ordered_map;
2159 bool lossless_map;
2160} pprint_tests_meta[] = {
2161{
2162 .descr = "BTF pretty print array",
2163 .map_type = BPF_MAP_TYPE_ARRAY,
2164 .map_name = "pprint_test_array",
2165 .ordered_map = true,
2166 .lossless_map = true,
2167},
2168
2169{
2170 .descr = "BTF pretty print hash",
2171 .map_type = BPF_MAP_TYPE_HASH,
2172 .map_name = "pprint_test_hash",
2173 .ordered_map = false,
2174 .lossless_map = true,
2175},
2176
2177{
2178 .descr = "BTF pretty print lru hash",
2179 .map_type = BPF_MAP_TYPE_LRU_HASH,
2180 .map_name = "pprint_test_lru_hash",
2181 .ordered_map = false,
2182 .lossless_map = false,
2183},
2184
2185};
2186
2187
2158static void set_pprint_mapv(struct pprint_mapv *v, uint32_t i) 2188static void set_pprint_mapv(struct pprint_mapv *v, uint32_t i)
2159{ 2189{
2160 v->ui32 = i; 2190 v->ui32 = i;
@@ -2166,10 +2196,12 @@ static void set_pprint_mapv(struct pprint_mapv *v, uint32_t i)
2166 v->aenum = i & 0x03; 2196 v->aenum = i & 0x03;
2167} 2197}
2168 2198
2169static int test_pprint(void) 2199static int do_test_pprint(void)
2170{ 2200{
2171 const struct btf_raw_test *test = &pprint_test; 2201 const struct btf_raw_test *test = &pprint_test_template;
2172 struct bpf_create_map_attr create_attr = {}; 2202 struct bpf_create_map_attr create_attr = {};
2203 unsigned int key, nr_read_elems;
2204 bool ordered_map, lossless_map;
2173 int map_fd = -1, btf_fd = -1; 2205 int map_fd = -1, btf_fd = -1;
2174 struct pprint_mapv mapv = {}; 2206 struct pprint_mapv mapv = {};
2175 unsigned int raw_btf_size; 2207 unsigned int raw_btf_size;
@@ -2178,7 +2210,6 @@ static int test_pprint(void)
2178 char pin_path[255]; 2210 char pin_path[255];
2179 size_t line_len = 0; 2211 size_t line_len = 0;
2180 char *line = NULL; 2212 char *line = NULL;
2181 unsigned int key;
2182 uint8_t *raw_btf; 2213 uint8_t *raw_btf;
2183 ssize_t nread; 2214 ssize_t nread;
2184 int err, ret; 2215 int err, ret;
@@ -2251,14 +2282,18 @@ static int test_pprint(void)
2251 goto done; 2282 goto done;
2252 } 2283 }
2253 2284
2254 key = 0; 2285 nr_read_elems = 0;
2286 ordered_map = test->ordered_map;
2287 lossless_map = test->lossless_map;
2255 do { 2288 do {
2256 ssize_t nexpected_line; 2289 ssize_t nexpected_line;
2290 unsigned int next_key;
2257 2291
2258 set_pprint_mapv(&mapv, key); 2292 next_key = ordered_map ? nr_read_elems : atoi(line);
2293 set_pprint_mapv(&mapv, next_key);
2259 nexpected_line = snprintf(expected_line, sizeof(expected_line), 2294 nexpected_line = snprintf(expected_line, sizeof(expected_line),
2260 "%u: {%u,0,%d,0x%x,0x%x,0x%x,{%lu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s}\n", 2295 "%u: {%u,0,%d,0x%x,0x%x,0x%x,{%lu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s}\n",
2261 key, 2296 next_key,
2262 mapv.ui32, mapv.si32, 2297 mapv.ui32, mapv.si32,
2263 mapv.unused_bits2a, mapv.bits28, mapv.unused_bits2b, 2298 mapv.unused_bits2a, mapv.bits28, mapv.unused_bits2b,
2264 mapv.ui64, 2299 mapv.ui64,
@@ -2281,11 +2316,12 @@ static int test_pprint(void)
2281 } 2316 }
2282 2317
2283 nread = getline(&line, &line_len, pin_file); 2318 nread = getline(&line, &line_len, pin_file);
2284 } while (++key < test->max_entries && nread > 0); 2319 } while (++nr_read_elems < test->max_entries && nread > 0);
2285 2320
2286 if (CHECK(key < test->max_entries, 2321 if (lossless_map &&
2287 "Unexpected EOF. key:%u test->max_entries:%u", 2322 CHECK(nr_read_elems < test->max_entries,
2288 key, test->max_entries)) { 2323 "Unexpected EOF. nr_read_elems:%u test->max_entries:%u",
2324 nr_read_elems, test->max_entries)) {
2289 err = -1; 2325 err = -1;
2290 goto done; 2326 goto done;
2291 } 2327 }
@@ -2314,6 +2350,24 @@ done:
2314 return err; 2350 return err;
2315} 2351}
2316 2352
2353static int test_pprint(void)
2354{
2355 unsigned int i;
2356 int err = 0;
2357
2358 for (i = 0; i < ARRAY_SIZE(pprint_tests_meta); i++) {
2359 pprint_test_template.descr = pprint_tests_meta[i].descr;
2360 pprint_test_template.map_type = pprint_tests_meta[i].map_type;
2361 pprint_test_template.map_name = pprint_tests_meta[i].map_name;
2362 pprint_test_template.ordered_map = pprint_tests_meta[i].ordered_map;
2363 pprint_test_template.lossless_map = pprint_tests_meta[i].lossless_map;
2364
2365 err |= count_result(do_test_pprint());
2366 }
2367
2368 return err;
2369}
2370
2317static void usage(const char *cmd) 2371static void usage(const char *cmd)
2318{ 2372{
2319 fprintf(stderr, "Usage: %s [-l] [[-r test_num (1 - %zu)] | [-g test_num (1 - %zu)] | [-f test_num (1 - %zu)] | [-p]]\n", 2373 fprintf(stderr, "Usage: %s [-l] [[-r test_num (1 - %zu)] | [-g test_num (1 - %zu)] | [-f test_num (1 - %zu)] | [-p]]\n",
@@ -2409,7 +2463,7 @@ int main(int argc, char **argv)
2409 err |= test_file(); 2463 err |= test_file();
2410 2464
2411 if (args.pprint_test) 2465 if (args.pprint_test)
2412 err |= count_result(test_pprint()); 2466 err |= test_pprint();
2413 2467
2414 if (args.raw_test || args.get_info_test || args.file_test || 2468 if (args.raw_test || args.get_info_test || args.file_test ||
2415 args.pprint_test) 2469 args.pprint_test)
diff --git a/tools/testing/selftests/bpf/test_cgroup_storage.c b/tools/testing/selftests/bpf/test_cgroup_storage.c
new file mode 100644
index 000000000000..dc83fb2d3f27
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_cgroup_storage.c
@@ -0,0 +1,130 @@
1// SPDX-License-Identifier: GPL-2.0
2#include <assert.h>
3#include <bpf/bpf.h>
4#include <linux/filter.h>
5#include <stdio.h>
6#include <stdlib.h>
7
8#include "cgroup_helpers.h"
9
10char bpf_log_buf[BPF_LOG_BUF_SIZE];
11
12#define TEST_CGROUP "/test-bpf-cgroup-storage-buf/"
13
14int main(int argc, char **argv)
15{
16 struct bpf_insn prog[] = {
17 BPF_LD_MAP_FD(BPF_REG_1, 0), /* map fd */
18 BPF_MOV64_IMM(BPF_REG_2, 0), /* flags, not used */
19 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
20 BPF_FUNC_get_local_storage),
21 BPF_MOV64_IMM(BPF_REG_1, 1),
22 BPF_STX_XADD(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
23 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
24 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0x1),
25 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
26 BPF_EXIT_INSN(),
27 };
28 size_t insns_cnt = sizeof(prog) / sizeof(struct bpf_insn);
29 int error = EXIT_FAILURE;
30 int map_fd, prog_fd, cgroup_fd;
31 struct bpf_cgroup_storage_key key;
32 unsigned long long value;
33
34 map_fd = bpf_create_map(BPF_MAP_TYPE_CGROUP_STORAGE, sizeof(key),
35 sizeof(value), 0, 0);
36 if (map_fd < 0) {
37 printf("Failed to create map: %s\n", strerror(errno));
38 goto out;
39 }
40
41 prog[0].imm = map_fd;
42 prog_fd = bpf_load_program(BPF_PROG_TYPE_CGROUP_SKB,
43 prog, insns_cnt, "GPL", 0,
44 bpf_log_buf, BPF_LOG_BUF_SIZE);
45 if (prog_fd < 0) {
46 printf("Failed to load bpf program: %s\n", bpf_log_buf);
47 goto out;
48 }
49
50 if (setup_cgroup_environment()) {
51 printf("Failed to setup cgroup environment\n");
52 goto err;
53 }
54
55 /* Create a cgroup, get fd, and join it */
56 cgroup_fd = create_and_get_cgroup(TEST_CGROUP);
57 if (!cgroup_fd) {
58 printf("Failed to create test cgroup\n");
59 goto err;
60 }
61
62 if (join_cgroup(TEST_CGROUP)) {
63 printf("Failed to join cgroup\n");
64 goto err;
65 }
66
67 /* Attach the bpf program */
68 if (bpf_prog_attach(prog_fd, cgroup_fd, BPF_CGROUP_INET_EGRESS, 0)) {
69 printf("Failed to attach bpf program\n");
70 goto err;
71 }
72
73 if (bpf_map_get_next_key(map_fd, NULL, &key)) {
74 printf("Failed to get the first key in cgroup storage\n");
75 goto err;
76 }
77
78 if (bpf_map_lookup_elem(map_fd, &key, &value)) {
79 printf("Failed to lookup cgroup storage\n");
80 goto err;
81 }
82
83 /* Every second packet should be dropped */
84 assert(system("ping localhost -c 1 -W 1 -q > /dev/null") == 0);
85 assert(system("ping localhost -c 1 -W 1 -q > /dev/null"));
86 assert(system("ping localhost -c 1 -W 1 -q > /dev/null") == 0);
87
88 /* Check the counter in the cgroup local storage */
89 if (bpf_map_lookup_elem(map_fd, &key, &value)) {
90 printf("Failed to lookup cgroup storage\n");
91 goto err;
92 }
93
94 if (value != 3) {
95 printf("Unexpected data in the cgroup storage: %llu\n", value);
96 goto err;
97 }
98
99 /* Bump the counter in the cgroup local storage */
100 value++;
101 if (bpf_map_update_elem(map_fd, &key, &value, 0)) {
102 printf("Failed to update the data in the cgroup storage\n");
103 goto err;
104 }
105
106 /* Every second packet should be dropped */
107 assert(system("ping localhost -c 1 -W 1 -q > /dev/null") == 0);
108 assert(system("ping localhost -c 1 -W 1 -q > /dev/null"));
109 assert(system("ping localhost -c 1 -W 1 -q > /dev/null") == 0);
110
111 /* Check the final value of the counter in the cgroup local storage */
112 if (bpf_map_lookup_elem(map_fd, &key, &value)) {
113 printf("Failed to lookup the cgroup storage\n");
114 goto err;
115 }
116
117 if (value != 7) {
118 printf("Unexpected data in the cgroup storage: %llu\n", value);
119 goto err;
120 }
121
122 error = 0;
123 printf("test_cgroup_storage:PASS\n");
124
125err:
126 cleanup_cgroup_environment();
127
128out:
129 return error;
130}
diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c
index 6c253343a6f9..6f54f84144a0 100644
--- a/tools/testing/selftests/bpf/test_maps.c
+++ b/tools/testing/selftests/bpf/test_maps.c
@@ -17,7 +17,8 @@
17#include <stdlib.h> 17#include <stdlib.h>
18 18
19#include <sys/wait.h> 19#include <sys/wait.h>
20 20#include <sys/socket.h>
21#include <netinet/in.h>
21#include <linux/bpf.h> 22#include <linux/bpf.h>
22 23
23#include <bpf/bpf.h> 24#include <bpf/bpf.h>
@@ -26,8 +27,21 @@
26#include "bpf_util.h" 27#include "bpf_util.h"
27#include "bpf_rlimit.h" 28#include "bpf_rlimit.h"
28 29
30#ifndef ENOTSUPP
31#define ENOTSUPP 524
32#endif
33
29static int map_flags; 34static int map_flags;
30 35
36#define CHECK(condition, tag, format...) ({ \
37 int __ret = !!(condition); \
38 if (__ret) { \
39 printf("%s(%d):FAIL:%s ", __func__, __LINE__, tag); \
40 printf(format); \
41 exit(-1); \
42 } \
43})
44
31static void test_hashmap(int task, void *data) 45static void test_hashmap(int task, void *data)
32{ 46{
33 long long key, next_key, first_key, value; 47 long long key, next_key, first_key, value;
@@ -1150,6 +1164,250 @@ static void test_map_wronly(void)
1150 assert(bpf_map_get_next_key(fd, &key, &value) == -1 && errno == EPERM); 1164 assert(bpf_map_get_next_key(fd, &key, &value) == -1 && errno == EPERM);
1151} 1165}
1152 1166
1167static void prepare_reuseport_grp(int type, int map_fd,
1168 __s64 *fds64, __u64 *sk_cookies,
1169 unsigned int n)
1170{
1171 socklen_t optlen, addrlen;
1172 struct sockaddr_in6 s6;
1173 const __u32 index0 = 0;
1174 const int optval = 1;
1175 unsigned int i;
1176 u64 sk_cookie;
1177 __s64 fd64;
1178 int err;
1179
1180 s6.sin6_family = AF_INET6;
1181 s6.sin6_addr = in6addr_any;
1182 s6.sin6_port = 0;
1183 addrlen = sizeof(s6);
1184 optlen = sizeof(sk_cookie);
1185
1186 for (i = 0; i < n; i++) {
1187 fd64 = socket(AF_INET6, type, 0);
1188 CHECK(fd64 == -1, "socket()",
1189 "sock_type:%d fd64:%lld errno:%d\n",
1190 type, fd64, errno);
1191
1192 err = setsockopt(fd64, SOL_SOCKET, SO_REUSEPORT,
1193 &optval, sizeof(optval));
1194 CHECK(err == -1, "setsockopt(SO_REUSEPORT)",
1195 "err:%d errno:%d\n", err, errno);
1196
1197 /* reuseport_array does not allow unbound sk */
1198 err = bpf_map_update_elem(map_fd, &index0, &fd64,
1199 BPF_ANY);
1200 CHECK(err != -1 || errno != EINVAL,
1201 "reuseport array update unbound sk",
1202 "sock_type:%d err:%d errno:%d\n",
1203 type, err, errno);
1204
1205 err = bind(fd64, (struct sockaddr *)&s6, sizeof(s6));
1206 CHECK(err == -1, "bind()",
1207 "sock_type:%d err:%d errno:%d\n", type, err, errno);
1208
1209 if (i == 0) {
1210 err = getsockname(fd64, (struct sockaddr *)&s6,
1211 &addrlen);
1212 CHECK(err == -1, "getsockname()",
1213 "sock_type:%d err:%d errno:%d\n",
1214 type, err, errno);
1215 }
1216
1217 err = getsockopt(fd64, SOL_SOCKET, SO_COOKIE, &sk_cookie,
1218 &optlen);
1219 CHECK(err == -1, "getsockopt(SO_COOKIE)",
1220 "sock_type:%d err:%d errno:%d\n", type, err, errno);
1221
1222 if (type == SOCK_STREAM) {
1223 /*
1224 * reuseport_array does not allow
1225 * non-listening tcp sk.
1226 */
1227 err = bpf_map_update_elem(map_fd, &index0, &fd64,
1228 BPF_ANY);
1229 CHECK(err != -1 || errno != EINVAL,
1230 "reuseport array update non-listening sk",
1231 "sock_type:%d err:%d errno:%d\n",
1232 type, err, errno);
1233 err = listen(fd64, 0);
1234 CHECK(err == -1, "listen()",
1235 "sock_type:%d, err:%d errno:%d\n",
1236 type, err, errno);
1237 }
1238
1239 fds64[i] = fd64;
1240 sk_cookies[i] = sk_cookie;
1241 }
1242}
1243
1244static void test_reuseport_array(void)
1245{
1246#define REUSEPORT_FD_IDX(err, last) ({ (err) ? last : !last; })
1247
1248 const __u32 array_size = 4, index0 = 0, index3 = 3;
1249 int types[2] = { SOCK_STREAM, SOCK_DGRAM }, type;
1250 __u64 grpa_cookies[2], sk_cookie, map_cookie;
1251 __s64 grpa_fds64[2] = { -1, -1 }, fd64 = -1;
1252 const __u32 bad_index = array_size;
1253 int map_fd, err, t, f;
1254 __u32 fds_idx = 0;
1255 int fd;
1256
1257 map_fd = bpf_create_map(BPF_MAP_TYPE_REUSEPORT_SOCKARRAY,
1258 sizeof(__u32), sizeof(__u64), array_size, 0);
1259 CHECK(map_fd == -1, "reuseport array create",
1260 "map_fd:%d, errno:%d\n", map_fd, errno);
1261
1262 /* Test lookup/update/delete with invalid index */
1263 err = bpf_map_delete_elem(map_fd, &bad_index);
1264 CHECK(err != -1 || errno != E2BIG, "reuseport array del >=max_entries",
1265 "err:%d errno:%d\n", err, errno);
1266
1267 err = bpf_map_update_elem(map_fd, &bad_index, &fd64, BPF_ANY);
1268 CHECK(err != -1 || errno != E2BIG,
1269 "reuseport array update >=max_entries",
1270 "err:%d errno:%d\n", err, errno);
1271
1272 err = bpf_map_lookup_elem(map_fd, &bad_index, &map_cookie);
1273 CHECK(err != -1 || errno != ENOENT,
1274 "reuseport array update >=max_entries",
1275 "err:%d errno:%d\n", err, errno);
1276
1277 /* Test lookup/delete non existence elem */
1278 err = bpf_map_lookup_elem(map_fd, &index3, &map_cookie);
1279 CHECK(err != -1 || errno != ENOENT,
1280 "reuseport array lookup not-exist elem",
1281 "err:%d errno:%d\n", err, errno);
1282 err = bpf_map_delete_elem(map_fd, &index3);
1283 CHECK(err != -1 || errno != ENOENT,
1284 "reuseport array del not-exist elem",
1285 "err:%d errno:%d\n", err, errno);
1286
1287 for (t = 0; t < ARRAY_SIZE(types); t++) {
1288 type = types[t];
1289
1290 prepare_reuseport_grp(type, map_fd, grpa_fds64,
1291 grpa_cookies, ARRAY_SIZE(grpa_fds64));
1292
1293 /* Test BPF_* update flags */
1294 /* BPF_EXIST failure case */
1295 err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx],
1296 BPF_EXIST);
1297 CHECK(err != -1 || errno != ENOENT,
1298 "reuseport array update empty elem BPF_EXIST",
1299 "sock_type:%d err:%d errno:%d\n",
1300 type, err, errno);
1301 fds_idx = REUSEPORT_FD_IDX(err, fds_idx);
1302
1303 /* BPF_NOEXIST success case */
1304 err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx],
1305 BPF_NOEXIST);
1306 CHECK(err == -1,
1307 "reuseport array update empty elem BPF_NOEXIST",
1308 "sock_type:%d err:%d errno:%d\n",
1309 type, err, errno);
1310 fds_idx = REUSEPORT_FD_IDX(err, fds_idx);
1311
1312 /* BPF_EXIST success case. */
1313 err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx],
1314 BPF_EXIST);
1315 CHECK(err == -1,
1316 "reuseport array update same elem BPF_EXIST",
1317 "sock_type:%d err:%d errno:%d\n", type, err, errno);
1318 fds_idx = REUSEPORT_FD_IDX(err, fds_idx);
1319
1320 /* BPF_NOEXIST failure case */
1321 err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx],
1322 BPF_NOEXIST);
1323 CHECK(err != -1 || errno != EEXIST,
1324 "reuseport array update non-empty elem BPF_NOEXIST",
1325 "sock_type:%d err:%d errno:%d\n",
1326 type, err, errno);
1327 fds_idx = REUSEPORT_FD_IDX(err, fds_idx);
1328
1329 /* BPF_ANY case (always succeed) */
1330 err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx],
1331 BPF_ANY);
1332 CHECK(err == -1,
1333 "reuseport array update same sk with BPF_ANY",
1334 "sock_type:%d err:%d errno:%d\n", type, err, errno);
1335
1336 fd64 = grpa_fds64[fds_idx];
1337 sk_cookie = grpa_cookies[fds_idx];
1338
1339 /* The same sk cannot be added to reuseport_array twice */
1340 err = bpf_map_update_elem(map_fd, &index3, &fd64, BPF_ANY);
1341 CHECK(err != -1 || errno != EBUSY,
1342 "reuseport array update same sk with same index",
1343 "sock_type:%d err:%d errno:%d\n",
1344 type, err, errno);
1345
1346 err = bpf_map_update_elem(map_fd, &index0, &fd64, BPF_ANY);
1347 CHECK(err != -1 || errno != EBUSY,
1348 "reuseport array update same sk with different index",
1349 "sock_type:%d err:%d errno:%d\n",
1350 type, err, errno);
1351
1352 /* Test delete elem */
1353 err = bpf_map_delete_elem(map_fd, &index3);
1354 CHECK(err == -1, "reuseport array delete sk",
1355 "sock_type:%d err:%d errno:%d\n",
1356 type, err, errno);
1357
1358 /* Add it back with BPF_NOEXIST */
1359 err = bpf_map_update_elem(map_fd, &index3, &fd64, BPF_NOEXIST);
1360 CHECK(err == -1,
1361 "reuseport array re-add with BPF_NOEXIST after del",
1362 "sock_type:%d err:%d errno:%d\n", type, err, errno);
1363
1364 /* Test cookie */
1365 err = bpf_map_lookup_elem(map_fd, &index3, &map_cookie);
1366 CHECK(err == -1 || sk_cookie != map_cookie,
1367 "reuseport array lookup re-added sk",
1368 "sock_type:%d err:%d errno:%d sk_cookie:0x%llx map_cookie:0x%llxn",
1369 type, err, errno, sk_cookie, map_cookie);
1370
1371 /* Test elem removed by close() */
1372 for (f = 0; f < ARRAY_SIZE(grpa_fds64); f++)
1373 close(grpa_fds64[f]);
1374 err = bpf_map_lookup_elem(map_fd, &index3, &map_cookie);
1375 CHECK(err != -1 || errno != ENOENT,
1376 "reuseport array lookup after close()",
1377 "sock_type:%d err:%d errno:%d\n",
1378 type, err, errno);
1379 }
1380
1381 /* Test SOCK_RAW */
1382 fd64 = socket(AF_INET6, SOCK_RAW, IPPROTO_UDP);
1383 CHECK(fd64 == -1, "socket(SOCK_RAW)", "err:%d errno:%d\n",
1384 err, errno);
1385 err = bpf_map_update_elem(map_fd, &index3, &fd64, BPF_NOEXIST);
1386 CHECK(err != -1 || errno != ENOTSUPP, "reuseport array update SOCK_RAW",
1387 "err:%d errno:%d\n", err, errno);
1388 close(fd64);
1389
1390 /* Close the 64 bit value map */
1391 close(map_fd);
1392
1393 /* Test 32 bit fd */
1394 map_fd = bpf_create_map(BPF_MAP_TYPE_REUSEPORT_SOCKARRAY,
1395 sizeof(__u32), sizeof(__u32), array_size, 0);
1396 CHECK(map_fd == -1, "reuseport array create",
1397 "map_fd:%d, errno:%d\n", map_fd, errno);
1398 prepare_reuseport_grp(SOCK_STREAM, map_fd, &fd64, &sk_cookie, 1);
1399 fd = fd64;
1400 err = bpf_map_update_elem(map_fd, &index3, &fd, BPF_NOEXIST);
1401 CHECK(err == -1, "reuseport array update 32 bit fd",
1402 "err:%d errno:%d\n", err, errno);
1403 err = bpf_map_lookup_elem(map_fd, &index3, &map_cookie);
1404 CHECK(err != -1 || errno != ENOSPC,
1405 "reuseport array lookup 32 bit fd",
1406 "err:%d errno:%d\n", err, errno);
1407 close(fd);
1408 close(map_fd);
1409}
1410
1153static void run_all_tests(void) 1411static void run_all_tests(void)
1154{ 1412{
1155 test_hashmap(0, NULL); 1413 test_hashmap(0, NULL);
@@ -1170,6 +1428,8 @@ static void run_all_tests(void)
1170 1428
1171 test_map_rdonly(); 1429 test_map_rdonly();
1172 test_map_wronly(); 1430 test_map_wronly();
1431
1432 test_reuseport_array();
1173} 1433}
1174 1434
1175int main(void) 1435int main(void)
diff --git a/tools/testing/selftests/bpf/test_offload.py b/tools/testing/selftests/bpf/test_offload.py
index be800d0e7a84..d59642e70f56 100755
--- a/tools/testing/selftests/bpf/test_offload.py
+++ b/tools/testing/selftests/bpf/test_offload.py
@@ -158,8 +158,9 @@ def tool(name, args, flags, JSON=True, ns="", fail=True, include_stderr=False):
158 else: 158 else:
159 return ret, out 159 return ret, out
160 160
161def bpftool(args, JSON=True, ns="", fail=True): 161def bpftool(args, JSON=True, ns="", fail=True, include_stderr=False):
162 return tool("bpftool", args, {"json":"-p"}, JSON=JSON, ns=ns, fail=fail) 162 return tool("bpftool", args, {"json":"-p"}, JSON=JSON, ns=ns,
163 fail=fail, include_stderr=include_stderr)
163 164
164def bpftool_prog_list(expected=None, ns=""): 165def bpftool_prog_list(expected=None, ns=""):
165 _, progs = bpftool("prog show", JSON=True, ns=ns, fail=True) 166 _, progs = bpftool("prog show", JSON=True, ns=ns, fail=True)
@@ -201,6 +202,21 @@ def bpftool_map_list_wait(expected=0, n_retry=20):
201 time.sleep(0.05) 202 time.sleep(0.05)
202 raise Exception("Time out waiting for map counts to stabilize want %d, have %d" % (expected, nmaps)) 203 raise Exception("Time out waiting for map counts to stabilize want %d, have %d" % (expected, nmaps))
203 204
205def bpftool_prog_load(sample, file_name, maps=[], prog_type="xdp", dev=None,
206 fail=True, include_stderr=False):
207 args = "prog load %s %s" % (os.path.join(bpf_test_dir, sample), file_name)
208 if prog_type is not None:
209 args += " type " + prog_type
210 if dev is not None:
211 args += " dev " + dev
212 if len(maps):
213 args += " map " + " map ".join(maps)
214
215 res = bpftool(args, fail=fail, include_stderr=include_stderr)
216 if res[0] == 0:
217 files.append(file_name)
218 return res
219
204def ip(args, force=False, JSON=True, ns="", fail=True, include_stderr=False): 220def ip(args, force=False, JSON=True, ns="", fail=True, include_stderr=False):
205 if force: 221 if force:
206 args = "-force " + args 222 args = "-force " + args
@@ -307,21 +323,25 @@ class NetdevSim:
307 Class for netdevsim netdevice and its attributes. 323 Class for netdevsim netdevice and its attributes.
308 """ 324 """
309 325
310 def __init__(self): 326 def __init__(self, link=None):
327 self.link = link
328
311 self.dev = self._netdevsim_create() 329 self.dev = self._netdevsim_create()
312 devs.append(self) 330 devs.append(self)
313 331
314 self.ns = "" 332 self.ns = ""
315 333
316 self.dfs_dir = '/sys/kernel/debug/netdevsim/%s' % (self.dev['ifname']) 334 self.dfs_dir = '/sys/kernel/debug/netdevsim/%s' % (self.dev['ifname'])
335 self.sdev_dir = self.dfs_dir + '/sdev/'
317 self.dfs_refresh() 336 self.dfs_refresh()
318 337
319 def __getitem__(self, key): 338 def __getitem__(self, key):
320 return self.dev[key] 339 return self.dev[key]
321 340
322 def _netdevsim_create(self): 341 def _netdevsim_create(self):
342 link = "" if self.link is None else "link " + self.link.dev['ifname']
323 _, old = ip("link show") 343 _, old = ip("link show")
324 ip("link add sim%d type netdevsim") 344 ip("link add sim%d {link} type netdevsim".format(link=link))
325 _, new = ip("link show") 345 _, new = ip("link show")
326 346
327 for dev in new: 347 for dev in new:
@@ -339,13 +359,18 @@ class NetdevSim:
339 self.dfs = DebugfsDir(self.dfs_dir) 359 self.dfs = DebugfsDir(self.dfs_dir)
340 return self.dfs 360 return self.dfs
341 361
362 def dfs_read(self, f):
363 path = os.path.join(self.dfs_dir, f)
364 _, data = cmd('cat %s' % (path))
365 return data.strip()
366
342 def dfs_num_bound_progs(self): 367 def dfs_num_bound_progs(self):
343 path = os.path.join(self.dfs_dir, "bpf_bound_progs") 368 path = os.path.join(self.sdev_dir, "bpf_bound_progs")
344 _, progs = cmd('ls %s' % (path)) 369 _, progs = cmd('ls %s' % (path))
345 return len(progs.split()) 370 return len(progs.split())
346 371
347 def dfs_get_bound_progs(self, expected): 372 def dfs_get_bound_progs(self, expected):
348 progs = DebugfsDir(os.path.join(self.dfs_dir, "bpf_bound_progs")) 373 progs = DebugfsDir(os.path.join(self.sdev_dir, "bpf_bound_progs"))
349 if expected is not None: 374 if expected is not None:
350 if len(progs) != expected: 375 if len(progs) != expected:
351 fail(True, "%d BPF programs bound, expected %d" % 376 fail(True, "%d BPF programs bound, expected %d" %
@@ -547,11 +572,11 @@ def check_extack(output, reference, args):
547 if skip_extack: 572 if skip_extack:
548 return 573 return
549 lines = output.split("\n") 574 lines = output.split("\n")
550 comp = len(lines) >= 2 and lines[1] == reference 575 comp = len(lines) >= 2 and lines[1] == 'Error: ' + reference
551 fail(not comp, "Missing or incorrect netlink extack message") 576 fail(not comp, "Missing or incorrect netlink extack message")
552 577
553def check_extack_nsim(output, reference, args): 578def check_extack_nsim(output, reference, args):
554 check_extack(output, "Error: netdevsim: " + reference, args) 579 check_extack(output, "netdevsim: " + reference, args)
555 580
556def check_no_extack(res, needle): 581def check_no_extack(res, needle):
557 fail((res[1] + res[2]).count(needle) or (res[1] + res[2]).count("Warning:"), 582 fail((res[1] + res[2]).count(needle) or (res[1] + res[2]).count("Warning:"),
@@ -654,7 +679,7 @@ try:
654 ret, _, err = sim.cls_bpf_add_filter(obj, skip_sw=True, 679 ret, _, err = sim.cls_bpf_add_filter(obj, skip_sw=True,
655 fail=False, include_stderr=True) 680 fail=False, include_stderr=True)
656 fail(ret == 0, "TC filter loaded without enabling TC offloads") 681 fail(ret == 0, "TC filter loaded without enabling TC offloads")
657 check_extack(err, "Error: TC offload is disabled on net device.", args) 682 check_extack(err, "TC offload is disabled on net device.", args)
658 sim.wait_for_flush() 683 sim.wait_for_flush()
659 684
660 sim.set_ethtool_tc_offloads(True) 685 sim.set_ethtool_tc_offloads(True)
@@ -694,7 +719,7 @@ try:
694 skip_sw=True, 719 skip_sw=True,
695 fail=False, include_stderr=True) 720 fail=False, include_stderr=True)
696 fail(ret == 0, "Offloaded a filter to chain other than 0") 721 fail(ret == 0, "Offloaded a filter to chain other than 0")
697 check_extack(err, "Error: Driver supports only offload of chain 0.", args) 722 check_extack(err, "Driver supports only offload of chain 0.", args)
698 sim.tc_flush_filters() 723 sim.tc_flush_filters()
699 724
700 start_test("Test TC replace...") 725 start_test("Test TC replace...")
@@ -814,24 +839,20 @@ try:
814 "Device parameters reported for non-offloaded program") 839 "Device parameters reported for non-offloaded program")
815 840
816 start_test("Test XDP prog replace with bad flags...") 841 start_test("Test XDP prog replace with bad flags...")
817 ret, _, err = sim.set_xdp(obj, "offload", force=True, 842 ret, _, err = sim.set_xdp(obj, "generic", force=True,
818 fail=False, include_stderr=True) 843 fail=False, include_stderr=True)
819 fail(ret == 0, "Replaced XDP program with a program in different mode") 844 fail(ret == 0, "Replaced XDP program with a program in different mode")
820 check_extack_nsim(err, "program loaded with different flags.", args) 845 fail(err.count("File exists") != 1, "Replaced driver XDP with generic")
821 ret, _, err = sim.set_xdp(obj, "", force=True, 846 ret, _, err = sim.set_xdp(obj, "", force=True,
822 fail=False, include_stderr=True) 847 fail=False, include_stderr=True)
823 fail(ret == 0, "Replaced XDP program with a program in different mode") 848 fail(ret == 0, "Replaced XDP program with a program in different mode")
824 check_extack_nsim(err, "program loaded with different flags.", args) 849 check_extack(err, "program loaded with different flags.", args)
825 850
826 start_test("Test XDP prog remove with bad flags...") 851 start_test("Test XDP prog remove with bad flags...")
827 ret, _, err = sim.unset_xdp("offload", force=True,
828 fail=False, include_stderr=True)
829 fail(ret == 0, "Removed program with a bad mode mode")
830 check_extack_nsim(err, "program loaded with different flags.", args)
831 ret, _, err = sim.unset_xdp("", force=True, 852 ret, _, err = sim.unset_xdp("", force=True,
832 fail=False, include_stderr=True) 853 fail=False, include_stderr=True)
833 fail(ret == 0, "Removed program with a bad mode mode") 854 fail(ret == 0, "Removed program with a bad mode")
834 check_extack_nsim(err, "program loaded with different flags.", args) 855 check_extack(err, "program loaded with different flags.", args)
835 856
836 start_test("Test MTU restrictions...") 857 start_test("Test MTU restrictions...")
837 ret, _ = sim.set_mtu(9000, fail=False) 858 ret, _ = sim.set_mtu(9000, fail=False)
@@ -846,6 +867,25 @@ try:
846 sim.set_mtu(1500) 867 sim.set_mtu(1500)
847 868
848 sim.wait_for_flush() 869 sim.wait_for_flush()
870 start_test("Test non-offload XDP attaching to HW...")
871 bpftool_prog_load("sample_ret0.o", "/sys/fs/bpf/nooffload")
872 nooffload = bpf_pinned("/sys/fs/bpf/nooffload")
873 ret, _, err = sim.set_xdp(nooffload, "offload",
874 fail=False, include_stderr=True)
875 fail(ret == 0, "attached non-offloaded XDP program to HW")
876 check_extack_nsim(err, "xdpoffload of non-bound program.", args)
877 rm("/sys/fs/bpf/nooffload")
878
879 start_test("Test offload XDP attaching to drv...")
880 bpftool_prog_load("sample_ret0.o", "/sys/fs/bpf/offload",
881 dev=sim['ifname'])
882 offload = bpf_pinned("/sys/fs/bpf/offload")
883 ret, _, err = sim.set_xdp(offload, "drv", fail=False, include_stderr=True)
884 fail(ret == 0, "attached offloaded XDP program to drv")
885 check_extack(err, "using device-bound program without HW_MODE flag is not supported.", args)
886 rm("/sys/fs/bpf/offload")
887 sim.wait_for_flush()
888
849 start_test("Test XDP offload...") 889 start_test("Test XDP offload...")
850 _, _, err = sim.set_xdp(obj, "offload", verbose=True, include_stderr=True) 890 _, _, err = sim.set_xdp(obj, "offload", verbose=True, include_stderr=True)
851 ipl = sim.ip_link_show(xdp=True) 891 ipl = sim.ip_link_show(xdp=True)
@@ -891,6 +931,60 @@ try:
891 rm(pin_file) 931 rm(pin_file)
892 bpftool_prog_list_wait(expected=0) 932 bpftool_prog_list_wait(expected=0)
893 933
934 start_test("Test multi-attachment XDP - attach...")
935 sim.set_xdp(obj, "offload")
936 xdp = sim.ip_link_show(xdp=True)["xdp"]
937 offloaded = sim.dfs_read("bpf_offloaded_id")
938 fail("prog" not in xdp, "Base program not reported in single program mode")
939 fail(len(ipl["xdp"]["attached"]) != 1,
940 "Wrong attached program count with one program")
941
942 sim.set_xdp(obj, "")
943 two_xdps = sim.ip_link_show(xdp=True)["xdp"]
944 offloaded2 = sim.dfs_read("bpf_offloaded_id")
945
946 fail(two_xdps["mode"] != 4, "Bad mode reported with multiple programs")
947 fail("prog" in two_xdps, "Base program reported in multi program mode")
948 fail(xdp["attached"][0] not in two_xdps["attached"],
949 "Offload program not reported after driver activated")
950 fail(len(two_xdps["attached"]) != 2,
951 "Wrong attached program count with two programs")
952 fail(two_xdps["attached"][0]["prog"]["id"] ==
953 two_xdps["attached"][1]["prog"]["id"],
954 "offloaded and drv programs have the same id")
955 fail(offloaded != offloaded2,
956 "offload ID changed after loading driver program")
957
958 start_test("Test multi-attachment XDP - replace...")
959 ret, _, err = sim.set_xdp(obj, "offload", fail=False, include_stderr=True)
960 fail(err.count("busy") != 1, "Replaced one of programs without -force")
961
962 start_test("Test multi-attachment XDP - detach...")
963 ret, _, err = sim.unset_xdp("drv", force=True,
964 fail=False, include_stderr=True)
965 fail(ret == 0, "Removed program with a bad mode")
966 check_extack(err, "program loaded with different flags.", args)
967
968 sim.unset_xdp("offload")
969 xdp = sim.ip_link_show(xdp=True)["xdp"]
970 offloaded = sim.dfs_read("bpf_offloaded_id")
971
972 fail(xdp["mode"] != 1, "Bad mode reported after multiple programs")
973 fail("prog" not in xdp,
974 "Base program not reported after multi program mode")
975 fail(xdp["attached"][0] not in two_xdps["attached"],
976 "Offload program not reported after driver activated")
977 fail(len(ipl["xdp"]["attached"]) != 1,
978 "Wrong attached program count with remaining programs")
979 fail(offloaded != "0", "offload ID reported with only driver program left")
980
981 start_test("Test multi-attachment XDP - device remove...")
982 sim.set_xdp(obj, "offload")
983 sim.remove()
984
985 sim = NetdevSim()
986 sim.set_ethtool_tc_offloads(True)
987
894 start_test("Test mixing of TC and XDP...") 988 start_test("Test mixing of TC and XDP...")
895 sim.tc_add_ingress() 989 sim.tc_add_ingress()
896 sim.set_xdp(obj, "offload") 990 sim.set_xdp(obj, "offload")
@@ -1085,6 +1179,106 @@ try:
1085 fail(ret == 0, 1179 fail(ret == 0,
1086 "netdevsim didn't refuse to create a map with offload disabled") 1180 "netdevsim didn't refuse to create a map with offload disabled")
1087 1181
1182 sim.remove()
1183
1184 start_test("Test multi-dev ASIC program reuse...")
1185 simA = NetdevSim()
1186 simB1 = NetdevSim()
1187 simB2 = NetdevSim(link=simB1)
1188 simB3 = NetdevSim(link=simB1)
1189 sims = (simA, simB1, simB2, simB3)
1190 simB = (simB1, simB2, simB3)
1191
1192 bpftool_prog_load("sample_map_ret0.o", "/sys/fs/bpf/nsimA",
1193 dev=simA['ifname'])
1194 progA = bpf_pinned("/sys/fs/bpf/nsimA")
1195 bpftool_prog_load("sample_map_ret0.o", "/sys/fs/bpf/nsimB",
1196 dev=simB1['ifname'])
1197 progB = bpf_pinned("/sys/fs/bpf/nsimB")
1198
1199 simA.set_xdp(progA, "offload", JSON=False)
1200 for d in simB:
1201 d.set_xdp(progB, "offload", JSON=False)
1202
1203 start_test("Test multi-dev ASIC cross-dev replace...")
1204 ret, _ = simA.set_xdp(progB, "offload", force=True, JSON=False, fail=False)
1205 fail(ret == 0, "cross-ASIC program allowed")
1206 for d in simB:
1207 ret, _ = d.set_xdp(progA, "offload", force=True, JSON=False, fail=False)
1208 fail(ret == 0, "cross-ASIC program allowed")
1209
1210 start_test("Test multi-dev ASIC cross-dev install...")
1211 for d in sims:
1212 d.unset_xdp("offload")
1213
1214 ret, _, err = simA.set_xdp(progB, "offload", force=True, JSON=False,
1215 fail=False, include_stderr=True)
1216 fail(ret == 0, "cross-ASIC program allowed")
1217 check_extack_nsim(err, "program bound to different dev.", args)
1218 for d in simB:
1219 ret, _, err = d.set_xdp(progA, "offload", force=True, JSON=False,
1220 fail=False, include_stderr=True)
1221 fail(ret == 0, "cross-ASIC program allowed")
1222 check_extack_nsim(err, "program bound to different dev.", args)
1223
1224 start_test("Test multi-dev ASIC cross-dev map reuse...")
1225
1226 mapA = bpftool("prog show %s" % (progA))[1]["map_ids"][0]
1227 mapB = bpftool("prog show %s" % (progB))[1]["map_ids"][0]
1228
1229 ret, _ = bpftool_prog_load("sample_map_ret0.o", "/sys/fs/bpf/nsimB_",
1230 dev=simB3['ifname'],
1231 maps=["idx 0 id %d" % (mapB)],
1232 fail=False)
1233 fail(ret != 0, "couldn't reuse a map on the same ASIC")
1234 rm("/sys/fs/bpf/nsimB_")
1235
1236 ret, _, err = bpftool_prog_load("sample_map_ret0.o", "/sys/fs/bpf/nsimA_",
1237 dev=simA['ifname'],
1238 maps=["idx 0 id %d" % (mapB)],
1239 fail=False, include_stderr=True)
1240 fail(ret == 0, "could reuse a map on a different ASIC")
1241 fail(err.count("offload device mismatch between prog and map") == 0,
1242 "error message missing for cross-ASIC map")
1243
1244 ret, _, err = bpftool_prog_load("sample_map_ret0.o", "/sys/fs/bpf/nsimB_",
1245 dev=simB1['ifname'],
1246 maps=["idx 0 id %d" % (mapA)],
1247 fail=False, include_stderr=True)
1248 fail(ret == 0, "could reuse a map on a different ASIC")
1249 fail(err.count("offload device mismatch between prog and map") == 0,
1250 "error message missing for cross-ASIC map")
1251
1252 start_test("Test multi-dev ASIC cross-dev destruction...")
1253 bpftool_prog_list_wait(expected=2)
1254
1255 simA.remove()
1256 bpftool_prog_list_wait(expected=1)
1257
1258 ifnameB = bpftool("prog show %s" % (progB))[1]["dev"]["ifname"]
1259 fail(ifnameB != simB1['ifname'], "program not bound to originial device")
1260 simB1.remove()
1261 bpftool_prog_list_wait(expected=1)
1262
1263 start_test("Test multi-dev ASIC cross-dev destruction - move...")
1264 ifnameB = bpftool("prog show %s" % (progB))[1]["dev"]["ifname"]
1265 fail(ifnameB not in (simB2['ifname'], simB3['ifname']),
1266 "program not bound to remaining devices")
1267
1268 simB2.remove()
1269 ifnameB = bpftool("prog show %s" % (progB))[1]["dev"]["ifname"]
1270 fail(ifnameB != simB3['ifname'], "program not bound to remaining device")
1271
1272 simB3.remove()
1273 bpftool_prog_list_wait(expected=0)
1274
1275 start_test("Test multi-dev ASIC cross-dev destruction - orphaned...")
1276 ret, out = bpftool("prog show %s" % (progB), fail=False)
1277 fail(ret == 0, "got information about orphaned program")
1278 fail("error" not in out, "no error reported for get info on orphaned")
1279 fail(out["error"] != "can't get prog info: No such device",
1280 "wrong error for get info on orphaned")
1281
1088 print("%s: OK" % (os.path.basename(__file__))) 1282 print("%s: OK" % (os.path.basename(__file__)))
1089 1283
1090finally: 1284finally:
diff --git a/tools/testing/selftests/bpf/test_select_reuseport.c b/tools/testing/selftests/bpf/test_select_reuseport.c
new file mode 100644
index 000000000000..75646d9b34aa
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_select_reuseport.c
@@ -0,0 +1,688 @@
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2018 Facebook */
3
4#include <stdlib.h>
5#include <unistd.h>
6#include <stdbool.h>
7#include <string.h>
8#include <errno.h>
9#include <assert.h>
10#include <fcntl.h>
11#include <linux/bpf.h>
12#include <linux/err.h>
13#include <linux/types.h>
14#include <linux/if_ether.h>
15#include <sys/types.h>
16#include <sys/epoll.h>
17#include <sys/socket.h>
18#include <netinet/in.h>
19#include <bpf/bpf.h>
20#include <bpf/libbpf.h>
21#include "bpf_rlimit.h"
22#include "bpf_util.h"
23#include "test_select_reuseport_common.h"
24
25#define MIN_TCPHDR_LEN 20
26#define UDPHDR_LEN 8
27
28#define TCP_SYNCOOKIE_SYSCTL "/proc/sys/net/ipv4/tcp_syncookies"
29#define TCP_FO_SYSCTL "/proc/sys/net/ipv4/tcp_fastopen"
30#define REUSEPORT_ARRAY_SIZE 32
31
32static int result_map, tmp_index_ovr_map, linum_map, data_check_map;
33static enum result expected_results[NR_RESULTS];
34static int sk_fds[REUSEPORT_ARRAY_SIZE];
35static int reuseport_array, outer_map;
36static int select_by_skb_data_prog;
37static int saved_tcp_syncookie;
38static struct bpf_object *obj;
39static int saved_tcp_fo;
40static __u32 index_zero;
41static int epfd;
42
43static union sa46 {
44 struct sockaddr_in6 v6;
45 struct sockaddr_in v4;
46 sa_family_t family;
47} srv_sa;
48
49#define CHECK(condition, tag, format...) ({ \
50 int __ret = !!(condition); \
51 if (__ret) { \
52 printf("%s(%d):FAIL:%s ", __func__, __LINE__, tag); \
53 printf(format); \
54 exit(-1); \
55 } \
56})
57
58static void create_maps(void)
59{
60 struct bpf_create_map_attr attr = {};
61
62 /* Creating reuseport_array */
63 attr.name = "reuseport_array";
64 attr.map_type = BPF_MAP_TYPE_REUSEPORT_SOCKARRAY;
65 attr.key_size = sizeof(__u32);
66 attr.value_size = sizeof(__u32);
67 attr.max_entries = REUSEPORT_ARRAY_SIZE;
68
69 reuseport_array = bpf_create_map_xattr(&attr);
70 CHECK(reuseport_array == -1, "creating reuseport_array",
71 "reuseport_array:%d errno:%d\n", reuseport_array, errno);
72
73 /* Creating outer_map */
74 attr.name = "outer_map";
75 attr.map_type = BPF_MAP_TYPE_ARRAY_OF_MAPS;
76 attr.key_size = sizeof(__u32);
77 attr.value_size = sizeof(__u32);
78 attr.max_entries = 1;
79 attr.inner_map_fd = reuseport_array;
80 outer_map = bpf_create_map_xattr(&attr);
81 CHECK(outer_map == -1, "creating outer_map",
82 "outer_map:%d errno:%d\n", outer_map, errno);
83}
84
85static void prepare_bpf_obj(void)
86{
87 struct bpf_program *prog;
88 struct bpf_map *map;
89 int err;
90 struct bpf_object_open_attr attr = {
91 .file = "test_select_reuseport_kern.o",
92 .prog_type = BPF_PROG_TYPE_SK_REUSEPORT,
93 };
94
95 obj = bpf_object__open_xattr(&attr);
96 CHECK(IS_ERR_OR_NULL(obj), "open test_select_reuseport_kern.o",
97 "obj:%p PTR_ERR(obj):%ld\n", obj, PTR_ERR(obj));
98
99 prog = bpf_program__next(NULL, obj);
100 CHECK(!prog, "get first bpf_program", "!prog\n");
101 bpf_program__set_type(prog, attr.prog_type);
102
103 map = bpf_object__find_map_by_name(obj, "outer_map");
104 CHECK(!map, "find outer_map", "!map\n");
105 err = bpf_map__reuse_fd(map, outer_map);
106 CHECK(err, "reuse outer_map", "err:%d\n", err);
107
108 err = bpf_object__load(obj);
109 CHECK(err, "load bpf_object", "err:%d\n", err);
110
111 select_by_skb_data_prog = bpf_program__fd(prog);
112 CHECK(select_by_skb_data_prog == -1, "get prog fd",
113 "select_by_skb_data_prog:%d\n", select_by_skb_data_prog);
114
115 map = bpf_object__find_map_by_name(obj, "result_map");
116 CHECK(!map, "find result_map", "!map\n");
117 result_map = bpf_map__fd(map);
118 CHECK(result_map == -1, "get result_map fd",
119 "result_map:%d\n", result_map);
120
121 map = bpf_object__find_map_by_name(obj, "tmp_index_ovr_map");
122 CHECK(!map, "find tmp_index_ovr_map", "!map\n");
123 tmp_index_ovr_map = bpf_map__fd(map);
124 CHECK(tmp_index_ovr_map == -1, "get tmp_index_ovr_map fd",
125 "tmp_index_ovr_map:%d\n", tmp_index_ovr_map);
126
127 map = bpf_object__find_map_by_name(obj, "linum_map");
128 CHECK(!map, "find linum_map", "!map\n");
129 linum_map = bpf_map__fd(map);
130 CHECK(linum_map == -1, "get linum_map fd",
131 "linum_map:%d\n", linum_map);
132
133 map = bpf_object__find_map_by_name(obj, "data_check_map");
134 CHECK(!map, "find data_check_map", "!map\n");
135 data_check_map = bpf_map__fd(map);
136 CHECK(data_check_map == -1, "get data_check_map fd",
137 "data_check_map:%d\n", data_check_map);
138}
139
140static void sa46_init_loopback(union sa46 *sa, sa_family_t family)
141{
142 memset(sa, 0, sizeof(*sa));
143 sa->family = family;
144 if (sa->family == AF_INET6)
145 sa->v6.sin6_addr = in6addr_loopback;
146 else
147 sa->v4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
148}
149
150static void sa46_init_inany(union sa46 *sa, sa_family_t family)
151{
152 memset(sa, 0, sizeof(*sa));
153 sa->family = family;
154 if (sa->family == AF_INET6)
155 sa->v6.sin6_addr = in6addr_any;
156 else
157 sa->v4.sin_addr.s_addr = INADDR_ANY;
158}
159
160static int read_int_sysctl(const char *sysctl)
161{
162 char buf[16];
163 int fd, ret;
164
165 fd = open(sysctl, 0);
166 CHECK(fd == -1, "open(sysctl)", "sysctl:%s fd:%d errno:%d\n",
167 sysctl, fd, errno);
168
169 ret = read(fd, buf, sizeof(buf));
170 CHECK(ret <= 0, "read(sysctl)", "sysctl:%s ret:%d errno:%d\n",
171 sysctl, ret, errno);
172 close(fd);
173
174 return atoi(buf);
175}
176
177static void write_int_sysctl(const char *sysctl, int v)
178{
179 int fd, ret, size;
180 char buf[16];
181
182 fd = open(sysctl, O_RDWR);
183 CHECK(fd == -1, "open(sysctl)", "sysctl:%s fd:%d errno:%d\n",
184 sysctl, fd, errno);
185
186 size = snprintf(buf, sizeof(buf), "%d", v);
187 ret = write(fd, buf, size);
188 CHECK(ret != size, "write(sysctl)",
189 "sysctl:%s ret:%d size:%d errno:%d\n", sysctl, ret, size, errno);
190 close(fd);
191}
192
193static void restore_sysctls(void)
194{
195 write_int_sysctl(TCP_FO_SYSCTL, saved_tcp_fo);
196 write_int_sysctl(TCP_SYNCOOKIE_SYSCTL, saved_tcp_syncookie);
197}
198
199static void enable_fastopen(void)
200{
201 int fo;
202
203 fo = read_int_sysctl(TCP_FO_SYSCTL);
204 write_int_sysctl(TCP_FO_SYSCTL, fo | 7);
205}
206
207static void enable_syncookie(void)
208{
209 write_int_sysctl(TCP_SYNCOOKIE_SYSCTL, 2);
210}
211
212static void disable_syncookie(void)
213{
214 write_int_sysctl(TCP_SYNCOOKIE_SYSCTL, 0);
215}
216
217static __u32 get_linum(void)
218{
219 __u32 linum;
220 int err;
221
222 err = bpf_map_lookup_elem(linum_map, &index_zero, &linum);
223 CHECK(err == -1, "lookup_elem(linum_map)", "err:%d errno:%d\n",
224 err, errno);
225
226 return linum;
227}
228
229static void check_data(int type, sa_family_t family, const struct cmd *cmd,
230 int cli_fd)
231{
232 struct data_check expected = {}, result;
233 union sa46 cli_sa;
234 socklen_t addrlen;
235 int err;
236
237 addrlen = sizeof(cli_sa);
238 err = getsockname(cli_fd, (struct sockaddr *)&cli_sa,
239 &addrlen);
240 CHECK(err == -1, "getsockname(cli_fd)", "err:%d errno:%d\n",
241 err, errno);
242
243 err = bpf_map_lookup_elem(data_check_map, &index_zero, &result);
244 CHECK(err == -1, "lookup_elem(data_check_map)", "err:%d errno:%d\n",
245 err, errno);
246
247 if (type == SOCK_STREAM) {
248 expected.len = MIN_TCPHDR_LEN;
249 expected.ip_protocol = IPPROTO_TCP;
250 } else {
251 expected.len = UDPHDR_LEN;
252 expected.ip_protocol = IPPROTO_UDP;
253 }
254
255 if (family == AF_INET6) {
256 expected.eth_protocol = htons(ETH_P_IPV6);
257 expected.bind_inany = !srv_sa.v6.sin6_addr.s6_addr32[3] &&
258 !srv_sa.v6.sin6_addr.s6_addr32[2] &&
259 !srv_sa.v6.sin6_addr.s6_addr32[1] &&
260 !srv_sa.v6.sin6_addr.s6_addr32[0];
261
262 memcpy(&expected.skb_addrs[0], cli_sa.v6.sin6_addr.s6_addr32,
263 sizeof(cli_sa.v6.sin6_addr));
264 memcpy(&expected.skb_addrs[4], &in6addr_loopback,
265 sizeof(in6addr_loopback));
266 expected.skb_ports[0] = cli_sa.v6.sin6_port;
267 expected.skb_ports[1] = srv_sa.v6.sin6_port;
268 } else {
269 expected.eth_protocol = htons(ETH_P_IP);
270 expected.bind_inany = !srv_sa.v4.sin_addr.s_addr;
271
272 expected.skb_addrs[0] = cli_sa.v4.sin_addr.s_addr;
273 expected.skb_addrs[1] = htonl(INADDR_LOOPBACK);
274 expected.skb_ports[0] = cli_sa.v4.sin_port;
275 expected.skb_ports[1] = srv_sa.v4.sin_port;
276 }
277
278 if (memcmp(&result, &expected, offsetof(struct data_check,
279 equal_check_end))) {
280 printf("unexpected data_check\n");
281 printf(" result: (0x%x, %u, %u)\n",
282 result.eth_protocol, result.ip_protocol,
283 result.bind_inany);
284 printf("expected: (0x%x, %u, %u)\n",
285 expected.eth_protocol, expected.ip_protocol,
286 expected.bind_inany);
287 CHECK(1, "data_check result != expected",
288 "bpf_prog_linum:%u\n", get_linum());
289 }
290
291 CHECK(!result.hash, "data_check result.hash empty",
292 "result.hash:%u", result.hash);
293
294 expected.len += cmd ? sizeof(*cmd) : 0;
295 if (type == SOCK_STREAM)
296 CHECK(expected.len > result.len, "expected.len > result.len",
297 "expected.len:%u result.len:%u bpf_prog_linum:%u\n",
298 expected.len, result.len, get_linum());
299 else
300 CHECK(expected.len != result.len, "expected.len != result.len",
301 "expected.len:%u result.len:%u bpf_prog_linum:%u\n",
302 expected.len, result.len, get_linum());
303}
304
305static void check_results(void)
306{
307 __u32 results[NR_RESULTS];
308 __u32 i, broken = 0;
309 int err;
310
311 for (i = 0; i < NR_RESULTS; i++) {
312 err = bpf_map_lookup_elem(result_map, &i, &results[i]);
313 CHECK(err == -1, "lookup_elem(result_map)",
314 "i:%u err:%d errno:%d\n", i, err, errno);
315 }
316
317 for (i = 0; i < NR_RESULTS; i++) {
318 if (results[i] != expected_results[i]) {
319 broken = i;
320 break;
321 }
322 }
323
324 if (i == NR_RESULTS)
325 return;
326
327 printf("unexpected result\n");
328 printf(" result: [");
329 printf("%u", results[0]);
330 for (i = 1; i < NR_RESULTS; i++)
331 printf(", %u", results[i]);
332 printf("]\n");
333
334 printf("expected: [");
335 printf("%u", expected_results[0]);
336 for (i = 1; i < NR_RESULTS; i++)
337 printf(", %u", expected_results[i]);
338 printf("]\n");
339
340 CHECK(expected_results[broken] != results[broken],
341 "unexpected result",
342 "expected_results[%u] != results[%u] bpf_prog_linum:%u\n",
343 broken, broken, get_linum());
344}
345
346static int send_data(int type, sa_family_t family, void *data, size_t len,
347 enum result expected)
348{
349 union sa46 cli_sa;
350 int fd, err;
351
352 fd = socket(family, type, 0);
353 CHECK(fd == -1, "socket()", "fd:%d errno:%d\n", fd, errno);
354
355 sa46_init_loopback(&cli_sa, family);
356 err = bind(fd, (struct sockaddr *)&cli_sa, sizeof(cli_sa));
357 CHECK(fd == -1, "bind(cli_sa)", "err:%d errno:%d\n", err, errno);
358
359 err = sendto(fd, data, len, MSG_FASTOPEN, (struct sockaddr *)&srv_sa,
360 sizeof(srv_sa));
361 CHECK(err != len && expected >= PASS,
362 "sendto()", "family:%u err:%d errno:%d expected:%d\n",
363 family, err, errno, expected);
364
365 return fd;
366}
367
368static void do_test(int type, sa_family_t family, struct cmd *cmd,
369 enum result expected)
370{
371 int nev, srv_fd, cli_fd;
372 struct epoll_event ev;
373 struct cmd rcv_cmd;
374 ssize_t nread;
375
376 cli_fd = send_data(type, family, cmd, cmd ? sizeof(*cmd) : 0,
377 expected);
378 nev = epoll_wait(epfd, &ev, 1, expected >= PASS ? 5 : 0);
379 CHECK((nev <= 0 && expected >= PASS) ||
380 (nev > 0 && expected < PASS),
381 "nev <> expected",
382 "nev:%d expected:%d type:%d family:%d data:(%d, %d)\n",
383 nev, expected, type, family,
384 cmd ? cmd->reuseport_index : -1,
385 cmd ? cmd->pass_on_failure : -1);
386 check_results();
387 check_data(type, family, cmd, cli_fd);
388
389 if (expected < PASS)
390 return;
391
392 CHECK(expected != PASS_ERR_SK_SELECT_REUSEPORT &&
393 cmd->reuseport_index != ev.data.u32,
394 "check cmd->reuseport_index",
395 "cmd:(%u, %u) ev.data.u32:%u\n",
396 cmd->pass_on_failure, cmd->reuseport_index, ev.data.u32);
397
398 srv_fd = sk_fds[ev.data.u32];
399 if (type == SOCK_STREAM) {
400 int new_fd = accept(srv_fd, NULL, 0);
401
402 CHECK(new_fd == -1, "accept(srv_fd)",
403 "ev.data.u32:%u new_fd:%d errno:%d\n",
404 ev.data.u32, new_fd, errno);
405
406 nread = recv(new_fd, &rcv_cmd, sizeof(rcv_cmd), MSG_DONTWAIT);
407 CHECK(nread != sizeof(rcv_cmd),
408 "recv(new_fd)",
409 "ev.data.u32:%u nread:%zd sizeof(rcv_cmd):%zu errno:%d\n",
410 ev.data.u32, nread, sizeof(rcv_cmd), errno);
411
412 close(new_fd);
413 } else {
414 nread = recv(srv_fd, &rcv_cmd, sizeof(rcv_cmd), MSG_DONTWAIT);
415 CHECK(nread != sizeof(rcv_cmd),
416 "recv(sk_fds)",
417 "ev.data.u32:%u nread:%zd sizeof(rcv_cmd):%zu errno:%d\n",
418 ev.data.u32, nread, sizeof(rcv_cmd), errno);
419 }
420
421 close(cli_fd);
422}
423
424static void test_err_inner_map(int type, sa_family_t family)
425{
426 struct cmd cmd = {
427 .reuseport_index = 0,
428 .pass_on_failure = 0,
429 };
430
431 printf("%s: ", __func__);
432 expected_results[DROP_ERR_INNER_MAP]++;
433 do_test(type, family, &cmd, DROP_ERR_INNER_MAP);
434 printf("OK\n");
435}
436
437static void test_err_skb_data(int type, sa_family_t family)
438{
439 printf("%s: ", __func__);
440 expected_results[DROP_ERR_SKB_DATA]++;
441 do_test(type, family, NULL, DROP_ERR_SKB_DATA);
442 printf("OK\n");
443}
444
445static void test_err_sk_select_port(int type, sa_family_t family)
446{
447 struct cmd cmd = {
448 .reuseport_index = REUSEPORT_ARRAY_SIZE,
449 .pass_on_failure = 0,
450 };
451
452 printf("%s: ", __func__);
453 expected_results[DROP_ERR_SK_SELECT_REUSEPORT]++;
454 do_test(type, family, &cmd, DROP_ERR_SK_SELECT_REUSEPORT);
455 printf("OK\n");
456}
457
458static void test_pass(int type, sa_family_t family)
459{
460 struct cmd cmd;
461 int i;
462
463 printf("%s: ", __func__);
464 cmd.pass_on_failure = 0;
465 for (i = 0; i < REUSEPORT_ARRAY_SIZE; i++) {
466 expected_results[PASS]++;
467 cmd.reuseport_index = i;
468 do_test(type, family, &cmd, PASS);
469 }
470 printf("OK\n");
471}
472
473static void test_syncookie(int type, sa_family_t family)
474{
475 int err, tmp_index = 1;
476 struct cmd cmd = {
477 .reuseport_index = 0,
478 .pass_on_failure = 0,
479 };
480
481 if (type != SOCK_STREAM)
482 return;
483
484 printf("%s: ", __func__);
485 /*
486 * +1 for TCP-SYN and
487 * +1 for the TCP-ACK (ack the syncookie)
488 */
489 expected_results[PASS] += 2;
490 enable_syncookie();
491 /*
492 * Simulate TCP-SYN and TCP-ACK are handled by two different sk:
493 * TCP-SYN: select sk_fds[tmp_index = 1] tmp_index is from the
494 * tmp_index_ovr_map
495 * TCP-ACK: select sk_fds[reuseport_index = 0] reuseport_index
496 * is from the cmd.reuseport_index
497 */
498 err = bpf_map_update_elem(tmp_index_ovr_map, &index_zero,
499 &tmp_index, BPF_ANY);
500 CHECK(err == -1, "update_elem(tmp_index_ovr_map, 0, 1)",
501 "err:%d errno:%d\n", err, errno);
502 do_test(type, family, &cmd, PASS);
503 err = bpf_map_lookup_elem(tmp_index_ovr_map, &index_zero,
504 &tmp_index);
505 CHECK(err == -1 || tmp_index != -1,
506 "lookup_elem(tmp_index_ovr_map)",
507 "err:%d errno:%d tmp_index:%d\n",
508 err, errno, tmp_index);
509 disable_syncookie();
510 printf("OK\n");
511}
512
513static void test_pass_on_err(int type, sa_family_t family)
514{
515 struct cmd cmd = {
516 .reuseport_index = REUSEPORT_ARRAY_SIZE,
517 .pass_on_failure = 1,
518 };
519
520 printf("%s: ", __func__);
521 expected_results[PASS_ERR_SK_SELECT_REUSEPORT] += 1;
522 do_test(type, family, &cmd, PASS_ERR_SK_SELECT_REUSEPORT);
523 printf("OK\n");
524}
525
526static void prepare_sk_fds(int type, sa_family_t family, bool inany)
527{
528 const int first = REUSEPORT_ARRAY_SIZE - 1;
529 int i, err, optval = 1;
530 struct epoll_event ev;
531 socklen_t addrlen;
532
533 if (inany)
534 sa46_init_inany(&srv_sa, family);
535 else
536 sa46_init_loopback(&srv_sa, family);
537 addrlen = sizeof(srv_sa);
538
539 /*
540 * The sk_fds[] is filled from the back such that the order
541 * is exactly opposite to the (struct sock_reuseport *)reuse->socks[].
542 */
543 for (i = first; i >= 0; i--) {
544 sk_fds[i] = socket(family, type, 0);
545 CHECK(sk_fds[i] == -1, "socket()", "sk_fds[%d]:%d errno:%d\n",
546 i, sk_fds[i], errno);
547 err = setsockopt(sk_fds[i], SOL_SOCKET, SO_REUSEPORT,
548 &optval, sizeof(optval));
549 CHECK(err == -1, "setsockopt(SO_REUSEPORT)",
550 "sk_fds[%d] err:%d errno:%d\n",
551 i, err, errno);
552
553 if (i == first) {
554 err = setsockopt(sk_fds[i], SOL_SOCKET,
555 SO_ATTACH_REUSEPORT_EBPF,
556 &select_by_skb_data_prog,
557 sizeof(select_by_skb_data_prog));
558 CHECK(err == -1, "setsockopt(SO_ATTACH_REUEPORT_EBPF)",
559 "err:%d errno:%d\n", err, errno);
560 }
561
562 err = bind(sk_fds[i], (struct sockaddr *)&srv_sa, addrlen);
563 CHECK(err == -1, "bind()", "sk_fds[%d] err:%d errno:%d\n",
564 i, err, errno);
565
566 if (type == SOCK_STREAM) {
567 err = listen(sk_fds[i], 10);
568 CHECK(err == -1, "listen()",
569 "sk_fds[%d] err:%d errno:%d\n",
570 i, err, errno);
571 }
572
573 err = bpf_map_update_elem(reuseport_array, &i, &sk_fds[i],
574 BPF_NOEXIST);
575 CHECK(err == -1, "update_elem(reuseport_array)",
576 "sk_fds[%d] err:%d errno:%d\n", i, err, errno);
577
578 if (i == first) {
579 socklen_t addrlen = sizeof(srv_sa);
580
581 err = getsockname(sk_fds[i], (struct sockaddr *)&srv_sa,
582 &addrlen);
583 CHECK(err == -1, "getsockname()",
584 "sk_fds[%d] err:%d errno:%d\n", i, err, errno);
585 }
586 }
587
588 epfd = epoll_create(1);
589 CHECK(epfd == -1, "epoll_create(1)",
590 "epfd:%d errno:%d\n", epfd, errno);
591
592 ev.events = EPOLLIN;
593 for (i = 0; i < REUSEPORT_ARRAY_SIZE; i++) {
594 ev.data.u32 = i;
595 err = epoll_ctl(epfd, EPOLL_CTL_ADD, sk_fds[i], &ev);
596 CHECK(err, "epoll_ctl(EPOLL_CTL_ADD)", "sk_fds[%d]\n", i);
597 }
598}
599
600static void setup_per_test(int type, unsigned short family, bool inany)
601{
602 int ovr = -1, err;
603
604 prepare_sk_fds(type, family, inany);
605 err = bpf_map_update_elem(tmp_index_ovr_map, &index_zero, &ovr,
606 BPF_ANY);
607 CHECK(err == -1, "update_elem(tmp_index_ovr_map, 0, -1)",
608 "err:%d errno:%d\n", err, errno);
609}
610
611static void cleanup_per_test(void)
612{
613 int i, err;
614
615 for (i = 0; i < REUSEPORT_ARRAY_SIZE; i++)
616 close(sk_fds[i]);
617 close(epfd);
618
619 err = bpf_map_delete_elem(outer_map, &index_zero);
620 CHECK(err == -1, "delete_elem(outer_map)",
621 "err:%d errno:%d\n", err, errno);
622}
623
624static void cleanup(void)
625{
626 close(outer_map);
627 close(reuseport_array);
628 bpf_object__close(obj);
629}
630
631static void test_all(void)
632{
633 /* Extra SOCK_STREAM to test bind_inany==true */
634 const int types[] = { SOCK_STREAM, SOCK_DGRAM, SOCK_STREAM };
635 const char * const type_strings[] = { "TCP", "UDP", "TCP" };
636 const char * const family_strings[] = { "IPv6", "IPv4" };
637 const unsigned short families[] = { AF_INET6, AF_INET };
638 const bool bind_inany[] = { false, false, true };
639 int t, f, err;
640
641 for (f = 0; f < ARRAY_SIZE(families); f++) {
642 unsigned short family = families[f];
643
644 for (t = 0; t < ARRAY_SIZE(types); t++) {
645 bool inany = bind_inany[t];
646 int type = types[t];
647
648 printf("######## %s/%s %s ########\n",
649 family_strings[f], type_strings[t],
650 inany ? " INANY " : "LOOPBACK");
651
652 setup_per_test(type, family, inany);
653
654 test_err_inner_map(type, family);
655
656 /* Install reuseport_array to the outer_map */
657 err = bpf_map_update_elem(outer_map, &index_zero,
658 &reuseport_array, BPF_ANY);
659 CHECK(err == -1, "update_elem(outer_map)",
660 "err:%d errno:%d\n", err, errno);
661
662 test_err_skb_data(type, family);
663 test_err_sk_select_port(type, family);
664 test_pass(type, family);
665 test_syncookie(type, family);
666 test_pass_on_err(type, family);
667
668 cleanup_per_test();
669 printf("\n");
670 }
671 }
672}
673
674int main(int argc, const char **argv)
675{
676 create_maps();
677 prepare_bpf_obj();
678 saved_tcp_fo = read_int_sysctl(TCP_FO_SYSCTL);
679 saved_tcp_syncookie = read_int_sysctl(TCP_SYNCOOKIE_SYSCTL);
680 enable_fastopen();
681 disable_syncookie();
682 atexit(restore_sysctls);
683
684 test_all();
685
686 cleanup();
687 return 0;
688}
diff --git a/tools/testing/selftests/bpf/test_select_reuseport_common.h b/tools/testing/selftests/bpf/test_select_reuseport_common.h
new file mode 100644
index 000000000000..08eb2a9f145f
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_select_reuseport_common.h
@@ -0,0 +1,36 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (c) 2018 Facebook */
3
4#ifndef __TEST_SELECT_REUSEPORT_COMMON_H
5#define __TEST_SELECT_REUSEPORT_COMMON_H
6
7#include <linux/types.h>
8
9enum result {
10 DROP_ERR_INNER_MAP,
11 DROP_ERR_SKB_DATA,
12 DROP_ERR_SK_SELECT_REUSEPORT,
13 DROP_MISC,
14 PASS,
15 PASS_ERR_SK_SELECT_REUSEPORT,
16 NR_RESULTS,
17};
18
19struct cmd {
20 __u32 reuseport_index;
21 __u32 pass_on_failure;
22};
23
24struct data_check {
25 __u32 ip_protocol;
26 __u32 skb_addrs[8];
27 __u16 skb_ports[2];
28 __u16 eth_protocol;
29 __u8 bind_inany;
30 __u8 equal_check_end[0];
31
32 __u32 len;
33 __u32 hash;
34};
35
36#endif
diff --git a/tools/testing/selftests/bpf/test_select_reuseport_kern.c b/tools/testing/selftests/bpf/test_select_reuseport_kern.c
new file mode 100644
index 000000000000..5b54ec637ada
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_select_reuseport_kern.c
@@ -0,0 +1,180 @@
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2018 Facebook */
3
4#include <stdlib.h>
5#include <linux/in.h>
6#include <linux/ip.h>
7#include <linux/ipv6.h>
8#include <linux/tcp.h>
9#include <linux/udp.h>
10#include <linux/bpf.h>
11#include <linux/types.h>
12#include <linux/if_ether.h>
13
14#include "bpf_endian.h"
15#include "bpf_helpers.h"
16#include "test_select_reuseport_common.h"
17
18int _version SEC("version") = 1;
19
20#ifndef offsetof
21#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
22#endif
23
24struct bpf_map_def SEC("maps") outer_map = {
25 .type = BPF_MAP_TYPE_ARRAY_OF_MAPS,
26 .key_size = sizeof(__u32),
27 .value_size = sizeof(__u32),
28 .max_entries = 1,
29};
30
31struct bpf_map_def SEC("maps") result_map = {
32 .type = BPF_MAP_TYPE_ARRAY,
33 .key_size = sizeof(__u32),
34 .value_size = sizeof(__u32),
35 .max_entries = NR_RESULTS,
36};
37
38struct bpf_map_def SEC("maps") tmp_index_ovr_map = {
39 .type = BPF_MAP_TYPE_ARRAY,
40 .key_size = sizeof(__u32),
41 .value_size = sizeof(int),
42 .max_entries = 1,
43};
44
45struct bpf_map_def SEC("maps") linum_map = {
46 .type = BPF_MAP_TYPE_ARRAY,
47 .key_size = sizeof(__u32),
48 .value_size = sizeof(__u32),
49 .max_entries = 1,
50};
51
52struct bpf_map_def SEC("maps") data_check_map = {
53 .type = BPF_MAP_TYPE_ARRAY,
54 .key_size = sizeof(__u32),
55 .value_size = sizeof(struct data_check),
56 .max_entries = 1,
57};
58
59#define GOTO_DONE(_result) ({ \
60 result = (_result); \
61 linum = __LINE__; \
62 goto done; \
63})
64
65SEC("select_by_skb_data")
66int _select_by_skb_data(struct sk_reuseport_md *reuse_md)
67{
68 __u32 linum, index = 0, flags = 0, index_zero = 0;
69 __u32 *result_cnt, *linum_value;
70 struct data_check data_check = {};
71 struct cmd *cmd, cmd_copy;
72 void *data, *data_end;
73 void *reuseport_array;
74 enum result result;
75 int *index_ovr;
76 int err;
77
78 data = reuse_md->data;
79 data_end = reuse_md->data_end;
80 data_check.len = reuse_md->len;
81 data_check.eth_protocol = reuse_md->eth_protocol;
82 data_check.ip_protocol = reuse_md->ip_protocol;
83 data_check.hash = reuse_md->hash;
84 data_check.bind_inany = reuse_md->bind_inany;
85 if (data_check.eth_protocol == bpf_htons(ETH_P_IP)) {
86 if (bpf_skb_load_bytes_relative(reuse_md,
87 offsetof(struct iphdr, saddr),
88 data_check.skb_addrs, 8,
89 BPF_HDR_START_NET))
90 GOTO_DONE(DROP_MISC);
91 } else {
92 if (bpf_skb_load_bytes_relative(reuse_md,
93 offsetof(struct ipv6hdr, saddr),
94 data_check.skb_addrs, 32,
95 BPF_HDR_START_NET))
96 GOTO_DONE(DROP_MISC);
97 }
98
99 /*
100 * The ip_protocol could be a compile time decision
101 * if the bpf_prog.o is dedicated to either TCP or
102 * UDP.
103 *
104 * Otherwise, reuse_md->ip_protocol or
105 * the protocol field in the iphdr can be used.
106 */
107 if (data_check.ip_protocol == IPPROTO_TCP) {
108 struct tcphdr *th = data;
109
110 if (th + 1 > data_end)
111 GOTO_DONE(DROP_MISC);
112
113 data_check.skb_ports[0] = th->source;
114 data_check.skb_ports[1] = th->dest;
115
116 if ((th->doff << 2) + sizeof(*cmd) > data_check.len)
117 GOTO_DONE(DROP_ERR_SKB_DATA);
118 if (bpf_skb_load_bytes(reuse_md, th->doff << 2, &cmd_copy,
119 sizeof(cmd_copy)))
120 GOTO_DONE(DROP_MISC);
121 cmd = &cmd_copy;
122 } else if (data_check.ip_protocol == IPPROTO_UDP) {
123 struct udphdr *uh = data;
124
125 if (uh + 1 > data_end)
126 GOTO_DONE(DROP_MISC);
127
128 data_check.skb_ports[0] = uh->source;
129 data_check.skb_ports[1] = uh->dest;
130
131 if (sizeof(struct udphdr) + sizeof(*cmd) > data_check.len)
132 GOTO_DONE(DROP_ERR_SKB_DATA);
133 if (data + sizeof(struct udphdr) + sizeof(*cmd) > data_end) {
134 if (bpf_skb_load_bytes(reuse_md, sizeof(struct udphdr),
135 &cmd_copy, sizeof(cmd_copy)))
136 GOTO_DONE(DROP_MISC);
137 cmd = &cmd_copy;
138 } else {
139 cmd = data + sizeof(struct udphdr);
140 }
141 } else {
142 GOTO_DONE(DROP_MISC);
143 }
144
145 reuseport_array = bpf_map_lookup_elem(&outer_map, &index_zero);
146 if (!reuseport_array)
147 GOTO_DONE(DROP_ERR_INNER_MAP);
148
149 index = cmd->reuseport_index;
150 index_ovr = bpf_map_lookup_elem(&tmp_index_ovr_map, &index_zero);
151 if (!index_ovr)
152 GOTO_DONE(DROP_MISC);
153
154 if (*index_ovr != -1) {
155 index = *index_ovr;
156 *index_ovr = -1;
157 }
158 err = bpf_sk_select_reuseport(reuse_md, reuseport_array, &index,
159 flags);
160 if (!err)
161 GOTO_DONE(PASS);
162
163 if (cmd->pass_on_failure)
164 GOTO_DONE(PASS_ERR_SK_SELECT_REUSEPORT);
165 else
166 GOTO_DONE(DROP_ERR_SK_SELECT_REUSEPORT);
167
168done:
169 result_cnt = bpf_map_lookup_elem(&result_map, &result);
170 if (!result_cnt)
171 return SK_DROP;
172
173 bpf_map_update_elem(&linum_map, &index_zero, &linum, BPF_ANY);
174 bpf_map_update_elem(&data_check_map, &index_zero, &data_check, BPF_ANY);
175
176 (*result_cnt)++;
177 return result < PASS ? SK_DROP : SK_PASS;
178}
179
180char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/test_skb_cgroup_id.sh b/tools/testing/selftests/bpf/test_skb_cgroup_id.sh
new file mode 100755
index 000000000000..42544a969abc
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_skb_cgroup_id.sh
@@ -0,0 +1,62 @@
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3# Copyright (c) 2018 Facebook
4
5set -eu
6
7wait_for_ip()
8{
9 local _i
10 echo -n "Wait for testing link-local IP to become available "
11 for _i in $(seq ${MAX_PING_TRIES}); do
12 echo -n "."
13 if ping -6 -q -c 1 -W 1 ff02::1%${TEST_IF} >/dev/null 2>&1; then
14 echo " OK"
15 return
16 fi
17 sleep 1
18 done
19 echo 1>&2 "ERROR: Timeout waiting for test IP to become available."
20 exit 1
21}
22
23setup()
24{
25 # Create testing interfaces not to interfere with current environment.
26 ip link add dev ${TEST_IF} type veth peer name ${TEST_IF_PEER}
27 ip link set ${TEST_IF} up
28 ip link set ${TEST_IF_PEER} up
29
30 wait_for_ip
31
32 tc qdisc add dev ${TEST_IF} clsact
33 tc filter add dev ${TEST_IF} egress bpf obj ${BPF_PROG_OBJ} \
34 sec ${BPF_PROG_SECTION} da
35
36 BPF_PROG_ID=$(tc filter show dev ${TEST_IF} egress | \
37 awk '/ id / {sub(/.* id /, "", $0); print($1)}')
38}
39
40cleanup()
41{
42 ip link del ${TEST_IF} 2>/dev/null || :
43 ip link del ${TEST_IF_PEER} 2>/dev/null || :
44}
45
46main()
47{
48 trap cleanup EXIT 2 3 6 15
49 setup
50 ${PROG} ${TEST_IF} ${BPF_PROG_ID}
51}
52
53DIR=$(dirname $0)
54TEST_IF="test_cgid_1"
55TEST_IF_PEER="test_cgid_2"
56MAX_PING_TRIES=5
57BPF_PROG_OBJ="${DIR}/test_skb_cgroup_id_kern.o"
58BPF_PROG_SECTION="cgroup_id_logger"
59BPF_PROG_ID=0
60PROG="${DIR}/test_skb_cgroup_id_user"
61
62main
diff --git a/tools/testing/selftests/bpf/test_skb_cgroup_id_kern.c b/tools/testing/selftests/bpf/test_skb_cgroup_id_kern.c
new file mode 100644
index 000000000000..68cf9829f5a7
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_skb_cgroup_id_kern.c
@@ -0,0 +1,47 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2018 Facebook
3
4#include <linux/bpf.h>
5#include <linux/pkt_cls.h>
6
7#include <string.h>
8
9#include "bpf_helpers.h"
10
11#define NUM_CGROUP_LEVELS 4
12
13struct bpf_map_def SEC("maps") cgroup_ids = {
14 .type = BPF_MAP_TYPE_ARRAY,
15 .key_size = sizeof(__u32),
16 .value_size = sizeof(__u64),
17 .max_entries = NUM_CGROUP_LEVELS,
18};
19
20static __always_inline void log_nth_level(struct __sk_buff *skb, __u32 level)
21{
22 __u64 id;
23
24 /* [1] &level passed to external function that may change it, it's
25 * incompatible with loop unroll.
26 */
27 id = bpf_skb_ancestor_cgroup_id(skb, level);
28 bpf_map_update_elem(&cgroup_ids, &level, &id, 0);
29}
30
31SEC("cgroup_id_logger")
32int log_cgroup_id(struct __sk_buff *skb)
33{
34 /* Loop unroll can't be used here due to [1]. Unrolling manually.
35 * Number of calls should be in sync with NUM_CGROUP_LEVELS.
36 */
37 log_nth_level(skb, 0);
38 log_nth_level(skb, 1);
39 log_nth_level(skb, 2);
40 log_nth_level(skb, 3);
41
42 return TC_ACT_OK;
43}
44
45int _version SEC("version") = 1;
46
47char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/test_skb_cgroup_id_user.c b/tools/testing/selftests/bpf/test_skb_cgroup_id_user.c
new file mode 100644
index 000000000000..c121cc59f314
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_skb_cgroup_id_user.c
@@ -0,0 +1,187 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2018 Facebook
3
4#include <stdlib.h>
5#include <string.h>
6#include <unistd.h>
7
8#include <arpa/inet.h>
9#include <net/if.h>
10#include <netinet/in.h>
11#include <sys/socket.h>
12#include <sys/types.h>
13
14
15#include <bpf/bpf.h>
16#include <bpf/libbpf.h>
17
18#include "bpf_rlimit.h"
19#include "cgroup_helpers.h"
20
21#define CGROUP_PATH "/skb_cgroup_test"
22#define NUM_CGROUP_LEVELS 4
23
24/* RFC 4291, Section 2.7.1 */
25#define LINKLOCAL_MULTICAST "ff02::1"
26
27static int mk_dst_addr(const char *ip, const char *iface,
28 struct sockaddr_in6 *dst)
29{
30 memset(dst, 0, sizeof(*dst));
31
32 dst->sin6_family = AF_INET6;
33 dst->sin6_port = htons(1025);
34
35 if (inet_pton(AF_INET6, ip, &dst->sin6_addr) != 1) {
36 log_err("Invalid IPv6: %s", ip);
37 return -1;
38 }
39
40 dst->sin6_scope_id = if_nametoindex(iface);
41 if (!dst->sin6_scope_id) {
42 log_err("Failed to get index of iface: %s", iface);
43 return -1;
44 }
45
46 return 0;
47}
48
49static int send_packet(const char *iface)
50{
51 struct sockaddr_in6 dst;
52 char msg[] = "msg";
53 int err = 0;
54 int fd = -1;
55
56 if (mk_dst_addr(LINKLOCAL_MULTICAST, iface, &dst))
57 goto err;
58
59 fd = socket(AF_INET6, SOCK_DGRAM, 0);
60 if (fd == -1) {
61 log_err("Failed to create UDP socket");
62 goto err;
63 }
64
65 if (sendto(fd, &msg, sizeof(msg), 0, (const struct sockaddr *)&dst,
66 sizeof(dst)) == -1) {
67 log_err("Failed to send datagram");
68 goto err;
69 }
70
71 goto out;
72err:
73 err = -1;
74out:
75 if (fd >= 0)
76 close(fd);
77 return err;
78}
79
80int get_map_fd_by_prog_id(int prog_id)
81{
82 struct bpf_prog_info info = {};
83 __u32 info_len = sizeof(info);
84 __u32 map_ids[1];
85 int prog_fd = -1;
86 int map_fd = -1;
87
88 prog_fd = bpf_prog_get_fd_by_id(prog_id);
89 if (prog_fd < 0) {
90 log_err("Failed to get fd by prog id %d", prog_id);
91 goto err;
92 }
93
94 info.nr_map_ids = 1;
95 info.map_ids = (__u64) (unsigned long) map_ids;
96
97 if (bpf_obj_get_info_by_fd(prog_fd, &info, &info_len)) {
98 log_err("Failed to get info by prog fd %d", prog_fd);
99 goto err;
100 }
101
102 if (!info.nr_map_ids) {
103 log_err("No maps found for prog fd %d", prog_fd);
104 goto err;
105 }
106
107 map_fd = bpf_map_get_fd_by_id(map_ids[0]);
108 if (map_fd < 0)
109 log_err("Failed to get fd by map id %d", map_ids[0]);
110err:
111 if (prog_fd >= 0)
112 close(prog_fd);
113 return map_fd;
114}
115
116int check_ancestor_cgroup_ids(int prog_id)
117{
118 __u64 actual_ids[NUM_CGROUP_LEVELS], expected_ids[NUM_CGROUP_LEVELS];
119 __u32 level;
120 int err = 0;
121 int map_fd;
122
123 expected_ids[0] = 0x100000001; /* root cgroup */
124 expected_ids[1] = get_cgroup_id("");
125 expected_ids[2] = get_cgroup_id(CGROUP_PATH);
126 expected_ids[3] = 0; /* non-existent cgroup */
127
128 map_fd = get_map_fd_by_prog_id(prog_id);
129 if (map_fd < 0)
130 goto err;
131
132 for (level = 0; level < NUM_CGROUP_LEVELS; ++level) {
133 if (bpf_map_lookup_elem(map_fd, &level, &actual_ids[level])) {
134 log_err("Failed to lookup key %d", level);
135 goto err;
136 }
137 if (actual_ids[level] != expected_ids[level]) {
138 log_err("%llx (actual) != %llx (expected), level: %u\n",
139 actual_ids[level], expected_ids[level], level);
140 goto err;
141 }
142 }
143
144 goto out;
145err:
146 err = -1;
147out:
148 if (map_fd >= 0)
149 close(map_fd);
150 return err;
151}
152
153int main(int argc, char **argv)
154{
155 int cgfd = -1;
156 int err = 0;
157
158 if (argc < 3) {
159 fprintf(stderr, "Usage: %s iface prog_id\n", argv[0]);
160 exit(EXIT_FAILURE);
161 }
162
163 if (setup_cgroup_environment())
164 goto err;
165
166 cgfd = create_and_get_cgroup(CGROUP_PATH);
167 if (!cgfd)
168 goto err;
169
170 if (join_cgroup(CGROUP_PATH))
171 goto err;
172
173 if (send_packet(argv[1]))
174 goto err;
175
176 if (check_ancestor_cgroup_ids(atoi(argv[2])))
177 goto err;
178
179 goto out;
180err:
181 err = -1;
182out:
183 close(cgfd);
184 cleanup_cgroup_environment();
185 printf("[%s]\n", err ? "FAIL" : "PASS");
186 return err;
187}
diff --git a/tools/testing/selftests/bpf/test_sock.c b/tools/testing/selftests/bpf/test_sock.c
index f4d99fabc56d..b8ebe2f58074 100644
--- a/tools/testing/selftests/bpf/test_sock.c
+++ b/tools/testing/selftests/bpf/test_sock.c
@@ -14,10 +14,7 @@
14 14
15#include "cgroup_helpers.h" 15#include "cgroup_helpers.h"
16#include "bpf_rlimit.h" 16#include "bpf_rlimit.h"
17 17#include "bpf_util.h"
18#ifndef ARRAY_SIZE
19# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
20#endif
21 18
22#define CG_PATH "/foo" 19#define CG_PATH "/foo"
23#define MAX_INSNS 512 20#define MAX_INSNS 512
diff --git a/tools/testing/selftests/bpf/test_sock_addr.c b/tools/testing/selftests/bpf/test_sock_addr.c
index a5e76b9219b9..aeeb76a54d63 100644
--- a/tools/testing/selftests/bpf/test_sock_addr.c
+++ b/tools/testing/selftests/bpf/test_sock_addr.c
@@ -20,15 +20,12 @@
20 20
21#include "cgroup_helpers.h" 21#include "cgroup_helpers.h"
22#include "bpf_rlimit.h" 22#include "bpf_rlimit.h"
23#include "bpf_util.h"
23 24
24#ifndef ENOTSUPP 25#ifndef ENOTSUPP
25# define ENOTSUPP 524 26# define ENOTSUPP 524
26#endif 27#endif
27 28
28#ifndef ARRAY_SIZE
29# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
30#endif
31
32#define CG_PATH "/foo" 29#define CG_PATH "/foo"
33#define CONNECT4_PROG_PATH "./connect4_prog.o" 30#define CONNECT4_PROG_PATH "./connect4_prog.o"
34#define CONNECT6_PROG_PATH "./connect6_prog.o" 31#define CONNECT6_PROG_PATH "./connect6_prog.o"
@@ -998,8 +995,9 @@ int init_pktinfo(int domain, struct cmsghdr *cmsg)
998 return 0; 995 return 0;
999} 996}
1000 997
1001static int sendmsg_to_server(const struct sockaddr_storage *addr, 998static int sendmsg_to_server(int type, const struct sockaddr_storage *addr,
1002 socklen_t addr_len, int set_cmsg, int *syscall_err) 999 socklen_t addr_len, int set_cmsg, int flags,
1000 int *syscall_err)
1003{ 1001{
1004 union { 1002 union {
1005 char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))]; 1003 char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
@@ -1022,7 +1020,7 @@ static int sendmsg_to_server(const struct sockaddr_storage *addr,
1022 goto err; 1020 goto err;
1023 } 1021 }
1024 1022
1025 fd = socket(domain, SOCK_DGRAM, 0); 1023 fd = socket(domain, type, 0);
1026 if (fd == -1) { 1024 if (fd == -1) {
1027 log_err("Failed to create client socket"); 1025 log_err("Failed to create client socket");
1028 goto err; 1026 goto err;
@@ -1052,7 +1050,7 @@ static int sendmsg_to_server(const struct sockaddr_storage *addr,
1052 } 1050 }
1053 } 1051 }
1054 1052
1055 if (sendmsg(fd, &hdr, 0) != sizeof(data)) { 1053 if (sendmsg(fd, &hdr, flags) != sizeof(data)) {
1056 log_err("Fail to send message to server"); 1054 log_err("Fail to send message to server");
1057 *syscall_err = errno; 1055 *syscall_err = errno;
1058 goto err; 1056 goto err;
@@ -1066,6 +1064,15 @@ out:
1066 return fd; 1064 return fd;
1067} 1065}
1068 1066
1067static int fastconnect_to_server(const struct sockaddr_storage *addr,
1068 socklen_t addr_len)
1069{
1070 int sendmsg_err;
1071
1072 return sendmsg_to_server(SOCK_STREAM, addr, addr_len, /*set_cmsg*/0,
1073 MSG_FASTOPEN, &sendmsg_err);
1074}
1075
1069static int recvmsg_from_client(int sockfd, struct sockaddr_storage *src_addr) 1076static int recvmsg_from_client(int sockfd, struct sockaddr_storage *src_addr)
1070{ 1077{
1071 struct timeval tv; 1078 struct timeval tv;
@@ -1185,6 +1192,20 @@ static int run_connect_test_case(const struct sock_addr_test *test)
1185 if (cmp_local_ip(clientfd, &expected_src_addr)) 1192 if (cmp_local_ip(clientfd, &expected_src_addr))
1186 goto err; 1193 goto err;
1187 1194
1195 if (test->type == SOCK_STREAM) {
1196 /* Test TCP Fast Open scenario */
1197 clientfd = fastconnect_to_server(&requested_addr, addr_len);
1198 if (clientfd == -1)
1199 goto err;
1200
1201 /* Make sure src and dst addrs were overridden properly */
1202 if (cmp_peer_addr(clientfd, &expected_addr))
1203 goto err;
1204
1205 if (cmp_local_ip(clientfd, &expected_src_addr))
1206 goto err;
1207 }
1208
1188 goto out; 1209 goto out;
1189err: 1210err:
1190 err = -1; 1211 err = -1;
@@ -1222,8 +1243,9 @@ static int run_sendmsg_test_case(const struct sock_addr_test *test)
1222 if (clientfd >= 0) 1243 if (clientfd >= 0)
1223 close(clientfd); 1244 close(clientfd);
1224 1245
1225 clientfd = sendmsg_to_server(&requested_addr, addr_len, 1246 clientfd = sendmsg_to_server(test->type, &requested_addr,
1226 set_cmsg, &err); 1247 addr_len, set_cmsg, /*flags*/0,
1248 &err);
1227 if (err) 1249 if (err)
1228 goto out; 1250 goto out;
1229 else if (clientfd == -1) 1251 else if (clientfd == -1)
diff --git a/tools/testing/selftests/bpf/test_socket_cookie.c b/tools/testing/selftests/bpf/test_socket_cookie.c
new file mode 100644
index 000000000000..68e108e4687a
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_socket_cookie.c
@@ -0,0 +1,225 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2018 Facebook
3
4#include <string.h>
5#include <unistd.h>
6
7#include <arpa/inet.h>
8#include <netinet/in.h>
9#include <sys/types.h>
10#include <sys/socket.h>
11
12#include <bpf/bpf.h>
13#include <bpf/libbpf.h>
14
15#include "bpf_rlimit.h"
16#include "cgroup_helpers.h"
17
18#define CG_PATH "/foo"
19#define SOCKET_COOKIE_PROG "./socket_cookie_prog.o"
20
21static int start_server(void)
22{
23 struct sockaddr_in6 addr;
24 int fd;
25
26 fd = socket(AF_INET6, SOCK_STREAM, 0);
27 if (fd == -1) {
28 log_err("Failed to create server socket");
29 goto out;
30 }
31
32 memset(&addr, 0, sizeof(addr));
33 addr.sin6_family = AF_INET6;
34 addr.sin6_addr = in6addr_loopback;
35 addr.sin6_port = 0;
36
37 if (bind(fd, (const struct sockaddr *)&addr, sizeof(addr)) == -1) {
38 log_err("Failed to bind server socket");
39 goto close_out;
40 }
41
42 if (listen(fd, 128) == -1) {
43 log_err("Failed to listen on server socket");
44 goto close_out;
45 }
46
47 goto out;
48
49close_out:
50 close(fd);
51 fd = -1;
52out:
53 return fd;
54}
55
56static int connect_to_server(int server_fd)
57{
58 struct sockaddr_storage addr;
59 socklen_t len = sizeof(addr);
60 int fd;
61
62 fd = socket(AF_INET6, SOCK_STREAM, 0);
63 if (fd == -1) {
64 log_err("Failed to create client socket");
65 goto out;
66 }
67
68 if (getsockname(server_fd, (struct sockaddr *)&addr, &len)) {
69 log_err("Failed to get server addr");
70 goto close_out;
71 }
72
73 if (connect(fd, (const struct sockaddr *)&addr, len) == -1) {
74 log_err("Fail to connect to server");
75 goto close_out;
76 }
77
78 goto out;
79
80close_out:
81 close(fd);
82 fd = -1;
83out:
84 return fd;
85}
86
87static int validate_map(struct bpf_map *map, int client_fd)
88{
89 __u32 cookie_expected_value;
90 struct sockaddr_in6 addr;
91 socklen_t len = sizeof(addr);
92 __u32 cookie_value;
93 __u64 cookie_key;
94 int err = 0;
95 int map_fd;
96
97 if (!map) {
98 log_err("Map not found in BPF object");
99 goto err;
100 }
101
102 map_fd = bpf_map__fd(map);
103
104 err = bpf_map_get_next_key(map_fd, NULL, &cookie_key);
105 if (err) {
106 log_err("Can't get cookie key from map");
107 goto out;
108 }
109
110 err = bpf_map_lookup_elem(map_fd, &cookie_key, &cookie_value);
111 if (err) {
112 log_err("Can't get cookie value from map");
113 goto out;
114 }
115
116 err = getsockname(client_fd, (struct sockaddr *)&addr, &len);
117 if (err) {
118 log_err("Can't get client local addr");
119 goto out;
120 }
121
122 cookie_expected_value = (ntohs(addr.sin6_port) << 8) | 0xFF;
123 if (cookie_value != cookie_expected_value) {
124 log_err("Unexpected value in map: %x != %x", cookie_value,
125 cookie_expected_value);
126 goto err;
127 }
128
129 goto out;
130err:
131 err = -1;
132out:
133 return err;
134}
135
136static int run_test(int cgfd)
137{
138 enum bpf_attach_type attach_type;
139 struct bpf_prog_load_attr attr;
140 struct bpf_program *prog;
141 struct bpf_object *pobj;
142 const char *prog_name;
143 int server_fd = -1;
144 int client_fd = -1;
145 int prog_fd = -1;
146 int err = 0;
147
148 memset(&attr, 0, sizeof(attr));
149 attr.file = SOCKET_COOKIE_PROG;
150 attr.prog_type = BPF_PROG_TYPE_UNSPEC;
151
152 err = bpf_prog_load_xattr(&attr, &pobj, &prog_fd);
153 if (err) {
154 log_err("Failed to load %s", attr.file);
155 goto out;
156 }
157
158 bpf_object__for_each_program(prog, pobj) {
159 prog_name = bpf_program__title(prog, /*needs_copy*/ false);
160
161 if (strcmp(prog_name, "cgroup/connect6") == 0) {
162 attach_type = BPF_CGROUP_INET6_CONNECT;
163 } else if (strcmp(prog_name, "sockops") == 0) {
164 attach_type = BPF_CGROUP_SOCK_OPS;
165 } else {
166 log_err("Unexpected prog: %s", prog_name);
167 goto err;
168 }
169
170 err = bpf_prog_attach(bpf_program__fd(prog), cgfd, attach_type,
171 BPF_F_ALLOW_OVERRIDE);
172 if (err) {
173 log_err("Failed to attach prog %s", prog_name);
174 goto out;
175 }
176 }
177
178 server_fd = start_server();
179 if (server_fd == -1)
180 goto err;
181
182 client_fd = connect_to_server(server_fd);
183 if (client_fd == -1)
184 goto err;
185
186 if (validate_map(bpf_map__next(NULL, pobj), client_fd))
187 goto err;
188
189 goto out;
190err:
191 err = -1;
192out:
193 close(client_fd);
194 close(server_fd);
195 bpf_object__close(pobj);
196 printf("%s\n", err ? "FAILED" : "PASSED");
197 return err;
198}
199
200int main(int argc, char **argv)
201{
202 int cgfd = -1;
203 int err = 0;
204
205 if (setup_cgroup_environment())
206 goto err;
207
208 cgfd = create_and_get_cgroup(CG_PATH);
209 if (!cgfd)
210 goto err;
211
212 if (join_cgroup(CG_PATH))
213 goto err;
214
215 if (run_test(cgfd))
216 goto err;
217
218 goto out;
219err:
220 err = -1;
221out:
222 close(cgfd);
223 cleanup_cgroup_environment();
224 return err;
225}
diff --git a/tools/testing/selftests/bpf/test_tcpbpf.h b/tools/testing/selftests/bpf/test_tcpbpf.h
index 2fe43289943c..7bcfa6207005 100644
--- a/tools/testing/selftests/bpf/test_tcpbpf.h
+++ b/tools/testing/selftests/bpf/test_tcpbpf.h
@@ -12,5 +12,6 @@ struct tcpbpf_globals {
12 __u32 good_cb_test_rv; 12 __u32 good_cb_test_rv;
13 __u64 bytes_received; 13 __u64 bytes_received;
14 __u64 bytes_acked; 14 __u64 bytes_acked;
15 __u32 num_listen;
15}; 16};
16#endif 17#endif
diff --git a/tools/testing/selftests/bpf/test_tcpbpf_kern.c b/tools/testing/selftests/bpf/test_tcpbpf_kern.c
index 3e645ee41ed5..4b7fd540cea9 100644
--- a/tools/testing/selftests/bpf/test_tcpbpf_kern.c
+++ b/tools/testing/selftests/bpf/test_tcpbpf_kern.c
@@ -96,15 +96,22 @@ int bpf_testcb(struct bpf_sock_ops *skops)
96 if (!gp) 96 if (!gp)
97 break; 97 break;
98 g = *gp; 98 g = *gp;
99 g.total_retrans = skops->total_retrans; 99 if (skops->args[0] == BPF_TCP_LISTEN) {
100 g.data_segs_in = skops->data_segs_in; 100 g.num_listen++;
101 g.data_segs_out = skops->data_segs_out; 101 } else {
102 g.bytes_received = skops->bytes_received; 102 g.total_retrans = skops->total_retrans;
103 g.bytes_acked = skops->bytes_acked; 103 g.data_segs_in = skops->data_segs_in;
104 g.data_segs_out = skops->data_segs_out;
105 g.bytes_received = skops->bytes_received;
106 g.bytes_acked = skops->bytes_acked;
107 }
104 bpf_map_update_elem(&global_map, &key, &g, 108 bpf_map_update_elem(&global_map, &key, &g,
105 BPF_ANY); 109 BPF_ANY);
106 } 110 }
107 break; 111 break;
112 case BPF_SOCK_OPS_TCP_LISTEN_CB:
113 bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_STATE_CB_FLAG);
114 break;
108 default: 115 default:
109 rv = -1; 116 rv = -1;
110 } 117 }
diff --git a/tools/testing/selftests/bpf/test_tcpbpf_user.c b/tools/testing/selftests/bpf/test_tcpbpf_user.c
index 84ab5163c828..a275c2971376 100644
--- a/tools/testing/selftests/bpf/test_tcpbpf_user.c
+++ b/tools/testing/selftests/bpf/test_tcpbpf_user.c
@@ -1,27 +1,59 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include <inttypes.h>
2#include <stdio.h> 3#include <stdio.h>
3#include <stdlib.h> 4#include <stdlib.h>
4#include <stdio.h>
5#include <unistd.h> 5#include <unistd.h>
6#include <errno.h> 6#include <errno.h>
7#include <signal.h>
8#include <string.h> 7#include <string.h>
9#include <assert.h>
10#include <linux/perf_event.h>
11#include <linux/ptrace.h>
12#include <linux/bpf.h> 8#include <linux/bpf.h>
13#include <sys/ioctl.h>
14#include <sys/time.h>
15#include <sys/types.h> 9#include <sys/types.h>
16#include <sys/stat.h>
17#include <fcntl.h>
18#include <bpf/bpf.h> 10#include <bpf/bpf.h>
19#include <bpf/libbpf.h> 11#include <bpf/libbpf.h>
20#include "bpf_util.h" 12
21#include "bpf_rlimit.h" 13#include "bpf_rlimit.h"
22#include <linux/perf_event.h> 14#include "bpf_util.h"
15#include "cgroup_helpers.h"
16
23#include "test_tcpbpf.h" 17#include "test_tcpbpf.h"
24 18
19#define EXPECT_EQ(expected, actual, fmt) \
20 do { \
21 if ((expected) != (actual)) { \
22 printf(" Value of: " #actual "\n" \
23 " Actual: %" fmt "\n" \
24 " Expected: %" fmt "\n", \
25 (actual), (expected)); \
26 goto err; \
27 } \
28 } while (0)
29
30int verify_result(const struct tcpbpf_globals *result)
31{
32 __u32 expected_events;
33
34 expected_events = ((1 << BPF_SOCK_OPS_TIMEOUT_INIT) |
35 (1 << BPF_SOCK_OPS_RWND_INIT) |
36 (1 << BPF_SOCK_OPS_TCP_CONNECT_CB) |
37 (1 << BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB) |
38 (1 << BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB) |
39 (1 << BPF_SOCK_OPS_NEEDS_ECN) |
40 (1 << BPF_SOCK_OPS_STATE_CB) |
41 (1 << BPF_SOCK_OPS_TCP_LISTEN_CB));
42
43 EXPECT_EQ(expected_events, result->event_map, "#" PRIx32);
44 EXPECT_EQ(501ULL, result->bytes_received, "llu");
45 EXPECT_EQ(1002ULL, result->bytes_acked, "llu");
46 EXPECT_EQ(1, result->data_segs_in, PRIu32);
47 EXPECT_EQ(1, result->data_segs_out, PRIu32);
48 EXPECT_EQ(0x80, result->bad_cb_test_rv, PRIu32);
49 EXPECT_EQ(0, result->good_cb_test_rv, PRIu32);
50 EXPECT_EQ(1, result->num_listen, PRIu32);
51
52 return 0;
53err:
54 return -1;
55}
56
25static int bpf_find_map(const char *test, struct bpf_object *obj, 57static int bpf_find_map(const char *test, struct bpf_object *obj,
26 const char *name) 58 const char *name)
27{ 59{
@@ -35,42 +67,28 @@ static int bpf_find_map(const char *test, struct bpf_object *obj,
35 return bpf_map__fd(map); 67 return bpf_map__fd(map);
36} 68}
37 69
38#define SYSTEM(CMD) \
39 do { \
40 if (system(CMD)) { \
41 printf("system(%s) FAILS!\n", CMD); \
42 } \
43 } while (0)
44
45int main(int argc, char **argv) 70int main(int argc, char **argv)
46{ 71{
47 const char *file = "test_tcpbpf_kern.o"; 72 const char *file = "test_tcpbpf_kern.o";
48 struct tcpbpf_globals g = {0}; 73 struct tcpbpf_globals g = {0};
49 int cg_fd, prog_fd, map_fd; 74 const char *cg_path = "/foo";
50 bool debug_flag = false;
51 int error = EXIT_FAILURE; 75 int error = EXIT_FAILURE;
52 struct bpf_object *obj; 76 struct bpf_object *obj;
53 char cmd[100], *dir; 77 int prog_fd, map_fd;
54 struct stat buffer; 78 int cg_fd = -1;
55 __u32 key = 0; 79 __u32 key = 0;
56 int pid;
57 int rv; 80 int rv;
58 81
59 if (argc > 1 && strcmp(argv[1], "-d") == 0) 82 if (setup_cgroup_environment())
60 debug_flag = true; 83 goto err;
61 84
62 dir = "/tmp/cgroupv2/foo"; 85 cg_fd = create_and_get_cgroup(cg_path);
86 if (!cg_fd)
87 goto err;
63 88
64 if (stat(dir, &buffer) != 0) { 89 if (join_cgroup(cg_path))
65 SYSTEM("mkdir -p /tmp/cgroupv2"); 90 goto err;
66 SYSTEM("mount -t cgroup2 none /tmp/cgroupv2");
67 SYSTEM("mkdir -p /tmp/cgroupv2/foo");
68 }
69 pid = (int) getpid();
70 sprintf(cmd, "echo %d >> /tmp/cgroupv2/foo/cgroup.procs", pid);
71 SYSTEM(cmd);
72 91
73 cg_fd = open(dir, O_DIRECTORY, O_RDONLY);
74 if (bpf_prog_load(file, BPF_PROG_TYPE_SOCK_OPS, &obj, &prog_fd)) { 92 if (bpf_prog_load(file, BPF_PROG_TYPE_SOCK_OPS, &obj, &prog_fd)) {
75 printf("FAILED: load_bpf_file failed for: %s\n", file); 93 printf("FAILED: load_bpf_file failed for: %s\n", file);
76 goto err; 94 goto err;
@@ -83,7 +101,10 @@ int main(int argc, char **argv)
83 goto err; 101 goto err;
84 } 102 }
85 103
86 SYSTEM("./tcp_server.py"); 104 if (system("./tcp_server.py")) {
105 printf("FAILED: TCP server\n");
106 goto err;
107 }
87 108
88 map_fd = bpf_find_map(__func__, obj, "global_map"); 109 map_fd = bpf_find_map(__func__, obj, "global_map");
89 if (map_fd < 0) 110 if (map_fd < 0)
@@ -95,34 +116,16 @@ int main(int argc, char **argv)
95 goto err; 116 goto err;
96 } 117 }
97 118
98 if (g.bytes_received != 501 || g.bytes_acked != 1002 || 119 if (verify_result(&g)) {
99 g.data_segs_in != 1 || g.data_segs_out != 1 ||
100 (g.event_map ^ 0x47e) != 0 || g.bad_cb_test_rv != 0x80 ||
101 g.good_cb_test_rv != 0) {
102 printf("FAILED: Wrong stats\n"); 120 printf("FAILED: Wrong stats\n");
103 if (debug_flag) {
104 printf("\n");
105 printf("bytes_received: %d (expecting 501)\n",
106 (int)g.bytes_received);
107 printf("bytes_acked: %d (expecting 1002)\n",
108 (int)g.bytes_acked);
109 printf("data_segs_in: %d (expecting 1)\n",
110 g.data_segs_in);
111 printf("data_segs_out: %d (expecting 1)\n",
112 g.data_segs_out);
113 printf("event_map: 0x%x (at least 0x47e)\n",
114 g.event_map);
115 printf("bad_cb_test_rv: 0x%x (expecting 0x80)\n",
116 g.bad_cb_test_rv);
117 printf("good_cb_test_rv:0x%x (expecting 0)\n",
118 g.good_cb_test_rv);
119 }
120 goto err; 121 goto err;
121 } 122 }
123
122 printf("PASSED!\n"); 124 printf("PASSED!\n");
123 error = 0; 125 error = 0;
124err: 126err:
125 bpf_prog_detach(cg_fd, BPF_CGROUP_SOCK_OPS); 127 bpf_prog_detach(cg_fd, BPF_CGROUP_SOCK_OPS);
128 close(cg_fd);
129 cleanup_cgroup_environment();
126 return error; 130 return error;
127
128} 131}
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
index 41106d9d5cc7..67c412d19c09 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -42,15 +42,12 @@
42#endif 42#endif
43#include "bpf_rlimit.h" 43#include "bpf_rlimit.h"
44#include "bpf_rand.h" 44#include "bpf_rand.h"
45#include "bpf_util.h"
45#include "../../../include/linux/filter.h" 46#include "../../../include/linux/filter.h"
46 47
47#ifndef ARRAY_SIZE
48# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
49#endif
50
51#define MAX_INSNS BPF_MAXINSNS 48#define MAX_INSNS BPF_MAXINSNS
52#define MAX_FIXUPS 8 49#define MAX_FIXUPS 8
53#define MAX_NR_MAPS 7 50#define MAX_NR_MAPS 8
54#define POINTER_VALUE 0xcafe4all 51#define POINTER_VALUE 0xcafe4all
55#define TEST_DATA_LEN 64 52#define TEST_DATA_LEN 64
56 53
@@ -70,6 +67,7 @@ struct bpf_test {
70 int fixup_prog1[MAX_FIXUPS]; 67 int fixup_prog1[MAX_FIXUPS];
71 int fixup_prog2[MAX_FIXUPS]; 68 int fixup_prog2[MAX_FIXUPS];
72 int fixup_map_in_map[MAX_FIXUPS]; 69 int fixup_map_in_map[MAX_FIXUPS];
70 int fixup_cgroup_storage[MAX_FIXUPS];
73 const char *errstr; 71 const char *errstr;
74 const char *errstr_unpriv; 72 const char *errstr_unpriv;
75 uint32_t retval; 73 uint32_t retval;
@@ -4631,6 +4629,121 @@ static struct bpf_test tests[] = {
4631 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 4629 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
4632 }, 4630 },
4633 { 4631 {
4632 "valid cgroup storage access",
4633 .insns = {
4634 BPF_MOV64_IMM(BPF_REG_2, 0),
4635 BPF_LD_MAP_FD(BPF_REG_1, 0),
4636 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4637 BPF_FUNC_get_local_storage),
4638 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4639 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4640 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
4641 BPF_EXIT_INSN(),
4642 },
4643 .fixup_cgroup_storage = { 1 },
4644 .result = ACCEPT,
4645 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4646 },
4647 {
4648 "invalid cgroup storage access 1",
4649 .insns = {
4650 BPF_MOV64_IMM(BPF_REG_2, 0),
4651 BPF_LD_MAP_FD(BPF_REG_1, 0),
4652 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4653 BPF_FUNC_get_local_storage),
4654 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4655 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4656 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
4657 BPF_EXIT_INSN(),
4658 },
4659 .fixup_map1 = { 1 },
4660 .result = REJECT,
4661 .errstr = "cannot pass map_type 1 into func bpf_get_local_storage",
4662 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4663 },
4664 {
4665 "invalid cgroup storage access 2",
4666 .insns = {
4667 BPF_MOV64_IMM(BPF_REG_2, 0),
4668 BPF_LD_MAP_FD(BPF_REG_1, 1),
4669 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4670 BPF_FUNC_get_local_storage),
4671 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
4672 BPF_EXIT_INSN(),
4673 },
4674 .result = REJECT,
4675 .errstr = "fd 1 is not pointing to valid bpf_map",
4676 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4677 },
4678 {
4679 "invalid per-cgroup storage access 3",
4680 .insns = {
4681 BPF_MOV64_IMM(BPF_REG_2, 0),
4682 BPF_LD_MAP_FD(BPF_REG_1, 0),
4683 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4684 BPF_FUNC_get_local_storage),
4685 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 256),
4686 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
4687 BPF_MOV64_IMM(BPF_REG_0, 0),
4688 BPF_EXIT_INSN(),
4689 },
4690 .fixup_cgroup_storage = { 1 },
4691 .result = REJECT,
4692 .errstr = "invalid access to map value, value_size=64 off=256 size=4",
4693 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4694 },
4695 {
4696 "invalid cgroup storage access 4",
4697 .insns = {
4698 BPF_MOV64_IMM(BPF_REG_2, 0),
4699 BPF_LD_MAP_FD(BPF_REG_1, 0),
4700 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4701 BPF_FUNC_get_local_storage),
4702 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, -2),
4703 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4704 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
4705 BPF_EXIT_INSN(),
4706 },
4707 .fixup_cgroup_storage = { 1 },
4708 .result = REJECT,
4709 .errstr = "invalid access to map value, value_size=64 off=-2 size=4",
4710 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4711 },
4712 {
4713 "invalid cgroup storage access 5",
4714 .insns = {
4715 BPF_MOV64_IMM(BPF_REG_2, 7),
4716 BPF_LD_MAP_FD(BPF_REG_1, 0),
4717 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4718 BPF_FUNC_get_local_storage),
4719 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4720 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4721 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
4722 BPF_EXIT_INSN(),
4723 },
4724 .fixup_cgroup_storage = { 1 },
4725 .result = REJECT,
4726 .errstr = "get_local_storage() doesn't support non-zero flags",
4727 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4728 },
4729 {
4730 "invalid cgroup storage access 6",
4731 .insns = {
4732 BPF_MOV64_REG(BPF_REG_2, BPF_REG_1),
4733 BPF_LD_MAP_FD(BPF_REG_1, 0),
4734 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4735 BPF_FUNC_get_local_storage),
4736 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4737 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4738 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
4739 BPF_EXIT_INSN(),
4740 },
4741 .fixup_cgroup_storage = { 1 },
4742 .result = REJECT,
4743 .errstr = "get_local_storage() doesn't support non-zero flags",
4744 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
4745 },
4746 {
4634 "multiple registers share map_lookup_elem result", 4747 "multiple registers share map_lookup_elem result",
4635 .insns = { 4748 .insns = {
4636 BPF_MOV64_IMM(BPF_REG_1, 10), 4749 BPF_MOV64_IMM(BPF_REG_1, 10),
@@ -6997,7 +7110,7 @@ static struct bpf_test tests[] = {
6997 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 7110 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
6998 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 7111 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
6999 BPF_FUNC_map_lookup_elem), 7112 BPF_FUNC_map_lookup_elem),
7000 BPF_MOV64_REG(BPF_REG_0, 0), 7113 BPF_MOV64_IMM(BPF_REG_0, 0),
7001 BPF_EXIT_INSN(), 7114 BPF_EXIT_INSN(),
7002 }, 7115 },
7003 .fixup_map_in_map = { 3 }, 7116 .fixup_map_in_map = { 3 },
@@ -7020,7 +7133,7 @@ static struct bpf_test tests[] = {
7020 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 7133 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
7021 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 7134 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7022 BPF_FUNC_map_lookup_elem), 7135 BPF_FUNC_map_lookup_elem),
7023 BPF_MOV64_REG(BPF_REG_0, 0), 7136 BPF_MOV64_IMM(BPF_REG_0, 0),
7024 BPF_EXIT_INSN(), 7137 BPF_EXIT_INSN(),
7025 }, 7138 },
7026 .fixup_map_in_map = { 3 }, 7139 .fixup_map_in_map = { 3 },
@@ -7042,7 +7155,7 @@ static struct bpf_test tests[] = {
7042 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 7155 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
7043 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 7156 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
7044 BPF_FUNC_map_lookup_elem), 7157 BPF_FUNC_map_lookup_elem),
7045 BPF_MOV64_REG(BPF_REG_0, 0), 7158 BPF_MOV64_IMM(BPF_REG_0, 0),
7046 BPF_EXIT_INSN(), 7159 BPF_EXIT_INSN(),
7047 }, 7160 },
7048 .fixup_map_in_map = { 3 }, 7161 .fixup_map_in_map = { 3 },
@@ -12372,6 +12485,32 @@ static struct bpf_test tests[] = {
12372 .result = REJECT, 12485 .result = REJECT,
12373 .errstr = "variable ctx access var_off=(0x0; 0x4)", 12486 .errstr = "variable ctx access var_off=(0x0; 0x4)",
12374 }, 12487 },
12488 {
12489 "mov64 src == dst",
12490 .insns = {
12491 BPF_MOV64_IMM(BPF_REG_2, 0),
12492 BPF_MOV64_REG(BPF_REG_2, BPF_REG_2),
12493 // Check bounds are OK
12494 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
12495 BPF_MOV64_IMM(BPF_REG_0, 0),
12496 BPF_EXIT_INSN(),
12497 },
12498 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12499 .result = ACCEPT,
12500 },
12501 {
12502 "mov64 src != dst",
12503 .insns = {
12504 BPF_MOV64_IMM(BPF_REG_3, 0),
12505 BPF_MOV64_REG(BPF_REG_2, BPF_REG_3),
12506 // Check bounds are OK
12507 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
12508 BPF_MOV64_IMM(BPF_REG_0, 0),
12509 BPF_EXIT_INSN(),
12510 },
12511 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
12512 .result = ACCEPT,
12513 },
12375}; 12514};
12376 12515
12377static int probe_filter_length(const struct bpf_insn *fp) 12516static int probe_filter_length(const struct bpf_insn *fp)
@@ -12476,6 +12615,19 @@ static int create_map_in_map(void)
12476 return outer_map_fd; 12615 return outer_map_fd;
12477} 12616}
12478 12617
12618static int create_cgroup_storage(void)
12619{
12620 int fd;
12621
12622 fd = bpf_create_map(BPF_MAP_TYPE_CGROUP_STORAGE,
12623 sizeof(struct bpf_cgroup_storage_key),
12624 TEST_DATA_LEN, 0, 0);
12625 if (fd < 0)
12626 printf("Failed to create array '%s'!\n", strerror(errno));
12627
12628 return fd;
12629}
12630
12479static char bpf_vlog[UINT_MAX >> 8]; 12631static char bpf_vlog[UINT_MAX >> 8];
12480 12632
12481static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog, 12633static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
@@ -12488,6 +12640,7 @@ static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
12488 int *fixup_prog1 = test->fixup_prog1; 12640 int *fixup_prog1 = test->fixup_prog1;
12489 int *fixup_prog2 = test->fixup_prog2; 12641 int *fixup_prog2 = test->fixup_prog2;
12490 int *fixup_map_in_map = test->fixup_map_in_map; 12642 int *fixup_map_in_map = test->fixup_map_in_map;
12643 int *fixup_cgroup_storage = test->fixup_cgroup_storage;
12491 12644
12492 if (test->fill_helper) 12645 if (test->fill_helper)
12493 test->fill_helper(test); 12646 test->fill_helper(test);
@@ -12555,6 +12708,14 @@ static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
12555 fixup_map_in_map++; 12708 fixup_map_in_map++;
12556 } while (*fixup_map_in_map); 12709 } while (*fixup_map_in_map);
12557 } 12710 }
12711
12712 if (*fixup_cgroup_storage) {
12713 map_fds[7] = create_cgroup_storage();
12714 do {
12715 prog[*fixup_cgroup_storage].imm = map_fds[7];
12716 fixup_cgroup_storage++;
12717 } while (*fixup_cgroup_storage);
12718 }
12558} 12719}
12559 12720
12560static void do_test_single(struct bpf_test *test, bool unpriv, 12721static void do_test_single(struct bpf_test *test, bool unpriv,
diff --git a/tools/testing/selftests/bpf/trace_helpers.c b/tools/testing/selftests/bpf/trace_helpers.c
index 3868dcb63420..cabe2a3a3b30 100644
--- a/tools/testing/selftests/bpf/trace_helpers.c
+++ b/tools/testing/selftests/bpf/trace_helpers.c
@@ -88,7 +88,7 @@ static int page_size;
88static int page_cnt = 8; 88static int page_cnt = 8;
89static struct perf_event_mmap_page *header; 89static struct perf_event_mmap_page *header;
90 90
91int perf_event_mmap(int fd) 91int perf_event_mmap_header(int fd, struct perf_event_mmap_page **header)
92{ 92{
93 void *base; 93 void *base;
94 int mmap_size; 94 int mmap_size;
@@ -102,10 +102,15 @@ int perf_event_mmap(int fd)
102 return -1; 102 return -1;
103 } 103 }
104 104
105 header = base; 105 *header = base;
106 return 0; 106 return 0;
107} 107}
108 108
109int perf_event_mmap(int fd)
110{
111 return perf_event_mmap_header(fd, &header);
112}
113
109static int perf_event_poll(int fd) 114static int perf_event_poll(int fd)
110{ 115{
111 struct pollfd pfd = { .fd = fd, .events = POLLIN }; 116 struct pollfd pfd = { .fd = fd, .events = POLLIN };
@@ -163,3 +168,42 @@ int perf_event_poller(int fd, perf_event_print_fn output_fn)
163 168
164 return ret; 169 return ret;
165} 170}
171
172int perf_event_poller_multi(int *fds, struct perf_event_mmap_page **headers,
173 int num_fds, perf_event_print_fn output_fn)
174{
175 enum bpf_perf_event_ret ret;
176 struct pollfd *pfds;
177 void *buf = NULL;
178 size_t len = 0;
179 int i;
180
181 pfds = calloc(num_fds, sizeof(*pfds));
182 if (!pfds)
183 return LIBBPF_PERF_EVENT_ERROR;
184
185 for (i = 0; i < num_fds; i++) {
186 pfds[i].fd = fds[i];
187 pfds[i].events = POLLIN;
188 }
189
190 for (;;) {
191 poll(pfds, num_fds, 1000);
192 for (i = 0; i < num_fds; i++) {
193 if (!pfds[i].revents)
194 continue;
195
196 ret = bpf_perf_event_read_simple(headers[i],
197 page_cnt * page_size,
198 page_size, &buf, &len,
199 bpf_perf_event_print,
200 output_fn);
201 if (ret != LIBBPF_PERF_EVENT_CONT)
202 break;
203 }
204 }
205 free(buf);
206 free(pfds);
207
208 return ret;
209}
diff --git a/tools/testing/selftests/bpf/trace_helpers.h b/tools/testing/selftests/bpf/trace_helpers.h
index 3b4bcf7f5084..18924f23db1b 100644
--- a/tools/testing/selftests/bpf/trace_helpers.h
+++ b/tools/testing/selftests/bpf/trace_helpers.h
@@ -3,6 +3,7 @@
3#define __TRACE_HELPER_H 3#define __TRACE_HELPER_H
4 4
5#include <libbpf.h> 5#include <libbpf.h>
6#include <linux/perf_event.h>
6 7
7struct ksym { 8struct ksym {
8 long addr; 9 long addr;
@@ -16,6 +17,9 @@ long ksym_get_addr(const char *name);
16typedef enum bpf_perf_event_ret (*perf_event_print_fn)(void *data, int size); 17typedef enum bpf_perf_event_ret (*perf_event_print_fn)(void *data, int size);
17 18
18int perf_event_mmap(int fd); 19int perf_event_mmap(int fd);
20int perf_event_mmap_header(int fd, struct perf_event_mmap_page **header);
19/* return LIBBPF_PERF_EVENT_DONE or LIBBPF_PERF_EVENT_ERROR */ 21/* return LIBBPF_PERF_EVENT_DONE or LIBBPF_PERF_EVENT_ERROR */
20int perf_event_poller(int fd, perf_event_print_fn output_fn); 22int perf_event_poller(int fd, perf_event_print_fn output_fn);
23int perf_event_poller_multi(int *fds, struct perf_event_mmap_page **headers,
24 int num_fds, perf_event_print_fn output_fn);
21#endif 25#endif
diff --git a/tools/testing/selftests/drivers/net/mlxsw/mirror_gre.sh b/tools/testing/selftests/drivers/net/mlxsw/mirror_gre.sh
new file mode 100755
index 000000000000..76f1ab4898d9
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/mlxsw/mirror_gre.sh
@@ -0,0 +1,217 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# This test uses standard topology for testing gretap. See
5# ../../../net/forwarding/mirror_gre_topo_lib.sh for more details.
6#
7# Test offloading various features of offloading gretap mirrors specific to
8# mlxsw.
9
10lib_dir=$(dirname $0)/../../../net/forwarding
11
12NUM_NETIFS=6
13source $lib_dir/lib.sh
14source $lib_dir/mirror_lib.sh
15source $lib_dir/mirror_gre_lib.sh
16source $lib_dir/mirror_gre_topo_lib.sh
17
18setup_keyful()
19{
20 tunnel_create gt6-key ip6gretap 2001:db8:3::1 2001:db8:3::2 \
21 ttl 100 tos inherit allow-localremote \
22 key 1234
23
24 tunnel_create h3-gt6-key ip6gretap 2001:db8:3::2 2001:db8:3::1 \
25 key 1234
26 ip link set h3-gt6-key vrf v$h3
27 matchall_sink_create h3-gt6-key
28
29 ip address add dev $swp3 2001:db8:3::1/64
30 ip address add dev $h3 2001:db8:3::2/64
31}
32
33cleanup_keyful()
34{
35 ip address del dev $h3 2001:db8:3::2/64
36 ip address del dev $swp3 2001:db8:3::1/64
37
38 tunnel_destroy h3-gt6-key
39 tunnel_destroy gt6-key
40}
41
42setup_soft()
43{
44 # Set up a topology for testing underlay routes that point at an
45 # unsupported soft device.
46
47 tunnel_create gt6-soft ip6gretap 2001:db8:4::1 2001:db8:4::2 \
48 ttl 100 tos inherit allow-localremote
49
50 tunnel_create h3-gt6-soft ip6gretap 2001:db8:4::2 2001:db8:4::1
51 ip link set h3-gt6-soft vrf v$h3
52 matchall_sink_create h3-gt6-soft
53
54 ip link add name v1 type veth peer name v2
55 ip link set dev v1 up
56 ip address add dev v1 2001:db8:4::1/64
57
58 ip link set dev v2 vrf v$h3
59 ip link set dev v2 up
60 ip address add dev v2 2001:db8:4::2/64
61}
62
63cleanup_soft()
64{
65 ip link del dev v1
66
67 tunnel_destroy h3-gt6-soft
68 tunnel_destroy gt6-soft
69}
70
71setup_prepare()
72{
73 h1=${NETIFS[p1]}
74 swp1=${NETIFS[p2]}
75
76 swp2=${NETIFS[p3]}
77 h2=${NETIFS[p4]}
78
79 swp3=${NETIFS[p5]}
80 h3=${NETIFS[p6]}
81
82 vrf_prepare
83 mirror_gre_topo_create
84
85 ip address add dev $swp3 2001:db8:2::1/64
86 ip address add dev $h3 2001:db8:2::2/64
87
88 ip address add dev $swp3 192.0.2.129/28
89 ip address add dev $h3 192.0.2.130/28
90
91 setup_keyful
92 setup_soft
93}
94
95cleanup()
96{
97 pre_cleanup
98
99 cleanup_soft
100 cleanup_keyful
101
102 ip address del dev $h3 2001:db8:2::2/64
103 ip address del dev $swp3 2001:db8:2::1/64
104
105 ip address del dev $h3 192.0.2.130/28
106 ip address del dev $swp3 192.0.2.129/28
107
108 mirror_gre_topo_destroy
109 vrf_cleanup
110}
111
112test_span_gre_ttl_inherit()
113{
114 local tundev=$1; shift
115 local type=$1; shift
116 local what=$1; shift
117
118 RET=0
119
120 ip link set dev $tundev type $type ttl inherit
121 mirror_install $swp1 ingress $tundev "matchall $tcflags"
122 fail_test_span_gre_dir $tundev ingress
123
124 ip link set dev $tundev type $type ttl 100
125
126 quick_test_span_gre_dir $tundev ingress
127 mirror_uninstall $swp1 ingress
128
129 log_test "$what: no offload on TTL of inherit ($tcflags)"
130}
131
132test_span_gre_tos_fixed()
133{
134 local tundev=$1; shift
135 local type=$1; shift
136 local what=$1; shift
137
138 RET=0
139
140 ip link set dev $tundev type $type tos 0x10
141 mirror_install $swp1 ingress $tundev "matchall $tcflags"
142 fail_test_span_gre_dir $tundev ingress
143
144 ip link set dev $tundev type $type tos inherit
145 quick_test_span_gre_dir $tundev ingress
146 mirror_uninstall $swp1 ingress
147
148 log_test "$what: no offload on a fixed TOS ($tcflags)"
149}
150
151test_span_failable()
152{
153 local should_fail=$1; shift
154 local tundev=$1; shift
155 local what=$1; shift
156
157 RET=0
158
159 mirror_install $swp1 ingress $tundev "matchall $tcflags"
160 if ((should_fail)); then
161 fail_test_span_gre_dir $tundev ingress
162 else
163 quick_test_span_gre_dir $tundev ingress
164 fi
165 mirror_uninstall $swp1 ingress
166
167 log_test "$what: should_fail=$should_fail ($tcflags)"
168}
169
170test_failable()
171{
172 local should_fail=$1; shift
173
174 test_span_failable $should_fail gt6-key "mirror to keyful gretap"
175 test_span_failable $should_fail gt6-soft "mirror to gretap w/ soft underlay"
176}
177
178test_sw()
179{
180 slow_path_trap_install $swp1 ingress
181 slow_path_trap_install $swp1 egress
182
183 test_failable 0
184
185 slow_path_trap_uninstall $swp1 egress
186 slow_path_trap_uninstall $swp1 ingress
187}
188
189test_hw()
190{
191 test_failable 1
192
193 test_span_gre_tos_fixed gt4 gretap "mirror to gretap"
194 test_span_gre_tos_fixed gt6 ip6gretap "mirror to ip6gretap"
195
196 test_span_gre_ttl_inherit gt4 gretap "mirror to gretap"
197 test_span_gre_ttl_inherit gt6 ip6gretap "mirror to ip6gretap"
198}
199
200trap cleanup EXIT
201
202setup_prepare
203setup_wait
204
205if ! tc_offload_check; then
206 check_err 1 "Could not test offloaded functionality"
207 log_test "mlxsw-specific tests for mirror to gretap"
208 exit
209fi
210
211tcflags="skip_hw"
212test_sw
213
214tcflags="skip_sw"
215test_hw
216
217exit $EXIT_STATUS
diff --git a/tools/testing/selftests/drivers/net/mlxsw/mirror_gre_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/mirror_gre_scale.sh
new file mode 100644
index 000000000000..6f3a70df63bc
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/mlxsw/mirror_gre_scale.sh
@@ -0,0 +1,197 @@
1# SPDX-License-Identifier: GPL-2.0
2
3# Test offloading a number of mirrors-to-gretap. The test creates a number of
4# tunnels. Then it adds one flower mirror for each of the tunnels, matching a
5# given host IP. Then it generates traffic at each of the host IPs and checks
6# that the traffic has been mirrored at the appropriate tunnel.
7#
8# +--------------------------+ +--------------------------+
9# | H1 | | H2 |
10# | + $h1 | | $h2 + |
11# | | 2001:db8:1:X::1/64 | | 2001:db8:1:X::2/64 | |
12# +-----|--------------------+ +--------------------|-----+
13# | |
14# +-----|-------------------------------------------------------------|-----+
15# | SW o--> mirrors | |
16# | +---|-------------------------------------------------------------|---+ |
17# | | + $swp1 BR $swp2 + | |
18# | +---------------------------------------------------------------------+ |
19# | |
20# | + $swp3 + gt6-<X> (ip6gretap) |
21# | | 2001:db8:2:X::1/64 : loc=2001:db8:2:X::1 |
22# | | : rem=2001:db8:2:X::2 |
23# | | : ttl=100 |
24# | | : tos=inherit |
25# | | : |
26# +-----|--------------------------------:----------------------------------+
27# | :
28# +-----|--------------------------------:----------------------------------+
29# | H3 + $h3 + h3-gt6-<X> (ip6gretap) |
30# | 2001:db8:2:X::2/64 loc=2001:db8:2:X::2 |
31# | rem=2001:db8:2:X::1 |
32# | ttl=100 |
33# | tos=inherit |
34# | |
35# +-------------------------------------------------------------------------+
36
37source ../../../../net/forwarding/mirror_lib.sh
38
39MIRROR_NUM_NETIFS=6
40
41mirror_gre_ipv6_addr()
42{
43 local net=$1; shift
44 local num=$1; shift
45
46 printf "2001:db8:%x:%x" $net $num
47}
48
49mirror_gre_tunnels_create()
50{
51 local count=$1; shift
52 local should_fail=$1; shift
53
54 MIRROR_GRE_BATCH_FILE="$(mktemp)"
55 for ((i=0; i < count; ++i)); do
56 local match_dip=$(mirror_gre_ipv6_addr 1 $i)::2
57 local htun=h3-gt6-$i
58 local tun=gt6-$i
59
60 ((mirror_gre_tunnels++))
61
62 ip address add dev $h1 $(mirror_gre_ipv6_addr 1 $i)::1/64
63 ip address add dev $h2 $(mirror_gre_ipv6_addr 1 $i)::2/64
64
65 ip address add dev $swp3 $(mirror_gre_ipv6_addr 2 $i)::1/64
66 ip address add dev $h3 $(mirror_gre_ipv6_addr 2 $i)::2/64
67
68 tunnel_create $tun ip6gretap \
69 $(mirror_gre_ipv6_addr 2 $i)::1 \
70 $(mirror_gre_ipv6_addr 2 $i)::2 \
71 ttl 100 tos inherit allow-localremote
72
73 tunnel_create $htun ip6gretap \
74 $(mirror_gre_ipv6_addr 2 $i)::2 \
75 $(mirror_gre_ipv6_addr 2 $i)::1
76 ip link set $htun vrf v$h3
77 matchall_sink_create $htun
78
79 cat >> $MIRROR_GRE_BATCH_FILE <<-EOF
80 filter add dev $swp1 ingress pref 1000 \
81 protocol ipv6 \
82 flower $tcflags dst_ip $match_dip \
83 action mirred egress mirror dev $tun
84 EOF
85 done
86
87 tc -b $MIRROR_GRE_BATCH_FILE
88 check_err_fail $should_fail $? "Mirror rule insertion"
89}
90
91mirror_gre_tunnels_destroy()
92{
93 local count=$1; shift
94
95 for ((i=0; i < count; ++i)); do
96 local htun=h3-gt6-$i
97 local tun=gt6-$i
98
99 ip address del dev $h3 $(mirror_gre_ipv6_addr 2 $i)::2/64
100 ip address del dev $swp3 $(mirror_gre_ipv6_addr 2 $i)::1/64
101
102 ip address del dev $h2 $(mirror_gre_ipv6_addr 1 $i)::2/64
103 ip address del dev $h1 $(mirror_gre_ipv6_addr 1 $i)::1/64
104
105 tunnel_destroy $htun
106 tunnel_destroy $tun
107 done
108}
109
110__mirror_gre_test()
111{
112 local count=$1; shift
113 local should_fail=$1; shift
114
115 mirror_gre_tunnels_create $count $should_fail
116 if ((should_fail)); then
117 return
118 fi
119
120 sleep 5
121
122 for ((i = 0; i < count; ++i)); do
123 local dip=$(mirror_gre_ipv6_addr 1 $i)::2
124 local htun=h3-gt6-$i
125 local message
126
127 icmp6_capture_install $htun
128 mirror_test v$h1 "" $dip $htun 100 10
129 icmp6_capture_uninstall $htun
130 done
131}
132
133mirror_gre_test()
134{
135 local count=$1; shift
136 local should_fail=$1; shift
137
138 if ! tc_offload_check $TC_FLOWER_NUM_NETIFS; then
139 check_err 1 "Could not test offloaded functionality"
140 return
141 fi
142
143 tcflags="skip_sw"
144 __mirror_gre_test $count $should_fail
145}
146
147mirror_gre_setup_prepare()
148{
149 h1=${NETIFS[p1]}
150 swp1=${NETIFS[p2]}
151
152 swp2=${NETIFS[p3]}
153 h2=${NETIFS[p4]}
154
155 swp3=${NETIFS[p5]}
156 h3=${NETIFS[p6]}
157
158 mirror_gre_tunnels=0
159
160 vrf_prepare
161
162 simple_if_init $h1
163 simple_if_init $h2
164 simple_if_init $h3
165
166 ip link add name br1 type bridge vlan_filtering 1
167 ip link set dev br1 up
168
169 ip link set dev $swp1 master br1
170 ip link set dev $swp1 up
171 tc qdisc add dev $swp1 clsact
172
173 ip link set dev $swp2 master br1
174 ip link set dev $swp2 up
175
176 ip link set dev $swp3 up
177}
178
179mirror_gre_cleanup()
180{
181 mirror_gre_tunnels_destroy $mirror_gre_tunnels
182
183 ip link set dev $swp3 down
184
185 ip link set dev $swp2 down
186
187 tc qdisc del dev $swp1 clsact
188 ip link set dev $swp1 down
189
190 ip link del dev br1
191
192 simple_if_fini $h3
193 simple_if_fini $h2
194 simple_if_fini $h1
195
196 vrf_cleanup
197}
diff --git a/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_bridge.sh b/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_bridge.sh
new file mode 100755
index 000000000000..1ca631d5aaba
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_bridge.sh
@@ -0,0 +1,189 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# Test for DSCP prioritization and rewrite. Packets ingress $swp1 with a DSCP
5# tag and are prioritized according to the map at $swp1. They egress $swp2 and
6# the DSCP value is updated to match the map at that interface. The updated DSCP
7# tag is verified at $h2.
8#
9# ICMP responses are produced with the same DSCP tag that arrived at $h2. They
10# go through prioritization at $swp2 and DSCP retagging at $swp1. The tag is
11# verified at $h1--it should match the original tag.
12#
13# +----------------------+ +----------------------+
14# | H1 | | H2 |
15# | + $h1 | | $h2 + |
16# | | 192.0.2.1/28 | | 192.0.2.2/28 | |
17# +----|-----------------+ +----------------|-----+
18# | |
19# +----|----------------------------------------------------------------|-----+
20# | SW | | |
21# | +-|----------------------------------------------------------------|-+ |
22# | | + $swp1 BR $swp2 + | |
23# | | APP=0,5,10 .. 7,5,17 APP=0,5,20 .. 7,5,27 | |
24# | +--------------------------------------------------------------------+ |
25# +---------------------------------------------------------------------------+
26
27ALL_TESTS="
28 ping_ipv4
29 test_dscp
30"
31
32lib_dir=$(dirname $0)/../../../net/forwarding
33
34NUM_NETIFS=4
35source $lib_dir/lib.sh
36
37h1_create()
38{
39 local dscp;
40
41 simple_if_init $h1 192.0.2.1/28
42 tc qdisc add dev $h1 clsact
43 dscp_capture_install $h1 10
44}
45
46h1_destroy()
47{
48 dscp_capture_uninstall $h1 10
49 tc qdisc del dev $h1 clsact
50 simple_if_fini $h1 192.0.2.1/28
51}
52
53h2_create()
54{
55 simple_if_init $h2 192.0.2.2/28
56 tc qdisc add dev $h2 clsact
57 dscp_capture_install $h2 20
58}
59
60h2_destroy()
61{
62 dscp_capture_uninstall $h2 20
63 tc qdisc del dev $h2 clsact
64 simple_if_fini $h2 192.0.2.2/28
65}
66
67dscp_map()
68{
69 local base=$1; shift
70
71 for prio in {0..7}; do
72 echo app=$prio,5,$((base + prio))
73 done
74}
75
76switch_create()
77{
78 ip link add name br1 type bridge vlan_filtering 1
79 ip link set dev br1 up
80 ip link set dev $swp1 master br1
81 ip link set dev $swp1 up
82 ip link set dev $swp2 master br1
83 ip link set dev $swp2 up
84
85 lldptool -T -i $swp1 -V APP $(dscp_map 10) >/dev/null
86 lldptool -T -i $swp2 -V APP $(dscp_map 20) >/dev/null
87 lldpad_app_wait_set $swp1
88 lldpad_app_wait_set $swp2
89}
90
91switch_destroy()
92{
93 lldptool -T -i $swp2 -V APP -d $(dscp_map 20) >/dev/null
94 lldptool -T -i $swp1 -V APP -d $(dscp_map 10) >/dev/null
95 lldpad_app_wait_del
96
97 ip link set dev $swp2 nomaster
98 ip link set dev $swp1 nomaster
99 ip link del dev br1
100}
101
102setup_prepare()
103{
104 h1=${NETIFS[p1]}
105 swp1=${NETIFS[p2]}
106
107 swp2=${NETIFS[p3]}
108 h2=${NETIFS[p4]}
109
110 vrf_prepare
111
112 h1_create
113 h2_create
114 switch_create
115}
116
117cleanup()
118{
119 pre_cleanup
120
121 switch_destroy
122 h2_destroy
123 h1_destroy
124
125 vrf_cleanup
126}
127
128ping_ipv4()
129{
130 ping_test $h1 192.0.2.2
131}
132
133dscp_ping_test()
134{
135 local vrf_name=$1; shift
136 local sip=$1; shift
137 local dip=$1; shift
138 local prio=$1; shift
139 local dev_10=$1; shift
140 local dev_20=$1; shift
141
142 local dscp_10=$(((prio + 10) << 2))
143 local dscp_20=$(((prio + 20) << 2))
144
145 RET=0
146
147 local -A t0s
148 eval "t0s=($(dscp_fetch_stats $dev_10 10)
149 $(dscp_fetch_stats $dev_20 20))"
150
151 ip vrf exec $vrf_name \
152 ${PING} -Q $dscp_10 ${sip:+-I $sip} $dip \
153 -c 10 -i 0.1 -w 2 &> /dev/null
154
155 local -A t1s
156 eval "t1s=($(dscp_fetch_stats $dev_10 10)
157 $(dscp_fetch_stats $dev_20 20))"
158
159 for key in ${!t0s[@]}; do
160 local expect
161 if ((key == prio+10 || key == prio+20)); then
162 expect=10
163 else
164 expect=0
165 fi
166
167 local delta=$((t1s[$key] - t0s[$key]))
168 ((expect == delta))
169 check_err $? "DSCP $key: Expected to capture $expect packets, got $delta."
170 done
171
172 log_test "DSCP rewrite: $dscp_10-(prio $prio)-$dscp_20"
173}
174
175test_dscp()
176{
177 for prio in {0..7}; do
178 dscp_ping_test v$h1 192.0.2.1 192.0.2.2 $prio $h1 $h2
179 done
180}
181
182trap cleanup EXIT
183
184setup_prepare
185setup_wait
186
187tests_run
188
189exit $EXIT_STATUS
diff --git a/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_router.sh b/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_router.sh
new file mode 100755
index 000000000000..281d90766e12
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_router.sh
@@ -0,0 +1,233 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# Test for DSCP prioritization in the router.
5#
6# With ip_forward_update_priority disabled, the packets are expected to keep
7# their DSCP (which in this test uses only values 0..7) intact as they are
8# forwarded by the switch. That is verified at $h2. ICMP responses are formed
9# with the same DSCP as the requests, and likewise pass through the switch
10# intact, which is verified at $h1.
11#
12# With ip_forward_update_priority enabled, router reprioritizes the packets
13# according to the table in reprioritize(). Thus, say, DSCP 7 maps to priority
14# 4, which on egress maps back to DSCP 4. The response packet then gets
15# reprioritized to 6, getting DSCP 6 on egress.
16#
17# +----------------------+ +----------------------+
18# | H1 | | H2 |
19# | + $h1 | | $h2 + |
20# | | 192.0.2.1/28 | | 192.0.2.18/28 | |
21# +----|-----------------+ +----------------|-----+
22# | |
23# +----|----------------------------------------------------------------|-----+
24# | SW | | |
25# | + $swp1 $swp2 + |
26# | 192.0.2.2/28 192.0.2.17/28 |
27# | APP=0,5,0 .. 7,5,7 APP=0,5,0 .. 7,5,7 |
28# +---------------------------------------------------------------------------+
29
30ALL_TESTS="
31 ping_ipv4
32 test_update
33 test_no_update
34"
35
36lib_dir=$(dirname $0)/../../../net/forwarding
37
38NUM_NETIFS=4
39source $lib_dir/lib.sh
40
41reprioritize()
42{
43 local in=$1; shift
44
45 # This is based on rt_tos2priority in include/net/route.h. Assuming 1:1
46 # mapping between priorities and TOS, it yields a new priority for a
47 # packet with ingress priority of $in.
48 local -a reprio=(0 0 2 2 6 6 4 4)
49
50 echo ${reprio[$in]}
51}
52
53h1_create()
54{
55 local dscp;
56
57 simple_if_init $h1 192.0.2.1/28
58 tc qdisc add dev $h1 clsact
59 dscp_capture_install $h1 0
60 ip route add vrf v$h1 192.0.2.16/28 via 192.0.2.2
61}
62
63h1_destroy()
64{
65 ip route del vrf v$h1 192.0.2.16/28 via 192.0.2.2
66 dscp_capture_uninstall $h1 0
67 tc qdisc del dev $h1 clsact
68 simple_if_fini $h1 192.0.2.1/28
69}
70
71h2_create()
72{
73 simple_if_init $h2 192.0.2.18/28
74 tc qdisc add dev $h2 clsact
75 dscp_capture_install $h2 0
76 ip route add vrf v$h2 192.0.2.0/28 via 192.0.2.17
77}
78
79h2_destroy()
80{
81 ip route del vrf v$h2 192.0.2.0/28 via 192.0.2.17
82 dscp_capture_uninstall $h2 0
83 tc qdisc del dev $h2 clsact
84 simple_if_fini $h2 192.0.2.18/28
85}
86
87dscp_map()
88{
89 local base=$1; shift
90
91 for prio in {0..7}; do
92 echo app=$prio,5,$((base + prio))
93 done
94}
95
96switch_create()
97{
98 simple_if_init $swp1 192.0.2.2/28
99 __simple_if_init $swp2 v$swp1 192.0.2.17/28
100
101 lldptool -T -i $swp1 -V APP $(dscp_map 0) >/dev/null
102 lldptool -T -i $swp2 -V APP $(dscp_map 0) >/dev/null
103 lldpad_app_wait_set $swp1
104 lldpad_app_wait_set $swp2
105}
106
107switch_destroy()
108{
109 lldptool -T -i $swp2 -V APP -d $(dscp_map 0) >/dev/null
110 lldptool -T -i $swp1 -V APP -d $(dscp_map 0) >/dev/null
111 lldpad_app_wait_del
112
113 __simple_if_fini $swp2 192.0.2.17/28
114 simple_if_fini $swp1 192.0.2.2/28
115}
116
117setup_prepare()
118{
119 h1=${NETIFS[p1]}
120 swp1=${NETIFS[p2]}
121
122 swp2=${NETIFS[p3]}
123 h2=${NETIFS[p4]}
124
125 vrf_prepare
126
127 sysctl_set net.ipv4.ip_forward_update_priority 1
128 h1_create
129 h2_create
130 switch_create
131}
132
133cleanup()
134{
135 pre_cleanup
136
137 switch_destroy
138 h2_destroy
139 h1_destroy
140 sysctl_restore net.ipv4.ip_forward_update_priority
141
142 vrf_cleanup
143}
144
145ping_ipv4()
146{
147 ping_test $h1 192.0.2.18
148}
149
150dscp_ping_test()
151{
152 local vrf_name=$1; shift
153 local sip=$1; shift
154 local dip=$1; shift
155 local prio=$1; shift
156 local reprio=$1; shift
157 local dev1=$1; shift
158 local dev2=$1; shift
159
160 local prio2=$($reprio $prio) # ICMP Request egress prio
161 local prio3=$($reprio $prio2) # ICMP Response egress prio
162
163 local dscp=$((prio << 2)) # ICMP Request ingress DSCP
164 local dscp2=$((prio2 << 2)) # ICMP Request egress DSCP
165 local dscp3=$((prio3 << 2)) # ICMP Response egress DSCP
166
167 RET=0
168
169 eval "local -A dev1_t0s=($(dscp_fetch_stats $dev1 0))"
170 eval "local -A dev2_t0s=($(dscp_fetch_stats $dev2 0))"
171
172 ip vrf exec $vrf_name \
173 ${PING} -Q $dscp ${sip:+-I $sip} $dip \
174 -c 10 -i 0.1 -w 2 &> /dev/null
175
176 eval "local -A dev1_t1s=($(dscp_fetch_stats $dev1 0))"
177 eval "local -A dev2_t1s=($(dscp_fetch_stats $dev2 0))"
178
179 for i in {0..7}; do
180 local dscpi=$((i << 2))
181 local expect2=0
182 local expect3=0
183
184 if ((i == prio2)); then
185 expect2=10
186 fi
187 if ((i == prio3)); then
188 expect3=10
189 fi
190
191 local delta=$((dev2_t1s[$i] - dev2_t0s[$i]))
192 ((expect2 == delta))
193 check_err $? "DSCP $dscpi@$dev2: Expected to capture $expect2 packets, got $delta."
194
195 delta=$((dev1_t1s[$i] - dev1_t0s[$i]))
196 ((expect3 == delta))
197 check_err $? "DSCP $dscpi@$dev1: Expected to capture $expect3 packets, got $delta."
198 done
199
200 log_test "DSCP rewrite: $dscp-(prio $prio2)-$dscp2-(prio $prio3)-$dscp3"
201}
202
203__test_update()
204{
205 local update=$1; shift
206 local reprio=$1; shift
207
208 sysctl_restore net.ipv4.ip_forward_update_priority
209 sysctl_set net.ipv4.ip_forward_update_priority $update
210
211 for prio in {0..7}; do
212 dscp_ping_test v$h1 192.0.2.1 192.0.2.18 $prio $reprio $h1 $h2
213 done
214}
215
216test_update()
217{
218 __test_update 1 reprioritize
219}
220
221test_no_update()
222{
223 __test_update 0 echo
224}
225
226trap cleanup EXIT
227
228setup_prepare
229setup_wait
230
231tests_run
232
233exit $EXIT_STATUS
diff --git a/tools/testing/selftests/drivers/net/mlxsw/router_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/router_scale.sh
new file mode 100644
index 000000000000..d231649b4f01
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/mlxsw/router_scale.sh
@@ -0,0 +1,167 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4ROUTER_NUM_NETIFS=4
5
6router_h1_create()
7{
8 simple_if_init $h1 192.0.1.1/24
9 ip route add 193.0.0.0/8 via 192.0.1.2 dev $h1
10}
11
12router_h1_destroy()
13{
14 ip route del 193.0.0.0/8 via 192.0.1.2 dev $h1
15 simple_if_fini $h1 192.0.1.1/24
16}
17
18router_h2_create()
19{
20 simple_if_init $h2 192.0.2.1/24
21 tc qdisc add dev $h2 handle ffff: ingress
22}
23
24router_h2_destroy()
25{
26 tc qdisc del dev $h2 handle ffff: ingress
27 simple_if_fini $h2 192.0.2.1/24
28}
29
30router_create()
31{
32 ip link set dev $rp1 up
33 ip link set dev $rp2 up
34
35 ip address add 192.0.1.2/24 dev $rp1
36 ip address add 192.0.2.2/24 dev $rp2
37}
38
39router_destroy()
40{
41 ip address del 192.0.2.2/24 dev $rp2
42 ip address del 192.0.1.2/24 dev $rp1
43
44 ip link set dev $rp2 down
45 ip link set dev $rp1 down
46}
47
48router_setup_prepare()
49{
50 h1=${NETIFS[p1]}
51 rp1=${NETIFS[p2]}
52
53 rp2=${NETIFS[p3]}
54 h2=${NETIFS[p4]}
55
56 h1mac=$(mac_get $h1)
57 rp1mac=$(mac_get $rp1)
58
59 vrf_prepare
60
61 router_h1_create
62 router_h2_create
63
64 router_create
65}
66
67router_offload_validate()
68{
69 local route_count=$1
70 local offloaded_count
71
72 offloaded_count=$(ip route | grep -o 'offload' | wc -l)
73 [[ $offloaded_count -ge $route_count ]]
74}
75
76router_routes_create()
77{
78 local route_count=$1
79 local count=0
80
81 ROUTE_FILE="$(mktemp)"
82
83 for i in {0..255}
84 do
85 for j in {0..255}
86 do
87 for k in {0..255}
88 do
89 if [[ $count -eq $route_count ]]; then
90 break 3
91 fi
92
93 echo route add 193.${i}.${j}.${k}/32 via \
94 192.0.2.1 dev $rp2 >> $ROUTE_FILE
95 ((count++))
96 done
97 done
98 done
99
100 ip -b $ROUTE_FILE &> /dev/null
101}
102
103router_routes_destroy()
104{
105 if [[ -v ROUTE_FILE ]]; then
106 rm -f $ROUTE_FILE
107 fi
108}
109
110router_test()
111{
112 local route_count=$1
113 local should_fail=$2
114 local count=0
115
116 RET=0
117
118 router_routes_create $route_count
119
120 router_offload_validate $route_count
121 check_err_fail $should_fail $? "Offload of $route_count routes"
122 if [[ $RET -ne 0 ]] || [[ $should_fail -eq 1 ]]; then
123 return
124 fi
125
126 tc filter add dev $h2 ingress protocol ip pref 1 flower \
127 skip_sw dst_ip 193.0.0.0/8 action drop
128
129 for i in {0..255}
130 do
131 for j in {0..255}
132 do
133 for k in {0..255}
134 do
135 if [[ $count -eq $route_count ]]; then
136 break 3
137 fi
138
139 $MZ $h1 -c 1 -p 64 -a $h1mac -b $rp1mac \
140 -A 192.0.1.1 -B 193.${i}.${j}.${k} \
141 -t ip -q
142 ((count++))
143 done
144 done
145 done
146
147 tc_check_packets "dev $h2 ingress" 1 $route_count
148 check_err $? "Offload mismatch"
149
150 tc filter del dev $h2 ingress protocol ip pref 1 flower \
151 skip_sw dst_ip 193.0.0.0/8 action drop
152
153 router_routes_destroy
154}
155
156router_cleanup()
157{
158 pre_cleanup
159
160 router_routes_destroy
161 router_destroy
162
163 router_h2_destroy
164 router_h1_destroy
165
166 vrf_cleanup
167}
diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh
new file mode 100755
index 000000000000..3b75180f455d
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh
@@ -0,0 +1,366 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# This test is for checking the A-TCAM and C-TCAM operation in Spectrum-2.
5# It tries to exercise as many code paths in the eRP state machine as
6# possible.
7
8lib_dir=$(dirname $0)/../../../../net/forwarding
9
10ALL_TESTS="single_mask_test identical_filters_test two_masks_test \
11 multiple_masks_test ctcam_edge_cases_test"
12NUM_NETIFS=2
13source $lib_dir/tc_common.sh
14source $lib_dir/lib.sh
15
16tcflags="skip_hw"
17
18h1_create()
19{
20 simple_if_init $h1 192.0.2.1/24 198.51.100.1/24
21}
22
23h1_destroy()
24{
25 simple_if_fini $h1 192.0.2.1/24 198.51.100.1/24
26}
27
28h2_create()
29{
30 simple_if_init $h2 192.0.2.2/24 198.51.100.2/24
31 tc qdisc add dev $h2 clsact
32}
33
34h2_destroy()
35{
36 tc qdisc del dev $h2 clsact
37 simple_if_fini $h2 192.0.2.2/24 198.51.100.2/24
38}
39
40single_mask_test()
41{
42 # When only a single mask is required, the device uses the master
43 # mask and not the eRP table. Verify that under this mode the right
44 # filter is matched
45
46 RET=0
47
48 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
49 $tcflags dst_ip 192.0.2.2 action drop
50
51 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
52 -t ip -q
53
54 tc_check_packets "dev $h2 ingress" 101 1
55 check_err $? "Single filter - did not match"
56
57 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \
58 $tcflags dst_ip 198.51.100.2 action drop
59
60 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
61 -t ip -q
62
63 tc_check_packets "dev $h2 ingress" 101 2
64 check_err $? "Two filters - did not match highest priority"
65
66 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 198.51.100.1 -B 198.51.100.2 \
67 -t ip -q
68
69 tc_check_packets "dev $h2 ingress" 102 1
70 check_err $? "Two filters - did not match lowest priority"
71
72 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
73
74 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 198.51.100.1 -B 198.51.100.2 \
75 -t ip -q
76
77 tc_check_packets "dev $h2 ingress" 102 2
78 check_err $? "Single filter - did not match after delete"
79
80 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
81
82 log_test "single mask test ($tcflags)"
83}
84
85identical_filters_test()
86{
87 # When two filters that only differ in their priority are used,
88 # one needs to be inserted into the C-TCAM. This test verifies
89 # that filters are correctly spilled to C-TCAM and that the right
90 # filter is matched
91
92 RET=0
93
94 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
95 $tcflags dst_ip 192.0.2.2 action drop
96 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \
97 $tcflags dst_ip 192.0.2.2 action drop
98
99 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
100 -t ip -q
101
102 tc_check_packets "dev $h2 ingress" 101 1
103 check_err $? "Did not match A-TCAM filter"
104
105 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
106
107 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
108 -t ip -q
109
110 tc_check_packets "dev $h2 ingress" 102 1
111 check_err $? "Did not match C-TCAM filter after A-TCAM delete"
112
113 tc filter add dev $h2 ingress protocol ip pref 3 handle 103 flower \
114 $tcflags dst_ip 192.0.2.2 action drop
115
116 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
117 -t ip -q
118
119 tc_check_packets "dev $h2 ingress" 102 2
120 check_err $? "Did not match C-TCAM filter after A-TCAM add"
121
122 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
123
124 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
125 -t ip -q
126
127 tc_check_packets "dev $h2 ingress" 103 1
128 check_err $? "Did not match A-TCAM filter after C-TCAM delete"
129
130 tc filter del dev $h2 ingress protocol ip pref 3 handle 103 flower
131
132 log_test "identical filters test ($tcflags)"
133}
134
135two_masks_test()
136{
137 # When more than one mask is required, the eRP table is used. This
138 # test verifies that the eRP table is correctly allocated and used
139
140 RET=0
141
142 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
143 $tcflags dst_ip 192.0.2.2 action drop
144 tc filter add dev $h2 ingress protocol ip pref 3 handle 103 flower \
145 $tcflags dst_ip 192.0.0.0/16 action drop
146
147 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
148 -t ip -q
149
150 tc_check_packets "dev $h2 ingress" 101 1
151 check_err $? "Two filters - did not match highest priority"
152
153 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
154
155 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
156 -t ip -q
157
158 tc_check_packets "dev $h2 ingress" 103 1
159 check_err $? "Single filter - did not match"
160
161 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \
162 $tcflags dst_ip 192.0.2.0/24 action drop
163
164 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
165 -t ip -q
166
167 tc_check_packets "dev $h2 ingress" 102 1
168 check_err $? "Two filters - did not match highest priority after add"
169
170 tc filter del dev $h2 ingress protocol ip pref 3 handle 103 flower
171 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
172
173 log_test "two masks test ($tcflags)"
174}
175
176multiple_masks_test()
177{
178 # The number of masks in a region is limited. Once the maximum
179 # number of masks has been reached filters that require new
180 # masks are spilled to the C-TCAM. This test verifies that
181 # spillage is performed correctly and that the right filter is
182 # matched
183
184 local index
185
186 RET=0
187
188 NUM_MASKS=32
189 BASE_INDEX=100
190
191 for i in $(eval echo {1..$NUM_MASKS}); do
192 index=$((BASE_INDEX - i))
193
194 tc filter add dev $h2 ingress protocol ip pref $index \
195 handle $index \
196 flower $tcflags dst_ip 192.0.2.2/${i} src_ip 192.0.2.1 \
197 action drop
198
199 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 \
200 -B 192.0.2.2 -t ip -q
201
202 tc_check_packets "dev $h2 ingress" $index 1
203 check_err $? "$i filters - did not match highest priority (add)"
204 done
205
206 for i in $(eval echo {$NUM_MASKS..1}); do
207 index=$((BASE_INDEX - i))
208
209 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 \
210 -B 192.0.2.2 -t ip -q
211
212 tc_check_packets "dev $h2 ingress" $index 2
213 check_err $? "$i filters - did not match highest priority (del)"
214
215 tc filter del dev $h2 ingress protocol ip pref $index \
216 handle $index flower
217 done
218
219 log_test "multiple masks test ($tcflags)"
220}
221
222ctcam_two_atcam_masks_test()
223{
224 RET=0
225
226 # First case: C-TCAM is disabled when there are two A-TCAM masks.
227 # We push a filter into the C-TCAM by using two identical filters
228 # as in identical_filters_test()
229
230 # Filter goes into A-TCAM
231 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
232 $tcflags dst_ip 192.0.2.2 action drop
233 # Filter goes into C-TCAM
234 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \
235 $tcflags dst_ip 192.0.2.2 action drop
236 # Filter goes into A-TCAM
237 tc filter add dev $h2 ingress protocol ip pref 3 handle 103 flower \
238 $tcflags dst_ip 192.0.2.0/24 action drop
239
240 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
241 -t ip -q
242
243 tc_check_packets "dev $h2 ingress" 101 1
244 check_err $? "Did not match A-TCAM filter"
245
246 # Delete both A-TCAM and C-TCAM filters and make sure the remaining
247 # A-TCAM filter still works
248 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
249 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
250
251 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
252 -t ip -q
253
254 tc_check_packets "dev $h2 ingress" 103 1
255 check_err $? "Did not match A-TCAM filter"
256
257 tc filter del dev $h2 ingress protocol ip pref 3 handle 103 flower
258
259 log_test "ctcam with two atcam masks test ($tcflags)"
260}
261
262ctcam_one_atcam_mask_test()
263{
264 RET=0
265
266 # Second case: C-TCAM is disabled when there is one A-TCAM mask.
267 # The test is similar to identical_filters_test()
268
269 # Filter goes into A-TCAM
270 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \
271 $tcflags dst_ip 192.0.2.2 action drop
272 # Filter goes into C-TCAM
273 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
274 $tcflags dst_ip 192.0.2.2 action drop
275
276 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
277 -t ip -q
278
279 tc_check_packets "dev $h2 ingress" 101 1
280 check_err $? "Did not match C-TCAM filter"
281
282 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
283
284 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
285 -t ip -q
286
287 tc_check_packets "dev $h2 ingress" 102 1
288 check_err $? "Did not match A-TCAM filter"
289
290 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
291
292 log_test "ctcam with one atcam mask test ($tcflags)"
293}
294
295ctcam_no_atcam_masks_test()
296{
297 RET=0
298
299 # Third case: C-TCAM is disabled when there are no A-TCAM masks
300 # This test exercises the code path that transitions the eRP table
301 # to its initial state after deleting the last C-TCAM mask
302
303 # Filter goes into A-TCAM
304 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
305 $tcflags dst_ip 192.0.2.2 action drop
306 # Filter goes into C-TCAM
307 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \
308 $tcflags dst_ip 192.0.2.2 action drop
309
310 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
311 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
312
313 log_test "ctcam with no atcam masks test ($tcflags)"
314}
315
316ctcam_edge_cases_test()
317{
318 # When the C-TCAM is disabled after deleting the last C-TCAM
319 # mask, we want to make sure the eRP state machine is put in
320 # the correct state
321
322 ctcam_two_atcam_masks_test
323 ctcam_one_atcam_mask_test
324 ctcam_no_atcam_masks_test
325}
326
327setup_prepare()
328{
329 h1=${NETIFS[p1]}
330 h2=${NETIFS[p2]}
331 h1mac=$(mac_get $h1)
332 h2mac=$(mac_get $h2)
333
334 vrf_prepare
335
336 h1_create
337 h2_create
338}
339
340cleanup()
341{
342 pre_cleanup
343
344 h2_destroy
345 h1_destroy
346
347 vrf_cleanup
348}
349
350trap cleanup EXIT
351
352setup_prepare
353setup_wait
354
355tests_run
356
357if ! tc_offload_check; then
358 check_err 1 "Could not test offloaded functionality"
359 log_test "mlxsw-specific tests for tc flower"
360 exit
361else
362 tcflags="skip_sw"
363 tests_run
364fi
365
366exit $EXIT_STATUS
diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum/devlink_lib_spectrum.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum/devlink_lib_spectrum.sh
new file mode 100644
index 000000000000..73035e25085d
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum/devlink_lib_spectrum.sh
@@ -0,0 +1,119 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4source "../../../../net/forwarding/devlink_lib.sh"
5
6if [ "$DEVLINK_VIDDID" != "15b3:cb84" ]; then
7 echo "SKIP: test is tailored for Mellanox Spectrum"
8 exit 1
9fi
10
11# Needed for returning to default
12declare -A KVD_DEFAULTS
13
14KVD_CHILDREN="linear hash_single hash_double"
15KVDL_CHILDREN="singles chunks large_chunks"
16
17devlink_sp_resource_minimize()
18{
19 local size
20 local i
21
22 for i in $KVD_CHILDREN; do
23 size=$(devlink_resource_get kvd "$i" | jq '.["size_min"]')
24 devlink_resource_size_set "$size" kvd "$i"
25 done
26
27 for i in $KVDL_CHILDREN; do
28 size=$(devlink_resource_get kvd linear "$i" | \
29 jq '.["size_min"]')
30 devlink_resource_size_set "$size" kvd linear "$i"
31 done
32}
33
34devlink_sp_size_kvd_to_default()
35{
36 local need_reload=0
37 local i
38
39 for i in $KVD_CHILDREN; do
40 local size=$(echo "${KVD_DEFAULTS[kvd_$i]}" | jq '.["size"]')
41 current_size=$(devlink_resource_size_get kvd "$i")
42
43 if [ "$size" -ne "$current_size" ]; then
44 devlink_resource_size_set "$size" kvd "$i"
45 need_reload=1
46 fi
47 done
48
49 for i in $KVDL_CHILDREN; do
50 local size=$(echo "${KVD_DEFAULTS[kvd_linear_$i]}" | \
51 jq '.["size"]')
52 current_size=$(devlink_resource_size_get kvd linear "$i")
53
54 if [ "$size" -ne "$current_size" ]; then
55 devlink_resource_size_set "$size" kvd linear "$i"
56 need_reload=1
57 fi
58 done
59
60 if [ "$need_reload" -ne "0" ]; then
61 devlink_reload
62 fi
63}
64
65devlink_sp_read_kvd_defaults()
66{
67 local key
68 local i
69
70 KVD_DEFAULTS[kvd]=$(devlink_resource_get "kvd")
71 for i in $KVD_CHILDREN; do
72 key=kvd_$i
73 KVD_DEFAULTS[$key]=$(devlink_resource_get kvd "$i")
74 done
75
76 for i in $KVDL_CHILDREN; do
77 key=kvd_linear_$i
78 KVD_DEFAULTS[$key]=$(devlink_resource_get kvd linear "$i")
79 done
80}
81
82KVD_PROFILES="default scale ipv4_max"
83
84devlink_sp_resource_kvd_profile_set()
85{
86 local profile=$1
87
88 case "$profile" in
89 scale)
90 devlink_resource_size_set 64000 kvd linear
91 devlink_resource_size_set 15616 kvd linear singles
92 devlink_resource_size_set 32000 kvd linear chunks
93 devlink_resource_size_set 16384 kvd linear large_chunks
94 devlink_resource_size_set 128000 kvd hash_single
95 devlink_resource_size_set 48000 kvd hash_double
96 devlink_reload
97 ;;
98 ipv4_max)
99 devlink_resource_size_set 64000 kvd linear
100 devlink_resource_size_set 15616 kvd linear singles
101 devlink_resource_size_set 32000 kvd linear chunks
102 devlink_resource_size_set 16384 kvd linear large_chunks
103 devlink_resource_size_set 144000 kvd hash_single
104 devlink_resource_size_set 32768 kvd hash_double
105 devlink_reload
106 ;;
107 default)
108 devlink_resource_size_set 98304 kvd linear
109 devlink_resource_size_set 16384 kvd linear singles
110 devlink_resource_size_set 49152 kvd linear chunks
111 devlink_resource_size_set 32768 kvd linear large_chunks
112 devlink_resource_size_set 87040 kvd hash_single
113 devlink_resource_size_set 60416 kvd hash_double
114 devlink_reload
115 ;;
116 *)
117 check_err 1 "Unknown profile $profile"
118 esac
119}
diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum/devlink_resources.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum/devlink_resources.sh
new file mode 100755
index 000000000000..b1fe960e398a
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum/devlink_resources.sh
@@ -0,0 +1,117 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4NUM_NETIFS=1
5source devlink_lib_spectrum.sh
6
7setup_prepare()
8{
9 devlink_sp_read_kvd_defaults
10}
11
12cleanup()
13{
14 pre_cleanup
15 devlink_sp_size_kvd_to_default
16}
17
18trap cleanup EXIT
19
20setup_prepare
21
22profiles_test()
23{
24 local i
25
26 log_info "Running profile tests"
27
28 for i in $KVD_PROFILES; do
29 RET=0
30 devlink_sp_resource_kvd_profile_set $i
31 log_test "'$i' profile"
32 done
33
34 # Default is explicitly tested at end to ensure it's actually applied
35 RET=0
36 devlink_sp_resource_kvd_profile_set "default"
37 log_test "'default' profile"
38}
39
40resources_min_test()
41{
42 local size
43 local i
44 local j
45
46 log_info "Running KVD-minimum tests"
47
48 for i in $KVD_CHILDREN; do
49 RET=0
50 size=$(devlink_resource_get kvd "$i" | jq '.["size_min"]')
51 devlink_resource_size_set "$size" kvd "$i"
52
53 # In case of linear, need to minimize sub-resources as well
54 if [[ "$i" == "linear" ]]; then
55 for j in $KVDL_CHILDREN; do
56 devlink_resource_size_set 0 kvd linear "$j"
57 done
58 fi
59
60 devlink_reload
61 devlink_sp_size_kvd_to_default
62 log_test "'$i' minimize [$size]"
63 done
64}
65
66resources_max_test()
67{
68 local min_size
69 local size
70 local i
71 local j
72
73 log_info "Running KVD-maximum tests"
74 for i in $KVD_CHILDREN; do
75 RET=0
76 devlink_sp_resource_minimize
77
78 # Calculate the maximum possible size for the given partition
79 size=$(devlink_resource_size_get kvd)
80 for j in $KVD_CHILDREN; do
81 if [ "$i" != "$j" ]; then
82 min_size=$(devlink_resource_get kvd "$j" | \
83 jq '.["size_min"]')
84 size=$((size - min_size))
85 fi
86 done
87
88 # Test almost maximum size
89 devlink_resource_size_set "$((size - 128))" kvd "$i"
90 devlink_reload
91 log_test "'$i' almost maximize [$((size - 128))]"
92
93 # Test above maximum size
94 devlink resource set "$DEVLINK_DEV" \
95 path "kvd/$i" size $((size + 128)) &> /dev/null
96 check_fail $? "Set kvd/$i to size $((size + 128)) should fail"
97 log_test "'$i' Overflow rejection [$((size + 128))]"
98
99 # Test maximum size
100 if [ "$i" == "hash_single" ] || [ "$i" == "hash_double" ]; then
101 echo "SKIP: Observed problem with exact max $i"
102 continue
103 fi
104
105 devlink_resource_size_set "$size" kvd "$i"
106 devlink_reload
107 log_test "'$i' maximize [$size]"
108
109 devlink_sp_size_kvd_to_default
110 done
111}
112
113profiles_test
114resources_min_test
115resources_max_test
116
117exit "$RET"
diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum/mirror_gre_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum/mirror_gre_scale.sh
new file mode 100644
index 000000000000..8d2186c7c62b
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum/mirror_gre_scale.sh
@@ -0,0 +1,13 @@
1# SPDX-License-Identifier: GPL-2.0
2source ../mirror_gre_scale.sh
3
4mirror_gre_get_target()
5{
6 local should_fail=$1; shift
7
8 if ((! should_fail)); then
9 echo 3
10 else
11 echo 4
12 fi
13}
diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum/resource_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum/resource_scale.sh
new file mode 100755
index 000000000000..a0a80e1a69e8
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum/resource_scale.sh
@@ -0,0 +1,55 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4NUM_NETIFS=6
5source ../../../../net/forwarding/lib.sh
6source ../../../../net/forwarding/tc_common.sh
7source devlink_lib_spectrum.sh
8
9current_test=""
10
11cleanup()
12{
13 pre_cleanup
14 if [ ! -z $current_test ]; then
15 ${current_test}_cleanup
16 fi
17 devlink_sp_size_kvd_to_default
18}
19
20devlink_sp_read_kvd_defaults
21trap cleanup EXIT
22
23ALL_TESTS="router tc_flower mirror_gre"
24for current_test in ${TESTS:-$ALL_TESTS}; do
25 source ${current_test}_scale.sh
26
27 num_netifs_var=${current_test^^}_NUM_NETIFS
28 num_netifs=${!num_netifs_var:-$NUM_NETIFS}
29
30 for profile in $KVD_PROFILES; do
31 RET=0
32 devlink_sp_resource_kvd_profile_set $profile
33 if [[ $RET -gt 0 ]]; then
34 log_test "'$current_test' [$profile] setting"
35 continue
36 fi
37
38 for should_fail in 0 1; do
39 RET=0
40 target=$(${current_test}_get_target "$should_fail")
41 ${current_test}_setup_prepare
42 setup_wait $num_netifs
43 ${current_test}_test "$target" "$should_fail"
44 ${current_test}_cleanup
45 if [[ "$should_fail" -eq 0 ]]; then
46 log_test "'$current_test' [$profile] $target"
47 else
48 log_test "'$current_test' [$profile] overflow $target"
49 fi
50 done
51 done
52done
53current_test=""
54
55exit "$RET"
diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum/router_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum/router_scale.sh
new file mode 100644
index 000000000000..21c4697d5bab
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum/router_scale.sh
@@ -0,0 +1,18 @@
1# SPDX-License-Identifier: GPL-2.0
2source ../router_scale.sh
3
4router_get_target()
5{
6 local should_fail=$1
7 local target
8
9 target=$(devlink_resource_size_get kvd hash_single)
10
11 if [[ $should_fail -eq 0 ]]; then
12 target=$((target * 85 / 100))
13 else
14 target=$((target + 1))
15 fi
16
17 echo $target
18}
diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum/tc_flower_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum/tc_flower_scale.sh
new file mode 100644
index 000000000000..f9bfd8937765
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum/tc_flower_scale.sh
@@ -0,0 +1,19 @@
1# SPDX-License-Identifier: GPL-2.0
2source ../tc_flower_scale.sh
3
4tc_flower_get_target()
5{
6 local should_fail=$1; shift
7
8 # 6144 (6x1024) is the theoretical maximum.
9 # One bank of 512 rules is taken by the 18-byte MC router rule.
10 # One rule is the ACL catch-all.
11 # 6144 - 512 - 1 = 5631
12 local target=5631
13
14 if ((! should_fail)); then
15 echo $target
16 else
17 echo $((target + 1))
18 fi
19}
diff --git a/tools/testing/selftests/drivers/net/mlxsw/tc_flower_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/tc_flower_scale.sh
new file mode 100644
index 000000000000..a6d733d2a4b4
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/mlxsw/tc_flower_scale.sh
@@ -0,0 +1,134 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# Test for resource limit of offloaded flower rules. The test adds a given
5# number of flower matches for different IPv6 addresses, then generates traffic,
6# and ensures each was hit exactly once. This file contains functions to set up
7# a testing topology and run the test, and is meant to be sourced from a test
8# script that calls the testing routine with a given number of rules.
9
10TC_FLOWER_NUM_NETIFS=2
11
12tc_flower_h1_create()
13{
14 simple_if_init $h1
15 tc qdisc add dev $h1 clsact
16}
17
18tc_flower_h1_destroy()
19{
20 tc qdisc del dev $h1 clsact
21 simple_if_fini $h1
22}
23
24tc_flower_h2_create()
25{
26 simple_if_init $h2
27 tc qdisc add dev $h2 clsact
28}
29
30tc_flower_h2_destroy()
31{
32 tc qdisc del dev $h2 clsact
33 simple_if_fini $h2
34}
35
36tc_flower_setup_prepare()
37{
38 h1=${NETIFS[p1]}
39 h2=${NETIFS[p2]}
40
41 vrf_prepare
42
43 tc_flower_h1_create
44 tc_flower_h2_create
45}
46
47tc_flower_cleanup()
48{
49 pre_cleanup
50
51 tc_flower_h2_destroy
52 tc_flower_h1_destroy
53
54 vrf_cleanup
55
56 if [[ -v TC_FLOWER_BATCH_FILE ]]; then
57 rm -f $TC_FLOWER_BATCH_FILE
58 fi
59}
60
61tc_flower_addr()
62{
63 local num=$1; shift
64
65 printf "2001:db8:1::%x" $num
66}
67
68tc_flower_rules_create()
69{
70 local count=$1; shift
71 local should_fail=$1; shift
72
73 TC_FLOWER_BATCH_FILE="$(mktemp)"
74
75 for ((i = 0; i < count; ++i)); do
76 cat >> $TC_FLOWER_BATCH_FILE <<-EOF
77 filter add dev $h2 ingress \
78 prot ipv6 \
79 pref 1000 \
80 flower $tcflags dst_ip $(tc_flower_addr $i) \
81 action drop
82 EOF
83 done
84
85 tc -b $TC_FLOWER_BATCH_FILE
86 check_err_fail $should_fail $? "Rule insertion"
87}
88
89__tc_flower_test()
90{
91 local count=$1; shift
92 local should_fail=$1; shift
93 local last=$((count - 1))
94
95 tc_flower_rules_create $count $should_fail
96
97 for ((i = 0; i < count; ++i)); do
98 $MZ $h1 -q -c 1 -t ip -p 20 -b bc -6 \
99 -A 2001:db8:2::1 \
100 -B $(tc_flower_addr $i)
101 done
102
103 MISMATCHES=$(
104 tc -j -s filter show dev $h2 ingress |
105 jq -r '[ .[] | select(.kind == "flower") | .options |
106 values as $rule | .actions[].stats.packets |
107 select(. != 1) | "\(.) on \($rule.keys.dst_ip)" ] |
108 join(", ")'
109 )
110
111 test -z "$MISMATCHES"
112 check_err $? "Expected to capture 1 packet for each IP, but got $MISMATCHES"
113}
114
115tc_flower_test()
116{
117 local count=$1; shift
118 local should_fail=$1; shift
119
120 # We use lower 16 bits of IPv6 address for match. Also there are only 16
121 # bits of rule priority space.
122 if ((count > 65536)); then
123 check_err 1 "Invalid count of $count. At most 65536 rules supported"
124 return
125 fi
126
127 if ! tc_offload_check $TC_FLOWER_NUM_NETIFS; then
128 check_err 1 "Could not test offloaded functionality"
129 return
130 fi
131
132 tcflags="skip_sw"
133 __tc_flower_test $count $should_fail
134}
diff --git a/tools/testing/selftests/gpio/gpio-mockup-chardev.c b/tools/testing/selftests/gpio/gpio-mockup-chardev.c
index 667e916fa7cc..f8d468f54e98 100644
--- a/tools/testing/selftests/gpio/gpio-mockup-chardev.c
+++ b/tools/testing/selftests/gpio/gpio-mockup-chardev.c
@@ -225,10 +225,10 @@ int gpio_pin_test(struct gpiochip_info *cinfo, int line, int flag, int value)
225 if (flag & GPIOHANDLE_REQUEST_ACTIVE_LOW) 225 if (flag & GPIOHANDLE_REQUEST_ACTIVE_LOW)
226 debugfs_value = !debugfs_value; 226 debugfs_value = !debugfs_value;
227 227
228 if (!(debugfs_dir == OUT && value == debugfs_value)) 228 if (!(debugfs_dir == OUT && value == debugfs_value)) {
229 errno = -EINVAL; 229 errno = -EINVAL;
230 ret = -errno; 230 ret = -errno;
231 231 }
232 } 232 }
233 gpiotools_release_linehandle(fd); 233 gpiotools_release_linehandle(fd);
234 234
diff --git a/tools/testing/selftests/net/.gitignore b/tools/testing/selftests/net/.gitignore
index 1a0ac3a29ec5..78b24cf76f40 100644
--- a/tools/testing/selftests/net/.gitignore
+++ b/tools/testing/selftests/net/.gitignore
@@ -13,3 +13,4 @@ udpgso
13udpgso_bench_rx 13udpgso_bench_rx
14udpgso_bench_tx 14udpgso_bench_tx
15tcp_inq 15tcp_inq
16tls
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
index 663e11e85727..9cca68e440a0 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -13,7 +13,7 @@ TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy
13TEST_GEN_FILES += tcp_mmap tcp_inq psock_snd 13TEST_GEN_FILES += tcp_mmap tcp_inq psock_snd
14TEST_GEN_FILES += udpgso udpgso_bench_tx udpgso_bench_rx 14TEST_GEN_FILES += udpgso udpgso_bench_tx udpgso_bench_rx
15TEST_GEN_PROGS = reuseport_bpf reuseport_bpf_cpu reuseport_bpf_numa 15TEST_GEN_PROGS = reuseport_bpf reuseport_bpf_cpu reuseport_bpf_numa
16TEST_GEN_PROGS += reuseport_dualstack reuseaddr_conflict 16TEST_GEN_PROGS += reuseport_dualstack reuseaddr_conflict tls
17 17
18include ../lib.mk 18include ../lib.mk
19 19
diff --git a/tools/testing/selftests/net/forwarding/README b/tools/testing/selftests/net/forwarding/README
index 4a0964c42860..b8a2af8fcfb7 100644
--- a/tools/testing/selftests/net/forwarding/README
+++ b/tools/testing/selftests/net/forwarding/README
@@ -46,6 +46,8 @@ Guidelines for Writing Tests
46 46
47o Where possible, reuse an existing topology for different tests instead 47o Where possible, reuse an existing topology for different tests instead
48 of recreating the same topology. 48 of recreating the same topology.
49o Tests that use anything but the most trivial topologies should include
50 an ASCII art showing the topology.
49o Where possible, IPv6 and IPv4 addresses shall conform to RFC 3849 and 51o Where possible, IPv6 and IPv4 addresses shall conform to RFC 3849 and
50 RFC 5737, respectively. 52 RFC 5737, respectively.
51o Where possible, tests shall be written so that they can be reused by 53o Where possible, tests shall be written so that they can be reused by
diff --git a/tools/testing/selftests/net/forwarding/bridge_port_isolation.sh b/tools/testing/selftests/net/forwarding/bridge_port_isolation.sh
new file mode 100755
index 000000000000..a43b4645c4de
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/bridge_port_isolation.sh
@@ -0,0 +1,151 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4ALL_TESTS="ping_ipv4 ping_ipv6 flooding"
5NUM_NETIFS=6
6CHECK_TC="yes"
7source lib.sh
8
9h1_create()
10{
11 simple_if_init $h1 192.0.2.1/24 2001:db8:1::1/64
12}
13
14h1_destroy()
15{
16 simple_if_fini $h1 192.0.2.1/24 2001:db8:1::1/64
17}
18
19h2_create()
20{
21 simple_if_init $h2 192.0.2.2/24 2001:db8:1::2/64
22}
23
24h2_destroy()
25{
26 simple_if_fini $h2 192.0.2.2/24 2001:db8:1::2/64
27}
28
29h3_create()
30{
31 simple_if_init $h3 192.0.2.3/24 2001:db8:1::3/64
32}
33
34h3_destroy()
35{
36 simple_if_fini $h3 192.0.2.3/24 2001:db8:1::3/64
37}
38
39switch_create()
40{
41 ip link add dev br0 type bridge
42
43 ip link set dev $swp1 master br0
44 ip link set dev $swp2 master br0
45 ip link set dev $swp3 master br0
46
47 ip link set dev $swp1 type bridge_slave isolated on
48 check_err $? "Can't set isolation on port $swp1"
49 ip link set dev $swp2 type bridge_slave isolated on
50 check_err $? "Can't set isolation on port $swp2"
51 ip link set dev $swp3 type bridge_slave isolated off
52 check_err $? "Can't disable isolation on port $swp3"
53
54 ip link set dev br0 up
55 ip link set dev $swp1 up
56 ip link set dev $swp2 up
57 ip link set dev $swp3 up
58}
59
60switch_destroy()
61{
62 ip link set dev $swp3 down
63 ip link set dev $swp2 down
64 ip link set dev $swp1 down
65
66 ip link del dev br0
67}
68
69setup_prepare()
70{
71 h1=${NETIFS[p1]}
72 swp1=${NETIFS[p2]}
73
74 swp2=${NETIFS[p3]}
75 h2=${NETIFS[p4]}
76
77 swp3=${NETIFS[p5]}
78 h3=${NETIFS[p6]}
79
80 vrf_prepare
81
82 h1_create
83 h2_create
84 h3_create
85
86 switch_create
87}
88
89cleanup()
90{
91 pre_cleanup
92
93 switch_destroy
94
95 h3_destroy
96 h2_destroy
97 h1_destroy
98
99 vrf_cleanup
100}
101
102ping_ipv4()
103{
104 RET=0
105 ping_do $h1 192.0.2.2
106 check_fail $? "Ping worked when it should not have"
107
108 RET=0
109 ping_do $h3 192.0.2.2
110 check_err $? "Ping didn't work when it should have"
111
112 log_test "Isolated port ping"
113}
114
115ping_ipv6()
116{
117 RET=0
118 ping6_do $h1 2001:db8:1::2
119 check_fail $? "Ping6 worked when it should not have"
120
121 RET=0
122 ping6_do $h3 2001:db8:1::2
123 check_err $? "Ping6 didn't work when it should have"
124
125 log_test "Isolated port ping6"
126}
127
128flooding()
129{
130 local mac=de:ad:be:ef:13:37
131 local ip=192.0.2.100
132
133 RET=0
134 flood_test_do false $mac $ip $h1 $h2
135 check_err $? "Packet was flooded when it should not have been"
136
137 RET=0
138 flood_test_do true $mac $ip $h3 $h2
139 check_err $? "Packet was not flooded when it should have been"
140
141 log_test "Isolated port flooding"
142}
143
144trap cleanup EXIT
145
146setup_prepare
147setup_wait
148
149tests_run
150
151exit $EXIT_STATUS
diff --git a/tools/testing/selftests/net/forwarding/devlink_lib.sh b/tools/testing/selftests/net/forwarding/devlink_lib.sh
new file mode 100644
index 000000000000..5ab1e5f43022
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/devlink_lib.sh
@@ -0,0 +1,108 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4##############################################################################
5# Source library
6
7relative_path="${BASH_SOURCE%/*}"
8if [[ "$relative_path" == "${BASH_SOURCE}" ]]; then
9 relative_path="."
10fi
11
12source "$relative_path/lib.sh"
13
14##############################################################################
15# Defines
16
17DEVLINK_DEV=$(devlink port show | grep "${NETIFS[p1]}" | \
18 grep -v "${NETIFS[p1]}[0-9]" | cut -d" " -f1 | \
19 rev | cut -d"/" -f2- | rev)
20if [ -z "$DEVLINK_DEV" ]; then
21 echo "SKIP: ${NETIFS[p1]} has no devlink device registered for it"
22 exit 1
23fi
24if [[ "$(echo $DEVLINK_DEV | grep -c pci)" -eq 0 ]]; then
25 echo "SKIP: devlink device's bus is not PCI"
26 exit 1
27fi
28
29DEVLINK_VIDDID=$(lspci -s $(echo $DEVLINK_DEV | cut -d"/" -f2) \
30 -n | cut -d" " -f3)
31
32##############################################################################
33# Sanity checks
34
35devlink -j resource show "$DEVLINK_DEV" &> /dev/null
36if [ $? -ne 0 ]; then
37 echo "SKIP: iproute2 too old, missing devlink resource support"
38 exit 1
39fi
40
41##############################################################################
42# Devlink helpers
43
44devlink_resource_names_to_path()
45{
46 local resource
47 local path=""
48
49 for resource in "${@}"; do
50 if [ "$path" == "" ]; then
51 path="$resource"
52 else
53 path="${path}/$resource"
54 fi
55 done
56
57 echo "$path"
58}
59
60devlink_resource_get()
61{
62 local name=$1
63 local resource_name=.[][\"$DEVLINK_DEV\"]
64
65 resource_name="$resource_name | .[] | select (.name == \"$name\")"
66
67 shift
68 for resource in "${@}"; do
69 resource_name="${resource_name} | .[\"resources\"][] | \
70 select (.name == \"$resource\")"
71 done
72
73 devlink -j resource show "$DEVLINK_DEV" | jq "$resource_name"
74}
75
76devlink_resource_size_get()
77{
78 local size=$(devlink_resource_get "$@" | jq '.["size_new"]')
79
80 if [ "$size" == "null" ]; then
81 devlink_resource_get "$@" | jq '.["size"]'
82 else
83 echo "$size"
84 fi
85}
86
87devlink_resource_size_set()
88{
89 local new_size=$1
90 local path
91
92 shift
93 path=$(devlink_resource_names_to_path "$@")
94 devlink resource set "$DEVLINK_DEV" path "$path" size "$new_size"
95 check_err $? "Failed setting path $path to size $size"
96}
97
98devlink_reload()
99{
100 local still_pending
101
102 devlink dev reload "$DEVLINK_DEV" &> /dev/null
103 check_err $? "Failed reload"
104
105 still_pending=$(devlink resource show "$DEVLINK_DEV" | \
106 grep -c "size_new")
107 check_err $still_pending "Failed reload - There are still unset sizes"
108}
diff --git a/tools/testing/selftests/net/forwarding/gre_multipath.sh b/tools/testing/selftests/net/forwarding/gre_multipath.sh
new file mode 100755
index 000000000000..cca2baa03fb8
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/gre_multipath.sh
@@ -0,0 +1,253 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# Test traffic distribution when a wECMP route forwards traffic to two GRE
5# tunnels.
6#
7# +-------------------------+
8# | H1 |
9# | $h1 + |
10# | 192.0.2.1/28 | |
11# +-------------------|-----+
12# |
13# +-------------------|------------------------+
14# | SW1 | |
15# | $ol1 + |
16# | 192.0.2.2/28 |
17# | |
18# | + g1a (gre) + g1b (gre) |
19# | loc=192.0.2.65 loc=192.0.2.81 |
20# | rem=192.0.2.66 --. rem=192.0.2.82 --. |
21# | tos=inherit | tos=inherit | |
22# | .------------------' | |
23# | | .------------------' |
24# | v v |
25# | + $ul1.111 (vlan) + $ul1.222 (vlan) |
26# | | 192.0.2.129/28 | 192.0.2.145/28 |
27# | \ / |
28# | \________________/ |
29# | | |
30# | + $ul1 |
31# +------------|-------------------------------+
32# |
33# +------------|-------------------------------+
34# | SW2 + $ul2 |
35# | _______|________ |
36# | / \ |
37# | / \ |
38# | + $ul2.111 (vlan) + $ul2.222 (vlan) |
39# | ^ 192.0.2.130/28 ^ 192.0.2.146/28 |
40# | | | |
41# | | '------------------. |
42# | '------------------. | |
43# | + g2a (gre) | + g2b (gre) | |
44# | loc=192.0.2.66 | loc=192.0.2.82 | |
45# | rem=192.0.2.65 --' rem=192.0.2.81 --' |
46# | tos=inherit tos=inherit |
47# | |
48# | $ol2 + |
49# | 192.0.2.17/28 | |
50# +-------------------|------------------------+
51# |
52# +-------------------|-----+
53# | H2 | |
54# | $h2 + |
55# | 192.0.2.18/28 |
56# +-------------------------+
57
58ALL_TESTS="
59 ping_ipv4
60 multipath_ipv4
61"
62
63NUM_NETIFS=6
64source lib.sh
65
66h1_create()
67{
68 simple_if_init $h1 192.0.2.1/28 2001:db8:1::1/64
69 ip route add vrf v$h1 192.0.2.16/28 via 192.0.2.2
70}
71
72h1_destroy()
73{
74 ip route del vrf v$h1 192.0.2.16/28 via 192.0.2.2
75 simple_if_fini $h1 192.0.2.1/28
76}
77
78sw1_create()
79{
80 simple_if_init $ol1 192.0.2.2/28
81 __simple_if_init $ul1 v$ol1
82 vlan_create $ul1 111 v$ol1 192.0.2.129/28
83 vlan_create $ul1 222 v$ol1 192.0.2.145/28
84
85 tunnel_create g1a gre 192.0.2.65 192.0.2.66 tos inherit dev v$ol1
86 __simple_if_init g1a v$ol1 192.0.2.65/32
87 ip route add vrf v$ol1 192.0.2.66/32 via 192.0.2.130
88
89 tunnel_create g1b gre 192.0.2.81 192.0.2.82 tos inherit dev v$ol1
90 __simple_if_init g1b v$ol1 192.0.2.81/32
91 ip route add vrf v$ol1 192.0.2.82/32 via 192.0.2.146
92
93 ip route add vrf v$ol1 192.0.2.16/28 \
94 nexthop dev g1a \
95 nexthop dev g1b
96
97 tc qdisc add dev $ul1 clsact
98 tc filter add dev $ul1 egress pref 111 prot ipv4 \
99 flower dst_ip 192.0.2.66 action pass
100 tc filter add dev $ul1 egress pref 222 prot ipv4 \
101 flower dst_ip 192.0.2.82 action pass
102}
103
104sw1_destroy()
105{
106 tc qdisc del dev $ul1 clsact
107
108 ip route del vrf v$ol1 192.0.2.16/28
109
110 ip route del vrf v$ol1 192.0.2.82/32 via 192.0.2.146
111 __simple_if_fini g1b 192.0.2.81/32
112 tunnel_destroy g1b
113
114 ip route del vrf v$ol1 192.0.2.66/32 via 192.0.2.130
115 __simple_if_fini g1a 192.0.2.65/32
116 tunnel_destroy g1a
117
118 vlan_destroy $ul1 222
119 vlan_destroy $ul1 111
120 __simple_if_fini $ul1
121 simple_if_fini $ol1 192.0.2.2/28
122}
123
124sw2_create()
125{
126 simple_if_init $ol2 192.0.2.17/28
127 __simple_if_init $ul2 v$ol2
128 vlan_create $ul2 111 v$ol2 192.0.2.130/28
129 vlan_create $ul2 222 v$ol2 192.0.2.146/28
130
131 tunnel_create g2a gre 192.0.2.66 192.0.2.65 tos inherit dev v$ol2
132 __simple_if_init g2a v$ol2 192.0.2.66/32
133 ip route add vrf v$ol2 192.0.2.65/32 via 192.0.2.129
134
135 tunnel_create g2b gre 192.0.2.82 192.0.2.81 tos inherit dev v$ol2
136 __simple_if_init g2b v$ol2 192.0.2.82/32
137 ip route add vrf v$ol2 192.0.2.81/32 via 192.0.2.145
138
139 ip route add vrf v$ol2 192.0.2.0/28 \
140 nexthop dev g2a \
141 nexthop dev g2b
142}
143
144sw2_destroy()
145{
146 ip route del vrf v$ol2 192.0.2.0/28
147
148 ip route del vrf v$ol2 192.0.2.81/32 via 192.0.2.145
149 __simple_if_fini g2b 192.0.2.82/32
150 tunnel_destroy g2b
151
152 ip route del vrf v$ol2 192.0.2.65/32 via 192.0.2.129
153 __simple_if_fini g2a 192.0.2.66/32
154 tunnel_destroy g2a
155
156 vlan_destroy $ul2 222
157 vlan_destroy $ul2 111
158 __simple_if_fini $ul2
159 simple_if_fini $ol2 192.0.2.17/28
160}
161
162h2_create()
163{
164 simple_if_init $h2 192.0.2.18/28
165 ip route add vrf v$h2 192.0.2.0/28 via 192.0.2.17
166}
167
168h2_destroy()
169{
170 ip route del vrf v$h2 192.0.2.0/28 via 192.0.2.17
171 simple_if_fini $h2 192.0.2.18/28
172}
173
174setup_prepare()
175{
176 h1=${NETIFS[p1]}
177 ol1=${NETIFS[p2]}
178
179 ul1=${NETIFS[p3]}
180 ul2=${NETIFS[p4]}
181
182 ol2=${NETIFS[p5]}
183 h2=${NETIFS[p6]}
184
185 vrf_prepare
186 h1_create
187 sw1_create
188 sw2_create
189 h2_create
190}
191
192cleanup()
193{
194 pre_cleanup
195
196 h2_destroy
197 sw2_destroy
198 sw1_destroy
199 h1_destroy
200 vrf_cleanup
201}
202
203multipath4_test()
204{
205 local what=$1; shift
206 local weight1=$1; shift
207 local weight2=$1; shift
208
209 sysctl_set net.ipv4.fib_multipath_hash_policy 1
210 ip route replace vrf v$ol1 192.0.2.16/28 \
211 nexthop dev g1a weight $weight1 \
212 nexthop dev g1b weight $weight2
213
214 local t0_111=$(tc_rule_stats_get $ul1 111 egress)
215 local t0_222=$(tc_rule_stats_get $ul1 222 egress)
216
217 ip vrf exec v$h1 \
218 $MZ $h1 -q -p 64 -A 192.0.2.1 -B 192.0.2.18 \
219 -d 1msec -t udp "sp=1024,dp=0-32768"
220
221 local t1_111=$(tc_rule_stats_get $ul1 111 egress)
222 local t1_222=$(tc_rule_stats_get $ul1 222 egress)
223
224 local d111=$((t1_111 - t0_111))
225 local d222=$((t1_222 - t0_222))
226 multipath_eval "$what" $weight1 $weight2 $d111 $d222
227
228 ip route replace vrf v$ol1 192.0.2.16/28 \
229 nexthop dev g1a \
230 nexthop dev g1b
231 sysctl_restore net.ipv4.fib_multipath_hash_policy
232}
233
234ping_ipv4()
235{
236 ping_test $h1 192.0.2.18
237}
238
239multipath_ipv4()
240{
241 log_info "Running IPv4 multipath tests"
242 multipath4_test "ECMP" 1 1
243 multipath4_test "Weighted MP 2:1" 2 1
244 multipath4_test "Weighted MP 11:45" 11 45
245}
246
247trap cleanup EXIT
248
249setup_prepare
250setup_wait
251tests_run
252
253exit $EXIT_STATUS
diff --git a/tools/testing/selftests/net/forwarding/lib.sh b/tools/testing/selftests/net/forwarding/lib.sh
index 7b18a53aa556..ca53b539aa2d 100644
--- a/tools/testing/selftests/net/forwarding/lib.sh
+++ b/tools/testing/selftests/net/forwarding/lib.sh
@@ -8,14 +8,21 @@
8PING=${PING:=ping} 8PING=${PING:=ping}
9PING6=${PING6:=ping6} 9PING6=${PING6:=ping6}
10MZ=${MZ:=mausezahn} 10MZ=${MZ:=mausezahn}
11ARPING=${ARPING:=arping}
12TEAMD=${TEAMD:=teamd}
11WAIT_TIME=${WAIT_TIME:=5} 13WAIT_TIME=${WAIT_TIME:=5}
12PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no} 14PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
13PAUSE_ON_CLEANUP=${PAUSE_ON_CLEANUP:=no} 15PAUSE_ON_CLEANUP=${PAUSE_ON_CLEANUP:=no}
14NETIF_TYPE=${NETIF_TYPE:=veth} 16NETIF_TYPE=${NETIF_TYPE:=veth}
15NETIF_CREATE=${NETIF_CREATE:=yes} 17NETIF_CREATE=${NETIF_CREATE:=yes}
16 18
17if [[ -f forwarding.config ]]; then 19relative_path="${BASH_SOURCE%/*}"
18 source forwarding.config 20if [[ "$relative_path" == "${BASH_SOURCE}" ]]; then
21 relative_path="."
22fi
23
24if [[ -f $relative_path/forwarding.config ]]; then
25 source "$relative_path/forwarding.config"
19fi 26fi
20 27
21############################################################################## 28##############################################################################
@@ -28,7 +35,10 @@ check_tc_version()
28 echo "SKIP: iproute2 too old; tc is missing JSON support" 35 echo "SKIP: iproute2 too old; tc is missing JSON support"
29 exit 1 36 exit 1
30 fi 37 fi
38}
31 39
40check_tc_shblock_support()
41{
32 tc filter help 2>&1 | grep block &> /dev/null 42 tc filter help 2>&1 | grep block &> /dev/null
33 if [[ $? -ne 0 ]]; then 43 if [[ $? -ne 0 ]]; then
34 echo "SKIP: iproute2 too old; tc is missing shared block support" 44 echo "SKIP: iproute2 too old; tc is missing shared block support"
@@ -36,6 +46,15 @@ check_tc_version()
36 fi 46 fi
37} 47}
38 48
49check_tc_chain_support()
50{
51 tc help 2>&1|grep chain &> /dev/null
52 if [[ $? -ne 0 ]]; then
53 echo "SKIP: iproute2 too old; tc is missing chain support"
54 exit 1
55 fi
56}
57
39if [[ "$(id -u)" -ne 0 ]]; then 58if [[ "$(id -u)" -ne 0 ]]; then
40 echo "SKIP: need root privileges" 59 echo "SKIP: need root privileges"
41 exit 0 60 exit 0
@@ -45,15 +64,18 @@ if [[ "$CHECK_TC" = "yes" ]]; then
45 check_tc_version 64 check_tc_version
46fi 65fi
47 66
48if [[ ! -x "$(command -v jq)" ]]; then 67require_command()
49 echo "SKIP: jq not installed" 68{
50 exit 1 69 local cmd=$1; shift
51fi
52 70
53if [[ ! -x "$(command -v $MZ)" ]]; then 71 if [[ ! -x "$(command -v "$cmd")" ]]; then
54 echo "SKIP: $MZ not installed" 72 echo "SKIP: $cmd not installed"
55 exit 1 73 exit 1
56fi 74 fi
75}
76
77require_command jq
78require_command $MZ
57 79
58if [[ ! -v NUM_NETIFS ]]; then 80if [[ ! -v NUM_NETIFS ]]; then
59 echo "SKIP: importer does not define \"NUM_NETIFS\"" 81 echo "SKIP: importer does not define \"NUM_NETIFS\""
@@ -151,6 +173,19 @@ check_fail()
151 fi 173 fi
152} 174}
153 175
176check_err_fail()
177{
178 local should_fail=$1; shift
179 local err=$1; shift
180 local what=$1; shift
181
182 if ((should_fail)); then
183 check_fail $err "$what succeeded, but should have failed"
184 else
185 check_err $err "$what failed"
186 fi
187}
188
154log_test() 189log_test()
155{ 190{
156 local test_name=$1 191 local test_name=$1
@@ -185,24 +220,54 @@ log_info()
185 echo "INFO: $msg" 220 echo "INFO: $msg"
186} 221}
187 222
223setup_wait_dev()
224{
225 local dev=$1; shift
226
227 while true; do
228 ip link show dev $dev up \
229 | grep 'state UP' &> /dev/null
230 if [[ $? -ne 0 ]]; then
231 sleep 1
232 else
233 break
234 fi
235 done
236}
237
188setup_wait() 238setup_wait()
189{ 239{
190 for i in $(eval echo {1..$NUM_NETIFS}); do 240 local num_netifs=${1:-$NUM_NETIFS}
191 while true; do 241
192 ip link show dev ${NETIFS[p$i]} up \ 242 for ((i = 1; i <= num_netifs; ++i)); do
193 | grep 'state UP' &> /dev/null 243 setup_wait_dev ${NETIFS[p$i]}
194 if [[ $? -ne 0 ]]; then
195 sleep 1
196 else
197 break
198 fi
199 done
200 done 244 done
201 245
202 # Make sure links are ready. 246 # Make sure links are ready.
203 sleep $WAIT_TIME 247 sleep $WAIT_TIME
204} 248}
205 249
250lldpad_app_wait_set()
251{
252 local dev=$1; shift
253
254 while lldptool -t -i $dev -V APP -c app | grep -q pending; do
255 echo "$dev: waiting for lldpad to push pending APP updates"
256 sleep 5
257 done
258}
259
260lldpad_app_wait_del()
261{
262 # Give lldpad a chance to push down the changes. If the device is downed
263 # too soon, the updates will be left pending. However, they will have
264 # been struck off the lldpad's DB already, so we won't be able to tell
265 # they are pending. Then on next test iteration this would cause
266 # weirdness as newly-added APP rules conflict with the old ones,
267 # sometimes getting stuck in an "unknown" state.
268 sleep 5
269}
270
206pre_cleanup() 271pre_cleanup()
207{ 272{
208 if [ "${PAUSE_ON_CLEANUP}" = "yes" ]; then 273 if [ "${PAUSE_ON_CLEANUP}" = "yes" ]; then
@@ -287,6 +352,29 @@ __addr_add_del()
287 done 352 done
288} 353}
289 354
355__simple_if_init()
356{
357 local if_name=$1; shift
358 local vrf_name=$1; shift
359 local addrs=("${@}")
360
361 ip link set dev $if_name master $vrf_name
362 ip link set dev $if_name up
363
364 __addr_add_del $if_name add "${addrs[@]}"
365}
366
367__simple_if_fini()
368{
369 local if_name=$1; shift
370 local addrs=("${@}")
371
372 __addr_add_del $if_name del "${addrs[@]}"
373
374 ip link set dev $if_name down
375 ip link set dev $if_name nomaster
376}
377
290simple_if_init() 378simple_if_init()
291{ 379{
292 local if_name=$1 380 local if_name=$1
@@ -298,11 +386,8 @@ simple_if_init()
298 array=("${@}") 386 array=("${@}")
299 387
300 vrf_create $vrf_name 388 vrf_create $vrf_name
301 ip link set dev $if_name master $vrf_name
302 ip link set dev $vrf_name up 389 ip link set dev $vrf_name up
303 ip link set dev $if_name up 390 __simple_if_init $if_name $vrf_name "${array[@]}"
304
305 __addr_add_del $if_name add "${array[@]}"
306} 391}
307 392
308simple_if_fini() 393simple_if_fini()
@@ -315,9 +400,7 @@ simple_if_fini()
315 vrf_name=v$if_name 400 vrf_name=v$if_name
316 array=("${@}") 401 array=("${@}")
317 402
318 __addr_add_del $if_name del "${array[@]}" 403 __simple_if_fini $if_name "${array[@]}"
319
320 ip link set dev $if_name down
321 vrf_destroy $vrf_name 404 vrf_destroy $vrf_name
322} 405}
323 406
@@ -365,6 +448,28 @@ vlan_destroy()
365 ip link del dev $name 448 ip link del dev $name
366} 449}
367 450
451team_create()
452{
453 local if_name=$1; shift
454 local mode=$1; shift
455
456 require_command $TEAMD
457 $TEAMD -t $if_name -d -c '{"runner": {"name": "'$mode'"}}'
458 for slave in "$@"; do
459 ip link set dev $slave down
460 ip link set dev $slave master $if_name
461 ip link set dev $slave up
462 done
463 ip link set dev $if_name up
464}
465
466team_destroy()
467{
468 local if_name=$1; shift
469
470 $TEAMD -t $if_name -k
471}
472
368master_name_get() 473master_name_get()
369{ 474{
370 local if_name=$1 475 local if_name=$1
@@ -383,9 +488,10 @@ tc_rule_stats_get()
383{ 488{
384 local dev=$1; shift 489 local dev=$1; shift
385 local pref=$1; shift 490 local pref=$1; shift
491 local dir=$1; shift
386 492
387 tc -j -s filter show dev $dev ingress pref $pref | 493 tc -j -s filter show dev $dev ${dir:-ingress} pref $pref \
388 jq '.[1].options.actions[].stats.packets' 494 | jq '.[1].options.actions[].stats.packets'
389} 495}
390 496
391mac_get() 497mac_get()
@@ -437,7 +543,9 @@ forwarding_restore()
437 543
438tc_offload_check() 544tc_offload_check()
439{ 545{
440 for i in $(eval echo {1..$NUM_NETIFS}); do 546 local num_netifs=${1:-$NUM_NETIFS}
547
548 for ((i = 1; i <= num_netifs; ++i)); do
441 ethtool -k ${NETIFS[p$i]} \ 549 ethtool -k ${NETIFS[p$i]} \
442 | grep "hw-tc-offload: on" &> /dev/null 550 | grep "hw-tc-offload: on" &> /dev/null
443 if [[ $? -ne 0 ]]; then 551 if [[ $? -ne 0 ]]; then
@@ -453,9 +561,15 @@ trap_install()
453 local dev=$1; shift 561 local dev=$1; shift
454 local direction=$1; shift 562 local direction=$1; shift
455 563
456 # For slow-path testing, we need to install a trap to get to 564 # Some devices may not support or need in-hardware trapping of traffic
457 # slow path the packets that would otherwise be switched in HW. 565 # (e.g. the veth pairs that this library creates for non-existent
458 tc filter add dev $dev $direction pref 1 flower skip_sw action trap 566 # loopbacks). Use continue instead, so that there is a filter in there
567 # (some tests check counters), and so that other filters are still
568 # processed.
569 tc filter add dev $dev $direction pref 1 \
570 flower skip_sw action trap 2>/dev/null \
571 || tc filter add dev $dev $direction pref 1 \
572 flower action continue
459} 573}
460 574
461trap_uninstall() 575trap_uninstall()
@@ -463,11 +577,13 @@ trap_uninstall()
463 local dev=$1; shift 577 local dev=$1; shift
464 local direction=$1; shift 578 local direction=$1; shift
465 579
466 tc filter del dev $dev $direction pref 1 flower skip_sw 580 tc filter del dev $dev $direction pref 1 flower
467} 581}
468 582
469slow_path_trap_install() 583slow_path_trap_install()
470{ 584{
585 # For slow-path testing, we need to install a trap to get to
586 # slow path the packets that would otherwise be switched in HW.
471 if [ "${tcflags/skip_hw}" != "$tcflags" ]; then 587 if [ "${tcflags/skip_hw}" != "$tcflags" ]; then
472 trap_install "$@" 588 trap_install "$@"
473 fi 589 fi
@@ -537,6 +653,48 @@ vlan_capture_uninstall()
537 __vlan_capture_add_del del 100 "$@" 653 __vlan_capture_add_del del 100 "$@"
538} 654}
539 655
656__dscp_capture_add_del()
657{
658 local add_del=$1; shift
659 local dev=$1; shift
660 local base=$1; shift
661 local dscp;
662
663 for prio in {0..7}; do
664 dscp=$((base + prio))
665 __icmp_capture_add_del $add_del $((dscp + 100)) "" $dev \
666 "skip_hw ip_tos $((dscp << 2))"
667 done
668}
669
670dscp_capture_install()
671{
672 local dev=$1; shift
673 local base=$1; shift
674
675 __dscp_capture_add_del add $dev $base
676}
677
678dscp_capture_uninstall()
679{
680 local dev=$1; shift
681 local base=$1; shift
682
683 __dscp_capture_add_del del $dev $base
684}
685
686dscp_fetch_stats()
687{
688 local dev=$1; shift
689 local base=$1; shift
690
691 for prio in {0..7}; do
692 local dscp=$((base + prio))
693 local t=$(tc_rule_stats_get $dev $((dscp + 100)))
694 echo "[$dscp]=$t "
695 done
696}
697
540matchall_sink_create() 698matchall_sink_create()
541{ 699{
542 local dev=$1; shift 700 local dev=$1; shift
@@ -557,33 +715,86 @@ tests_run()
557 done 715 done
558} 716}
559 717
718multipath_eval()
719{
720 local desc="$1"
721 local weight_rp12=$2
722 local weight_rp13=$3
723 local packets_rp12=$4
724 local packets_rp13=$5
725 local weights_ratio packets_ratio diff
726
727 RET=0
728
729 if [[ "$weight_rp12" -gt "$weight_rp13" ]]; then
730 weights_ratio=$(echo "scale=2; $weight_rp12 / $weight_rp13" \
731 | bc -l)
732 else
733 weights_ratio=$(echo "scale=2; $weight_rp13 / $weight_rp12" \
734 | bc -l)
735 fi
736
737 if [[ "$packets_rp12" -eq "0" || "$packets_rp13" -eq "0" ]]; then
738 check_err 1 "Packet difference is 0"
739 log_test "Multipath"
740 log_info "Expected ratio $weights_ratio"
741 return
742 fi
743
744 if [[ "$weight_rp12" -gt "$weight_rp13" ]]; then
745 packets_ratio=$(echo "scale=2; $packets_rp12 / $packets_rp13" \
746 | bc -l)
747 else
748 packets_ratio=$(echo "scale=2; $packets_rp13 / $packets_rp12" \
749 | bc -l)
750 fi
751
752 diff=$(echo $weights_ratio - $packets_ratio | bc -l)
753 diff=${diff#-}
754
755 test "$(echo "$diff / $weights_ratio > 0.15" | bc -l)" -eq 0
756 check_err $? "Too large discrepancy between expected and measured ratios"
757 log_test "$desc"
758 log_info "Expected ratio $weights_ratio Measured ratio $packets_ratio"
759}
760
560############################################################################## 761##############################################################################
561# Tests 762# Tests
562 763
563ping_test() 764ping_do()
564{ 765{
565 local if_name=$1 766 local if_name=$1
566 local dip=$2 767 local dip=$2
567 local vrf_name 768 local vrf_name
568 769
569 RET=0
570
571 vrf_name=$(master_name_get $if_name) 770 vrf_name=$(master_name_get $if_name)
572 ip vrf exec $vrf_name $PING $dip -c 10 -i 0.1 -w 2 &> /dev/null 771 ip vrf exec $vrf_name $PING $dip -c 10 -i 0.1 -w 2 &> /dev/null
772}
773
774ping_test()
775{
776 RET=0
777
778 ping_do $1 $2
573 check_err $? 779 check_err $?
574 log_test "ping" 780 log_test "ping"
575} 781}
576 782
577ping6_test() 783ping6_do()
578{ 784{
579 local if_name=$1 785 local if_name=$1
580 local dip=$2 786 local dip=$2
581 local vrf_name 787 local vrf_name
582 788
583 RET=0
584
585 vrf_name=$(master_name_get $if_name) 789 vrf_name=$(master_name_get $if_name)
586 ip vrf exec $vrf_name $PING6 $dip -c 10 -i 0.1 -w 2 &> /dev/null 790 ip vrf exec $vrf_name $PING6 $dip -c 10 -i 0.1 -w 2 &> /dev/null
791}
792
793ping6_test()
794{
795 RET=0
796
797 ping6_do $1 $2
587 check_err $? 798 check_err $?
588 log_test "ping6" 799 log_test "ping6"
589} 800}
diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1d.sh b/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1d.sh
new file mode 100755
index 000000000000..c5095da7f6bf
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1d.sh
@@ -0,0 +1,132 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# Test for "tc action mirred egress mirror" when the underlay route points at a
5# bridge device without vlan filtering (802.1d).
6#
7# This test uses standard topology for testing mirror-to-gretap. See
8# mirror_gre_topo_lib.sh for more details. The full topology is as follows:
9#
10# +---------------------+ +---------------------+
11# | H1 | | H2 |
12# | + $h1 | | $h2 + |
13# | | 192.0.2.1/28 | | 192.0.2.2/28 | |
14# +-----|---------------+ +---------------|-----+
15# | |
16# +-----|-------------------------------------------------------------|-----+
17# | SW o---> mirror | |
18# | +---|-------------------------------------------------------------|---+ |
19# | | + $swp1 + br1 (802.1q bridge) $swp2 + | |
20# | +---------------------------------------------------------------------+ |
21# | |
22# | +---------------------------------------------------------------------+ |
23# | | + br2 (802.1d bridge) | |
24# | | 192.0.2.129/28 | |
25# | | + $swp3 2001:db8:2::1/64 | |
26# | +---|-----------------------------------------------------------------+ |
27# | | ^ ^ |
28# | | + gt6 (ip6gretap) | + gt4 (gretap) | |
29# | | : loc=2001:db8:2::1 | : loc=192.0.2.129 | |
30# | | : rem=2001:db8:2::2 -+ : rem=192.0.2.130 -+ |
31# | | : ttl=100 : ttl=100 |
32# | | : tos=inherit : tos=inherit |
33# +-----|---------------------:----------------------:----------------------+
34# | : :
35# +-----|---------------------:----------------------:----------------------+
36# | H3 + $h3 + h3-gt6(ip6gretap) + h3-gt4 (gretap) |
37# | 192.0.2.130/28 loc=2001:db8:2::2 loc=192.0.2.130 |
38# | 2001:db8:2::2/64 rem=2001:db8:2::1 rem=192.0.2.129 |
39# | ttl=100 ttl=100 |
40# | tos=inherit tos=inherit |
41# +-------------------------------------------------------------------------+
42
43ALL_TESTS="
44 test_gretap
45 test_ip6gretap
46"
47
48NUM_NETIFS=6
49source lib.sh
50source mirror_lib.sh
51source mirror_gre_lib.sh
52source mirror_gre_topo_lib.sh
53
54setup_prepare()
55{
56 h1=${NETIFS[p1]}
57 swp1=${NETIFS[p2]}
58
59 swp2=${NETIFS[p3]}
60 h2=${NETIFS[p4]}
61
62 swp3=${NETIFS[p5]}
63 h3=${NETIFS[p6]}
64
65 vrf_prepare
66 mirror_gre_topo_create
67
68 ip link add name br2 type bridge vlan_filtering 0
69 ip link set dev br2 up
70
71 ip link set dev $swp3 master br2
72 ip route add 192.0.2.130/32 dev br2
73 ip -6 route add 2001:db8:2::2/128 dev br2
74
75 ip address add dev br2 192.0.2.129/28
76 ip address add dev br2 2001:db8:2::1/64
77
78 ip address add dev $h3 192.0.2.130/28
79 ip address add dev $h3 2001:db8:2::2/64
80}
81
82cleanup()
83{
84 pre_cleanup
85
86 ip address del dev $h3 2001:db8:2::2/64
87 ip address del dev $h3 192.0.2.130/28
88 ip link del dev br2
89
90 mirror_gre_topo_destroy
91 vrf_cleanup
92}
93
94test_gretap()
95{
96 full_test_span_gre_dir gt4 ingress 8 0 "mirror to gretap"
97 full_test_span_gre_dir gt4 egress 0 8 "mirror to gretap"
98}
99
100test_ip6gretap()
101{
102 full_test_span_gre_dir gt6 ingress 8 0 "mirror to ip6gretap"
103 full_test_span_gre_dir gt6 egress 0 8 "mirror to ip6gretap"
104}
105
106test_all()
107{
108 slow_path_trap_install $swp1 ingress
109 slow_path_trap_install $swp1 egress
110
111 tests_run
112
113 slow_path_trap_uninstall $swp1 egress
114 slow_path_trap_uninstall $swp1 ingress
115}
116
117trap cleanup EXIT
118
119setup_prepare
120setup_wait
121
122tcflags="skip_hw"
123test_all
124
125if ! tc_offload_check; then
126 echo "WARN: Could not test offloaded functionality"
127else
128 tcflags="skip_sw"
129 test_all
130fi
131
132exit $EXIT_STATUS
diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1d_vlan.sh b/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1d_vlan.sh
index 3bb4c2ba7b14..197e769c2ed1 100755
--- a/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1d_vlan.sh
+++ b/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1d_vlan.sh
@@ -74,12 +74,14 @@ test_vlan_match()
74 74
75test_gretap() 75test_gretap()
76{ 76{
77 test_vlan_match gt4 'vlan_id 555 vlan_ethtype ip' "mirror to gretap" 77 test_vlan_match gt4 'skip_hw vlan_id 555 vlan_ethtype ip' \
78 "mirror to gretap"
78} 79}
79 80
80test_ip6gretap() 81test_ip6gretap()
81{ 82{
82 test_vlan_match gt6 'vlan_id 555 vlan_ethtype ipv6' "mirror to ip6gretap" 83 test_vlan_match gt6 'skip_hw vlan_id 555 vlan_ethtype ip' \
84 "mirror to ip6gretap"
83} 85}
84 86
85test_gretap_stp() 87test_gretap_stp()
diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1q.sh b/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1q.sh
new file mode 100755
index 000000000000..a3402cd8d5b6
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1q.sh
@@ -0,0 +1,126 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# Test for "tc action mirred egress mirror" when the underlay route points at a
5# bridge device with vlan filtering (802.1q).
6#
7# This test uses standard topology for testing mirror-to-gretap. See
8# mirror_gre_topo_lib.sh for more details. The full topology is as follows:
9#
10# +---------------------+ +---------------------+
11# | H1 | | H2 |
12# | + $h1 | | $h2 + |
13# | | 192.0.2.1/28 | | 192.0.2.2/28 | |
14# +-----|---------------+ +---------------|-----+
15# | |
16# +-----|---------------------------------------------------------------|-----+
17# | SW o---> mirror | |
18# | +---|---------------------------------------------------------------|---+ |
19# | | + $swp1 + br1 (802.1q bridge) $swp2 + | |
20# | | 192.0.2.129/28 | |
21# | | + $swp3 2001:db8:2::1/64 | |
22# | | | vid555 vid555[pvid,untagged] | |
23# | +---|-------------------------------------------------------------------+ |
24# | | ^ ^ |
25# | | + gt6 (ip6gretap) | + gt4 (gretap) | |
26# | | : loc=2001:db8:2::1 | : loc=192.0.2.129 | |
27# | | : rem=2001:db8:2::2 -+ : rem=192.0.2.130 -+ |
28# | | : ttl=100 : ttl=100 |
29# | | : tos=inherit : tos=inherit |
30# +-----|---------------------:------------------------:----------------------+
31# | : :
32# +-----|---------------------:------------------------:----------------------+
33# | H3 + $h3 + h3-gt6(ip6gretap) + h3-gt4 (gretap) |
34# | | loc=2001:db8:2::2 loc=192.0.2.130 |
35# | + $h3.555 rem=2001:db8:2::1 rem=192.0.2.129 |
36# | 192.0.2.130/28 ttl=100 ttl=100 |
37# | 2001:db8:2::2/64 tos=inherit tos=inherit |
38# +---------------------------------------------------------------------------+
39
40ALL_TESTS="
41 test_gretap
42 test_ip6gretap
43"
44
45NUM_NETIFS=6
46source lib.sh
47source mirror_lib.sh
48source mirror_gre_lib.sh
49source mirror_gre_topo_lib.sh
50
51setup_prepare()
52{
53 h1=${NETIFS[p1]}
54 swp1=${NETIFS[p2]}
55
56 swp2=${NETIFS[p3]}
57 h2=${NETIFS[p4]}
58
59 swp3=${NETIFS[p5]}
60 h3=${NETIFS[p6]}
61
62 vrf_prepare
63 mirror_gre_topo_create
64
65 ip link set dev $swp3 master br1
66 bridge vlan add dev br1 vid 555 pvid untagged self
67 ip address add dev br1 192.0.2.129/28
68 ip address add dev br1 2001:db8:2::1/64
69
70 ip -4 route add 192.0.2.130/32 dev br1
71 ip -6 route add 2001:db8:2::2/128 dev br1
72
73 vlan_create $h3 555 v$h3 192.0.2.130/28 2001:db8:2::2/64
74 bridge vlan add dev $swp3 vid 555
75}
76
77cleanup()
78{
79 pre_cleanup
80
81 ip link set dev $swp3 nomaster
82 vlan_destroy $h3 555
83
84 mirror_gre_topo_destroy
85 vrf_cleanup
86}
87
88test_gretap()
89{
90 full_test_span_gre_dir gt4 ingress 8 0 "mirror to gretap"
91 full_test_span_gre_dir gt4 egress 0 8 "mirror to gretap"
92}
93
94test_ip6gretap()
95{
96 full_test_span_gre_dir gt6 ingress 8 0 "mirror to ip6gretap"
97 full_test_span_gre_dir gt6 egress 0 8 "mirror to ip6gretap"
98}
99
100tests()
101{
102 slow_path_trap_install $swp1 ingress
103 slow_path_trap_install $swp1 egress
104
105 tests_run
106
107 slow_path_trap_uninstall $swp1 egress
108 slow_path_trap_uninstall $swp1 ingress
109}
110
111trap cleanup EXIT
112
113setup_prepare
114setup_wait
115
116tcflags="skip_hw"
117tests
118
119if ! tc_offload_check; then
120 echo "WARN: Could not test offloaded functionality"
121else
122 tcflags="skip_sw"
123 tests
124fi
125
126exit $EXIT_STATUS
diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1q_lag.sh b/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1q_lag.sh
new file mode 100755
index 000000000000..61844caf671e
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1q_lag.sh
@@ -0,0 +1,283 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# Test for "tc action mirred egress mirror" when the underlay route points at a
5# bridge device with vlan filtering (802.1q), and the egress device is a team
6# device.
7#
8# +----------------------+ +----------------------+
9# | H1 | | H2 |
10# | + $h1.333 | | $h1.555 + |
11# | | 192.0.2.1/28 | | 192.0.2.18/28 | |
12# +-----|----------------+ +----------------|-----+
13# | $h1 |
14# +--------------------------------+------------------------------+
15# |
16# +--------------------------------------|------------------------------------+
17# | SW o---> mirror |
18# | | |
19# | +--------------------------------+------------------------------+ |
20# | | $swp1 | |
21# | + $swp1.333 $swp1.555 + |
22# | 192.0.2.2/28 192.0.2.17/28 |
23# | |
24# | +-----------------------------------------------------------------------+ |
25# | | BR1 (802.1q) | |
26# | | + lag (team) 192.0.2.129/28 | |
27# | | / \ 2001:db8:2::1/64 | |
28# | +---/---\---------------------------------------------------------------+ |
29# | / \ ^ |
30# | | \ + gt4 (gretap) | |
31# | | \ loc=192.0.2.129 | |
32# | | \ rem=192.0.2.130 -+ |
33# | | \ ttl=100 |
34# | | \ tos=inherit |
35# | | \ |
36# | | \_________________________________ |
37# | | \ |
38# | + $swp3 + $swp4 |
39# +---|------------------------------------------------|----------------------+
40# | |
41# +---|----------------------+ +---|----------------------+
42# | + $h3 H3 | | + $h4 H4 |
43# | 192.0.2.130/28 | | 192.0.2.130/28 |
44# | 2001:db8:2::2/64 | | 2001:db8:2::2/64 |
45# +--------------------------+ +--------------------------+
46
47ALL_TESTS="
48 test_mirror_gretap_first
49 test_mirror_gretap_second
50"
51
52NUM_NETIFS=6
53source lib.sh
54source mirror_lib.sh
55source mirror_gre_lib.sh
56
57require_command $ARPING
58
59vlan_host_create()
60{
61 local if_name=$1; shift
62 local vid=$1; shift
63 local vrf_name=$1; shift
64 local ips=("${@}")
65
66 vrf_create $vrf_name
67 ip link set dev $vrf_name up
68 vlan_create $if_name $vid $vrf_name "${ips[@]}"
69}
70
71vlan_host_destroy()
72{
73 local if_name=$1; shift
74 local vid=$1; shift
75 local vrf_name=$1; shift
76
77 vlan_destroy $if_name $vid
78 ip link set dev $vrf_name down
79 vrf_destroy $vrf_name
80}
81
82h1_create()
83{
84 vlan_host_create $h1 333 vrf-h1 192.0.2.1/28
85 ip -4 route add 192.0.2.16/28 vrf vrf-h1 nexthop via 192.0.2.2
86}
87
88h1_destroy()
89{
90 ip -4 route del 192.0.2.16/28 vrf vrf-h1
91 vlan_host_destroy $h1 333 vrf-h1
92}
93
94h2_create()
95{
96 vlan_host_create $h1 555 vrf-h2 192.0.2.18/28
97 ip -4 route add 192.0.2.0/28 vrf vrf-h2 nexthop via 192.0.2.17
98}
99
100h2_destroy()
101{
102 ip -4 route del 192.0.2.0/28 vrf vrf-h2
103 vlan_host_destroy $h1 555 vrf-h2
104}
105
106h3_create()
107{
108 simple_if_init $h3 192.0.2.130/28
109 tc qdisc add dev $h3 clsact
110}
111
112h3_destroy()
113{
114 tc qdisc del dev $h3 clsact
115 simple_if_fini $h3 192.0.2.130/28
116}
117
118h4_create()
119{
120 simple_if_init $h4 192.0.2.130/28
121 tc qdisc add dev $h4 clsact
122}
123
124h4_destroy()
125{
126 tc qdisc del dev $h4 clsact
127 simple_if_fini $h4 192.0.2.130/28
128}
129
130switch_create()
131{
132 ip link set dev $swp1 up
133 tc qdisc add dev $swp1 clsact
134 vlan_create $swp1 333 "" 192.0.2.2/28
135 vlan_create $swp1 555 "" 192.0.2.17/28
136
137 tunnel_create gt4 gretap 192.0.2.129 192.0.2.130 \
138 ttl 100 tos inherit
139
140 ip link set dev $swp3 up
141 ip link set dev $swp4 up
142
143 ip link add name br1 type bridge vlan_filtering 1
144 ip link set dev br1 up
145 __addr_add_del br1 add 192.0.2.129/32
146 ip -4 route add 192.0.2.130/32 dev br1
147
148 team_create lag loadbalance $swp3 $swp4
149 ip link set dev lag master br1
150}
151
152switch_destroy()
153{
154 ip link set dev lag nomaster
155 team_destroy lag
156
157 ip -4 route del 192.0.2.130/32 dev br1
158 __addr_add_del br1 del 192.0.2.129/32
159 ip link set dev br1 down
160 ip link del dev br1
161
162 ip link set dev $swp4 down
163 ip link set dev $swp3 down
164
165 tunnel_destroy gt4
166
167 vlan_destroy $swp1 555
168 vlan_destroy $swp1 333
169 tc qdisc del dev $swp1 clsact
170 ip link set dev $swp1 down
171}
172
173setup_prepare()
174{
175 h1=${NETIFS[p1]}
176 swp1=${NETIFS[p2]}
177
178 swp3=${NETIFS[p3]}
179 h3=${NETIFS[p4]}
180
181 swp4=${NETIFS[p5]}
182 h4=${NETIFS[p6]}
183
184 vrf_prepare
185
186 ip link set dev $h1 up
187 h1_create
188 h2_create
189 h3_create
190 h4_create
191 switch_create
192
193 trap_install $h3 ingress
194 trap_install $h4 ingress
195}
196
197cleanup()
198{
199 pre_cleanup
200
201 trap_uninstall $h4 ingress
202 trap_uninstall $h3 ingress
203
204 switch_destroy
205 h4_destroy
206 h3_destroy
207 h2_destroy
208 h1_destroy
209 ip link set dev $h1 down
210
211 vrf_cleanup
212}
213
214test_lag_slave()
215{
216 local host_dev=$1; shift
217 local up_dev=$1; shift
218 local down_dev=$1; shift
219 local what=$1; shift
220
221 RET=0
222
223 mirror_install $swp1 ingress gt4 \
224 "proto 802.1q flower vlan_id 333 $tcflags"
225
226 # Test connectivity through $up_dev when $down_dev is set down.
227 ip link set dev $down_dev down
228 setup_wait_dev $up_dev
229 setup_wait_dev $host_dev
230 $ARPING -I br1 192.0.2.130 -qfc 1
231 sleep 2
232 mirror_test vrf-h1 192.0.2.1 192.0.2.18 $host_dev 1 10
233
234 # Test lack of connectivity when both slaves are down.
235 ip link set dev $up_dev down
236 sleep 2
237 mirror_test vrf-h1 192.0.2.1 192.0.2.18 $h3 1 0
238 mirror_test vrf-h1 192.0.2.1 192.0.2.18 $h4 1 0
239
240 ip link set dev $up_dev up
241 ip link set dev $down_dev up
242 mirror_uninstall $swp1 ingress
243
244 log_test "$what ($tcflags)"
245}
246
247test_mirror_gretap_first()
248{
249 test_lag_slave $h3 $swp3 $swp4 "mirror to gretap: LAG first slave"
250}
251
252test_mirror_gretap_second()
253{
254 test_lag_slave $h4 $swp4 $swp3 "mirror to gretap: LAG second slave"
255}
256
257test_all()
258{
259 slow_path_trap_install $swp1 ingress
260 slow_path_trap_install $swp1 egress
261
262 tests_run
263
264 slow_path_trap_uninstall $swp1 egress
265 slow_path_trap_uninstall $swp1 ingress
266}
267
268trap cleanup EXIT
269
270setup_prepare
271setup_wait
272
273tcflags="skip_hw"
274test_all
275
276if ! tc_offload_check; then
277 echo "WARN: Could not test offloaded functionality"
278else
279 tcflags="skip_sw"
280 test_all
281fi
282
283exit $EXIT_STATUS
diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_changes.sh b/tools/testing/selftests/net/forwarding/mirror_gre_changes.sh
index aa29d46186a8..135902aa8b11 100755
--- a/tools/testing/selftests/net/forwarding/mirror_gre_changes.sh
+++ b/tools/testing/selftests/net/forwarding/mirror_gre_changes.sh
@@ -122,15 +122,8 @@ test_span_gre_egress_up()
122 # After setting the device up, wait for neighbor to get resolved so that 122 # After setting the device up, wait for neighbor to get resolved so that
123 # we can expect mirroring to work. 123 # we can expect mirroring to work.
124 ip link set dev $swp3 up 124 ip link set dev $swp3 up
125 while true; do 125 setup_wait_dev $swp3
126 ip neigh sh dev $swp3 $remote_ip nud reachable | 126 ping -c 1 -I $swp3 $remote_ip &>/dev/null
127 grep -q ^
128 if [[ $? -ne 0 ]]; then
129 sleep 1
130 else
131 break
132 fi
133 done
134 127
135 quick_test_span_gre_dir $tundev ingress 128 quick_test_span_gre_dir $tundev ingress
136 mirror_uninstall $swp1 ingress 129 mirror_uninstall $swp1 ingress
diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_lag_lacp.sh b/tools/testing/selftests/net/forwarding/mirror_gre_lag_lacp.sh
new file mode 100755
index 000000000000..9edf4cb104a8
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/mirror_gre_lag_lacp.sh
@@ -0,0 +1,285 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# Test for "tc action mirred egress mirror" when the underlay route points at a
5# team device.
6#
7# +----------------------+ +----------------------+
8# | H1 | | H2 |
9# | + $h1.333 | | $h1.555 + |
10# | | 192.0.2.1/28 | | 192.0.2.18/28 | |
11# +----|-----------------+ +----------------|-----+
12# | $h1 |
13# +---------------------------------+------------------------------+
14# |
15# +--------------------------------------|------------------------------------+
16# | SW o---> mirror |
17# | | |
18# | +----------------------------------+------------------------------+ |
19# | | $swp1 | |
20# | + $swp1.333 $swp1.555 + |
21# | 192.0.2.2/28 192.0.2.17/28 |
22# | |
23# | |
24# | + gt4 (gretap) ,-> + lag1 (team) |
25# | loc=192.0.2.129 | | 192.0.2.129/28 |
26# | rem=192.0.2.130 --' | |
27# | ttl=100 | |
28# | tos=inherit | |
29# | _____________________|______________________ |
30# | / \ |
31# | / \ |
32# | + $swp3 + $swp4 |
33# +---|------------------------------------------------|----------------------+
34# | |
35# +---|------------------------------------------------|----------------------+
36# | + $h3 + $h4 H3 |
37# | \ / |
38# | \____________________________________________/ |
39# | | |
40# | + lag2 (team) |
41# | 192.0.2.130/28 |
42# | |
43# +---------------------------------------------------------------------------+
44
45ALL_TESTS="
46 test_mirror_gretap_first
47 test_mirror_gretap_second
48"
49
50NUM_NETIFS=6
51source lib.sh
52source mirror_lib.sh
53source mirror_gre_lib.sh
54
55require_command $ARPING
56
57vlan_host_create()
58{
59 local if_name=$1; shift
60 local vid=$1; shift
61 local vrf_name=$1; shift
62 local ips=("${@}")
63
64 vrf_create $vrf_name
65 ip link set dev $vrf_name up
66 vlan_create $if_name $vid $vrf_name "${ips[@]}"
67}
68
69vlan_host_destroy()
70{
71 local if_name=$1; shift
72 local vid=$1; shift
73 local vrf_name=$1; shift
74
75 vlan_destroy $if_name $vid
76 ip link set dev $vrf_name down
77 vrf_destroy $vrf_name
78}
79
80h1_create()
81{
82 vlan_host_create $h1 333 vrf-h1 192.0.2.1/28
83 ip -4 route add 192.0.2.16/28 vrf vrf-h1 nexthop via 192.0.2.2
84}
85
86h1_destroy()
87{
88 ip -4 route del 192.0.2.16/28 vrf vrf-h1
89 vlan_host_destroy $h1 333 vrf-h1
90}
91
92h2_create()
93{
94 vlan_host_create $h1 555 vrf-h2 192.0.2.18/28
95 ip -4 route add 192.0.2.0/28 vrf vrf-h2 nexthop via 192.0.2.17
96}
97
98h2_destroy()
99{
100 ip -4 route del 192.0.2.0/28 vrf vrf-h2
101 vlan_host_destroy $h1 555 vrf-h2
102}
103
104h3_create_team()
105{
106 team_create lag2 lacp $h3 $h4
107 __simple_if_init lag2 vrf-h3 192.0.2.130/32
108 ip -4 route add vrf vrf-h3 192.0.2.129/32 dev lag2
109}
110
111h3_destroy_team()
112{
113 ip -4 route del vrf vrf-h3 192.0.2.129/32 dev lag2
114 __simple_if_fini lag2 192.0.2.130/32
115 team_destroy lag2
116
117 ip link set dev $h3 down
118 ip link set dev $h4 down
119}
120
121h3_create()
122{
123 vrf_create vrf-h3
124 ip link set dev vrf-h3 up
125 tc qdisc add dev $h3 clsact
126 tc qdisc add dev $h4 clsact
127 h3_create_team
128}
129
130h3_destroy()
131{
132 h3_destroy_team
133 tc qdisc del dev $h4 clsact
134 tc qdisc del dev $h3 clsact
135 ip link set dev vrf-h3 down
136 vrf_destroy vrf-h3
137}
138
139switch_create()
140{
141 ip link set dev $swp1 up
142 tc qdisc add dev $swp1 clsact
143 vlan_create $swp1 333 "" 192.0.2.2/28
144 vlan_create $swp1 555 "" 192.0.2.17/28
145
146 tunnel_create gt4 gretap 192.0.2.129 192.0.2.130 \
147 ttl 100 tos inherit
148
149 ip link set dev $swp3 up
150 ip link set dev $swp4 up
151 team_create lag1 lacp $swp3 $swp4
152 __addr_add_del lag1 add 192.0.2.129/32
153 ip -4 route add 192.0.2.130/32 dev lag1
154}
155
156switch_destroy()
157{
158 ip -4 route del 192.0.2.130/32 dev lag1
159 __addr_add_del lag1 del 192.0.2.129/32
160 team_destroy lag1
161
162 ip link set dev $swp4 down
163 ip link set dev $swp3 down
164
165 tunnel_destroy gt4
166
167 vlan_destroy $swp1 555
168 vlan_destroy $swp1 333
169 tc qdisc del dev $swp1 clsact
170 ip link set dev $swp1 down
171}
172
173setup_prepare()
174{
175 h1=${NETIFS[p1]}
176 swp1=${NETIFS[p2]}
177
178 swp3=${NETIFS[p3]}
179 h3=${NETIFS[p4]}
180
181 swp4=${NETIFS[p5]}
182 h4=${NETIFS[p6]}
183
184 vrf_prepare
185
186 ip link set dev $h1 up
187 h1_create
188 h2_create
189 h3_create
190 switch_create
191
192 trap_install $h3 ingress
193 trap_install $h4 ingress
194}
195
196cleanup()
197{
198 pre_cleanup
199
200 trap_uninstall $h4 ingress
201 trap_uninstall $h3 ingress
202
203 switch_destroy
204 h3_destroy
205 h2_destroy
206 h1_destroy
207 ip link set dev $h1 down
208
209 vrf_cleanup
210}
211
212test_lag_slave()
213{
214 local up_dev=$1; shift
215 local down_dev=$1; shift
216 local what=$1; shift
217
218 RET=0
219
220 mirror_install $swp1 ingress gt4 \
221 "proto 802.1q flower vlan_id 333 $tcflags"
222
223 # Move $down_dev away from the team. That will prompt change in
224 # txability of the connected device, without changing its upness. The
225 # driver should notice the txability change and move the traffic to the
226 # other slave.
227 ip link set dev $down_dev nomaster
228 sleep 2
229 mirror_test vrf-h1 192.0.2.1 192.0.2.18 $up_dev 1 10
230
231 # Test lack of connectivity when neither slave is txable.
232 ip link set dev $up_dev nomaster
233 sleep 2
234 mirror_test vrf-h1 192.0.2.1 192.0.2.18 $h3 1 0
235 mirror_test vrf-h1 192.0.2.1 192.0.2.18 $h4 1 0
236 mirror_uninstall $swp1 ingress
237
238 # Recreate H3's team device, because mlxsw, which this test is
239 # predominantly mean to test, requires a bottom-up construction and
240 # doesn't allow enslavement to a device that already has an upper.
241 h3_destroy_team
242 h3_create_team
243 # Wait for ${h,swp}{3,4}.
244 setup_wait
245
246 log_test "$what ($tcflags)"
247}
248
249test_mirror_gretap_first()
250{
251 test_lag_slave $h3 $h4 "mirror to gretap: LAG first slave"
252}
253
254test_mirror_gretap_second()
255{
256 test_lag_slave $h4 $h3 "mirror to gretap: LAG second slave"
257}
258
259test_all()
260{
261 slow_path_trap_install $swp1 ingress
262 slow_path_trap_install $swp1 egress
263
264 tests_run
265
266 slow_path_trap_uninstall $swp1 egress
267 slow_path_trap_uninstall $swp1 ingress
268}
269
270trap cleanup EXIT
271
272setup_prepare
273setup_wait
274
275tcflags="skip_hw"
276test_all
277
278if ! tc_offload_check; then
279 echo "WARN: Could not test offloaded functionality"
280else
281 tcflags="skip_sw"
282 test_all
283fi
284
285exit $EXIT_STATUS
diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_lib.sh b/tools/testing/selftests/net/forwarding/mirror_gre_lib.sh
index 619b469365be..fac486178ef7 100644
--- a/tools/testing/selftests/net/forwarding/mirror_gre_lib.sh
+++ b/tools/testing/selftests/net/forwarding/mirror_gre_lib.sh
@@ -1,6 +1,6 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2 2
3source mirror_lib.sh 3source "$relative_path/mirror_lib.sh"
4 4
5quick_test_span_gre_dir_ips() 5quick_test_span_gre_dir_ips()
6{ 6{
@@ -62,7 +62,7 @@ full_test_span_gre_dir_vlan_ips()
62 "$backward_type" "$ip1" "$ip2" 62 "$backward_type" "$ip1" "$ip2"
63 63
64 tc filter add dev $h3 ingress pref 77 prot 802.1q \ 64 tc filter add dev $h3 ingress pref 77 prot 802.1q \
65 flower $vlan_match ip_proto 0x2f \ 65 flower $vlan_match \
66 action pass 66 action pass
67 mirror_test v$h1 $ip1 $ip2 $h3 77 10 67 mirror_test v$h1 $ip1 $ip2 $h3 77 10
68 tc filter del dev $h3 ingress pref 77 68 tc filter del dev $h3 ingress pref 77
diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_nh.sh b/tools/testing/selftests/net/forwarding/mirror_gre_nh.sh
index 8fa681eb90e7..6f9ef1820e93 100755
--- a/tools/testing/selftests/net/forwarding/mirror_gre_nh.sh
+++ b/tools/testing/selftests/net/forwarding/mirror_gre_nh.sh
@@ -35,6 +35,8 @@ setup_prepare()
35 vrf_prepare 35 vrf_prepare
36 mirror_gre_topo_create 36 mirror_gre_topo_create
37 37
38 sysctl_set net.ipv4.conf.v$h3.rp_filter 0
39
38 ip address add dev $swp3 192.0.2.161/28 40 ip address add dev $swp3 192.0.2.161/28
39 ip address add dev $h3 192.0.2.162/28 41 ip address add dev $h3 192.0.2.162/28
40 ip address add dev gt4 192.0.2.129/32 42 ip address add dev gt4 192.0.2.129/32
@@ -61,6 +63,8 @@ cleanup()
61 ip address del dev $h3 192.0.2.162/28 63 ip address del dev $h3 192.0.2.162/28
62 ip address del dev $swp3 192.0.2.161/28 64 ip address del dev $swp3 192.0.2.161/28
63 65
66 sysctl_restore net.ipv4.conf.v$h3.rp_filter 0
67
64 mirror_gre_topo_destroy 68 mirror_gre_topo_destroy
65 vrf_cleanup 69 vrf_cleanup
66 70
diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_topo_lib.sh b/tools/testing/selftests/net/forwarding/mirror_gre_topo_lib.sh
index 253419564708..39c03e2867f4 100644
--- a/tools/testing/selftests/net/forwarding/mirror_gre_topo_lib.sh
+++ b/tools/testing/selftests/net/forwarding/mirror_gre_topo_lib.sh
@@ -33,7 +33,7 @@
33# | | 33# | |
34# +-------------------------------------------------------------------------+ 34# +-------------------------------------------------------------------------+
35 35
36source mirror_topo_lib.sh 36source "$relative_path/mirror_topo_lib.sh"
37 37
38mirror_gre_topo_h3_create() 38mirror_gre_topo_h3_create()
39{ 39{
diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_vlan_bridge_1q.sh b/tools/testing/selftests/net/forwarding/mirror_gre_vlan_bridge_1q.sh
index 5dbc7a08f4bd..204b25f13934 100755
--- a/tools/testing/selftests/net/forwarding/mirror_gre_vlan_bridge_1q.sh
+++ b/tools/testing/selftests/net/forwarding/mirror_gre_vlan_bridge_1q.sh
@@ -28,6 +28,8 @@ source mirror_lib.sh
28source mirror_gre_lib.sh 28source mirror_gre_lib.sh
29source mirror_gre_topo_lib.sh 29source mirror_gre_topo_lib.sh
30 30
31require_command $ARPING
32
31setup_prepare() 33setup_prepare()
32{ 34{
33 h1=${NETIFS[p1]} 35 h1=${NETIFS[p1]}
@@ -39,6 +41,12 @@ setup_prepare()
39 swp3=${NETIFS[p5]} 41 swp3=${NETIFS[p5]}
40 h3=${NETIFS[p6]} 42 h3=${NETIFS[p6]}
41 43
44 # gt4's remote address is at $h3.555, not $h3. Thus the packets arriving
45 # directly to $h3 for test_gretap_untagged_egress() are rejected by
46 # rp_filter and the test spuriously fails.
47 sysctl_set net.ipv4.conf.all.rp_filter 0
48 sysctl_set net.ipv4.conf.$h3.rp_filter 0
49
42 vrf_prepare 50 vrf_prepare
43 mirror_gre_topo_create 51 mirror_gre_topo_create
44 52
@@ -65,6 +73,9 @@ cleanup()
65 73
66 mirror_gre_topo_destroy 74 mirror_gre_topo_destroy
67 vrf_cleanup 75 vrf_cleanup
76
77 sysctl_restore net.ipv4.conf.$h3.rp_filter
78 sysctl_restore net.ipv4.conf.all.rp_filter
68} 79}
69 80
70test_vlan_match() 81test_vlan_match()
@@ -79,12 +90,14 @@ test_vlan_match()
79 90
80test_gretap() 91test_gretap()
81{ 92{
82 test_vlan_match gt4 'vlan_id 555 vlan_ethtype ip' "mirror to gretap" 93 test_vlan_match gt4 'skip_hw vlan_id 555 vlan_ethtype ip' \
94 "mirror to gretap"
83} 95}
84 96
85test_ip6gretap() 97test_ip6gretap()
86{ 98{
87 test_vlan_match gt6 'vlan_id 555 vlan_ethtype ipv6' "mirror to ip6gretap" 99 test_vlan_match gt6 'skip_hw vlan_id 555 vlan_ethtype ip' \
100 "mirror to ip6gretap"
88} 101}
89 102
90test_span_gre_forbidden_cpu() 103test_span_gre_forbidden_cpu()
@@ -138,7 +151,7 @@ test_span_gre_forbidden_egress()
138 151
139 bridge vlan add dev $swp3 vid 555 152 bridge vlan add dev $swp3 vid 555
140 # Re-prime FDB 153 # Re-prime FDB
141 arping -I br1.555 192.0.2.130 -fqc 1 154 $ARPING -I br1.555 192.0.2.130 -fqc 1
142 sleep 1 155 sleep 1
143 quick_test_span_gre_dir $tundev ingress 156 quick_test_span_gre_dir $tundev ingress
144 157
@@ -212,7 +225,7 @@ test_span_gre_fdb_roaming()
212 225
213 bridge fdb del dev $swp2 $h3mac vlan 555 master 226 bridge fdb del dev $swp2 $h3mac vlan 555 master
214 # Re-prime FDB 227 # Re-prime FDB
215 arping -I br1.555 192.0.2.130 -fqc 1 228 $ARPING -I br1.555 192.0.2.130 -fqc 1
216 sleep 1 229 sleep 1
217 quick_test_span_gre_dir $tundev ingress 230 quick_test_span_gre_dir $tundev ingress
218 231
diff --git a/tools/testing/selftests/net/forwarding/mirror_lib.sh b/tools/testing/selftests/net/forwarding/mirror_lib.sh
index d36dc26c6c51..07991e1025c7 100644
--- a/tools/testing/selftests/net/forwarding/mirror_lib.sh
+++ b/tools/testing/selftests/net/forwarding/mirror_lib.sh
@@ -105,7 +105,7 @@ do_test_span_vlan_dir_ips()
105 # Install the capture as skip_hw to avoid double-counting of packets. 105 # Install the capture as skip_hw to avoid double-counting of packets.
106 # The traffic is meant for local box anyway, so will be trapped to 106 # The traffic is meant for local box anyway, so will be trapped to
107 # kernel. 107 # kernel.
108 vlan_capture_install $dev "skip_hw vlan_id $vid" 108 vlan_capture_install $dev "skip_hw vlan_id $vid vlan_ethtype ip"
109 mirror_test v$h1 $ip1 $ip2 $dev 100 $expect 109 mirror_test v$h1 $ip1 $ip2 $dev 100 $expect
110 mirror_test v$h2 $ip2 $ip1 $dev 100 $expect 110 mirror_test v$h2 $ip2 $ip1 $dev 100 $expect
111 vlan_capture_uninstall $dev 111 vlan_capture_uninstall $dev
diff --git a/tools/testing/selftests/net/forwarding/router_bridge.sh b/tools/testing/selftests/net/forwarding/router_bridge.sh
new file mode 100755
index 000000000000..ebc596a272f7
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/router_bridge.sh
@@ -0,0 +1,113 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4ALL_TESTS="
5 ping_ipv4
6 ping_ipv6
7"
8NUM_NETIFS=4
9source lib.sh
10
11h1_create()
12{
13 simple_if_init $h1 192.0.2.1/28 2001:db8:1::1/64
14 ip -4 route add 192.0.2.128/28 vrf v$h1 nexthop via 192.0.2.2
15 ip -6 route add 2001:db8:2::/64 vrf v$h1 nexthop via 2001:db8:1::2
16}
17
18h1_destroy()
19{
20 ip -6 route del 2001:db8:2::/64 vrf v$h1
21 ip -4 route del 192.0.2.128/28 vrf v$h1
22 simple_if_fini $h1 192.0.2.1/28 2001:db8:1::1/64
23}
24
25h2_create()
26{
27 simple_if_init $h2 192.0.2.130/28 2001:db8:2::2/64
28 ip -4 route add 192.0.2.0/28 vrf v$h2 nexthop via 192.0.2.129
29 ip -6 route add 2001:db8:1::/64 vrf v$h2 nexthop via 2001:db8:2::1
30}
31
32h2_destroy()
33{
34 ip -6 route del 2001:db8:1::/64 vrf v$h2
35 ip -4 route del 192.0.2.0/28 vrf v$h2
36 simple_if_fini $h2 192.0.2.130/28 2001:db8:2::2/64
37}
38
39router_create()
40{
41 ip link add name br1 type bridge vlan_filtering 1
42 ip link set dev br1 up
43
44 ip link set dev $swp1 master br1
45 ip link set dev $swp1 up
46 __addr_add_del br1 add 192.0.2.2/28 2001:db8:1::2/64
47
48 ip link set dev $swp2 up
49 __addr_add_del $swp2 add 192.0.2.129/28 2001:db8:2::1/64
50}
51
52router_destroy()
53{
54 __addr_add_del $swp2 del 192.0.2.129/28 2001:db8:2::1/64
55 ip link set dev $swp2 down
56
57 __addr_add_del br1 del 192.0.2.2/28 2001:db8:1::2/64
58 ip link set dev $swp1 down
59 ip link set dev $swp1 nomaster
60
61 ip link del dev br1
62}
63
64setup_prepare()
65{
66 h1=${NETIFS[p1]}
67 swp1=${NETIFS[p2]}
68
69 swp2=${NETIFS[p3]}
70 h2=${NETIFS[p4]}
71
72 vrf_prepare
73
74 h1_create
75 h2_create
76
77 router_create
78
79 forwarding_enable
80}
81
82cleanup()
83{
84 pre_cleanup
85
86 forwarding_restore
87
88 router_destroy
89
90 h2_destroy
91 h1_destroy
92
93 vrf_cleanup
94}
95
96ping_ipv4()
97{
98 ping_test $h1 192.0.2.130
99}
100
101ping_ipv6()
102{
103 ping6_test $h1 2001:db8:2::2
104}
105
106trap cleanup EXIT
107
108setup_prepare
109setup_wait
110
111tests_run
112
113exit $EXIT_STATUS
diff --git a/tools/testing/selftests/net/forwarding/router_bridge_vlan.sh b/tools/testing/selftests/net/forwarding/router_bridge_vlan.sh
new file mode 100755
index 000000000000..fef88eb4b873
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/router_bridge_vlan.sh
@@ -0,0 +1,132 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4ALL_TESTS="
5 ping_ipv4
6 ping_ipv6
7 vlan
8"
9NUM_NETIFS=4
10source lib.sh
11
12h1_create()
13{
14 simple_if_init $h1
15 vlan_create $h1 555 v$h1 192.0.2.1/28 2001:db8:1::1/64
16 ip -4 route add 192.0.2.128/28 vrf v$h1 nexthop via 192.0.2.2
17 ip -6 route add 2001:db8:2::/64 vrf v$h1 nexthop via 2001:db8:1::2
18}
19
20h1_destroy()
21{
22 ip -6 route del 2001:db8:2::/64 vrf v$h1
23 ip -4 route del 192.0.2.128/28 vrf v$h1
24 vlan_destroy $h1 555
25 simple_if_fini $h1
26}
27
28h2_create()
29{
30 simple_if_init $h2 192.0.2.130/28 2001:db8:2::2/64
31 ip -4 route add 192.0.2.0/28 vrf v$h2 nexthop via 192.0.2.129
32 ip -6 route add 2001:db8:1::/64 vrf v$h2 nexthop via 2001:db8:2::1
33}
34
35h2_destroy()
36{
37 ip -6 route del 2001:db8:1::/64 vrf v$h2
38 ip -4 route del 192.0.2.0/28 vrf v$h2
39 simple_if_fini $h2 192.0.2.130/28
40}
41
42router_create()
43{
44 ip link add name br1 type bridge vlan_filtering 1
45 ip link set dev br1 up
46
47 ip link set dev $swp1 master br1
48 ip link set dev $swp1 up
49
50 bridge vlan add dev br1 vid 555 self pvid untagged
51 bridge vlan add dev $swp1 vid 555
52
53 __addr_add_del br1 add 192.0.2.2/28 2001:db8:1::2/64
54
55 ip link set dev $swp2 up
56 __addr_add_del $swp2 add 192.0.2.129/28 2001:db8:2::1/64
57}
58
59router_destroy()
60{
61 __addr_add_del $swp2 del 192.0.2.129/28 2001:db8:2::1/64
62 ip link set dev $swp2 down
63
64 __addr_add_del br1 del 192.0.2.2/28 2001:db8:1::2/64
65 ip link set dev $swp1 down
66 ip link set dev $swp1 nomaster
67
68 ip link del dev br1
69}
70
71setup_prepare()
72{
73 h1=${NETIFS[p1]}
74 swp1=${NETIFS[p2]}
75
76 swp2=${NETIFS[p3]}
77 h2=${NETIFS[p4]}
78
79 vrf_prepare
80
81 h1_create
82 h2_create
83
84 router_create
85
86 forwarding_enable
87}
88
89cleanup()
90{
91 pre_cleanup
92
93 forwarding_restore
94
95 router_destroy
96
97 h2_destroy
98 h1_destroy
99
100 vrf_cleanup
101}
102
103vlan()
104{
105 RET=0
106
107 bridge vlan add dev br1 vid 333 self
108 check_err $? "Can't add a non-PVID VLAN"
109 bridge vlan del dev br1 vid 333 self
110 check_err $? "Can't remove a non-PVID VLAN"
111
112 log_test "vlan"
113}
114
115ping_ipv4()
116{
117 ping_test $h1 192.0.2.130
118}
119
120ping_ipv6()
121{
122 ping6_test $h1 2001:db8:2::2
123}
124
125trap cleanup EXIT
126
127setup_prepare
128setup_wait
129
130tests_run
131
132exit $EXIT_STATUS
diff --git a/tools/testing/selftests/net/forwarding/router_broadcast.sh b/tools/testing/selftests/net/forwarding/router_broadcast.sh
new file mode 100755
index 000000000000..7bd2ebb6e9de
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/router_broadcast.sh
@@ -0,0 +1,233 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4ALL_TESTS="ping_ipv4"
5NUM_NETIFS=6
6source lib.sh
7
8h1_create()
9{
10 vrf_create "vrf-h1"
11 ip link set dev $h1 master vrf-h1
12
13 ip link set dev vrf-h1 up
14 ip link set dev $h1 up
15
16 ip address add 192.0.2.2/24 dev $h1
17
18 ip route add 198.51.100.0/24 vrf vrf-h1 nexthop via 192.0.2.1
19 ip route add 198.51.200.0/24 vrf vrf-h1 nexthop via 192.0.2.1
20}
21
22h1_destroy()
23{
24 ip route del 198.51.200.0/24 vrf vrf-h1
25 ip route del 198.51.100.0/24 vrf vrf-h1
26
27 ip address del 192.0.2.2/24 dev $h1
28
29 ip link set dev $h1 down
30 vrf_destroy "vrf-h1"
31}
32
33h2_create()
34{
35 vrf_create "vrf-h2"
36 ip link set dev $h2 master vrf-h2
37
38 ip link set dev vrf-h2 up
39 ip link set dev $h2 up
40
41 ip address add 198.51.100.2/24 dev $h2
42
43 ip route add 192.0.2.0/24 vrf vrf-h2 nexthop via 198.51.100.1
44 ip route add 198.51.200.0/24 vrf vrf-h2 nexthop via 198.51.100.1
45}
46
47h2_destroy()
48{
49 ip route del 198.51.200.0/24 vrf vrf-h2
50 ip route del 192.0.2.0/24 vrf vrf-h2
51
52 ip address del 198.51.100.2/24 dev $h2
53
54 ip link set dev $h2 down
55 vrf_destroy "vrf-h2"
56}
57
58h3_create()
59{
60 vrf_create "vrf-h3"
61 ip link set dev $h3 master vrf-h3
62
63 ip link set dev vrf-h3 up
64 ip link set dev $h3 up
65
66 ip address add 198.51.200.2/24 dev $h3
67
68 ip route add 192.0.2.0/24 vrf vrf-h3 nexthop via 198.51.200.1
69 ip route add 198.51.100.0/24 vrf vrf-h3 nexthop via 198.51.200.1
70}
71
72h3_destroy()
73{
74 ip route del 198.51.100.0/24 vrf vrf-h3
75 ip route del 192.0.2.0/24 vrf vrf-h3
76
77 ip address del 198.51.200.2/24 dev $h3
78
79 ip link set dev $h3 down
80 vrf_destroy "vrf-h3"
81}
82
83router_create()
84{
85 ip link set dev $rp1 up
86 ip link set dev $rp2 up
87 ip link set dev $rp3 up
88
89 ip address add 192.0.2.1/24 dev $rp1
90
91 ip address add 198.51.100.1/24 dev $rp2
92 ip address add 198.51.200.1/24 dev $rp3
93}
94
95router_destroy()
96{
97 ip address del 198.51.200.1/24 dev $rp3
98 ip address del 198.51.100.1/24 dev $rp2
99
100 ip address del 192.0.2.1/24 dev $rp1
101
102 ip link set dev $rp3 down
103 ip link set dev $rp2 down
104 ip link set dev $rp1 down
105}
106
107setup_prepare()
108{
109 h1=${NETIFS[p1]}
110 rp1=${NETIFS[p2]}
111
112 rp2=${NETIFS[p3]}
113 h2=${NETIFS[p4]}
114
115 rp3=${NETIFS[p5]}
116 h3=${NETIFS[p6]}
117
118 vrf_prepare
119
120 h1_create
121 h2_create
122 h3_create
123
124 router_create
125
126 forwarding_enable
127}
128
129cleanup()
130{
131 pre_cleanup
132
133 forwarding_restore
134
135 router_destroy
136
137 h3_destroy
138 h2_destroy
139 h1_destroy
140
141 vrf_cleanup
142}
143
144bc_forwarding_disable()
145{
146 sysctl_set net.ipv4.conf.all.bc_forwarding 0
147 sysctl_set net.ipv4.conf.$rp1.bc_forwarding 0
148}
149
150bc_forwarding_enable()
151{
152 sysctl_set net.ipv4.conf.all.bc_forwarding 1
153 sysctl_set net.ipv4.conf.$rp1.bc_forwarding 1
154}
155
156bc_forwarding_restore()
157{
158 sysctl_restore net.ipv4.conf.$rp1.bc_forwarding
159 sysctl_restore net.ipv4.conf.all.bc_forwarding
160}
161
162ping_test_from()
163{
164 local oif=$1
165 local dip=$2
166 local from=$3
167 local fail=${4:-0}
168
169 RET=0
170
171 log_info "ping $dip, expected reply from $from"
172 ip vrf exec $(master_name_get $oif) \
173 $PING -I $oif $dip -c 10 -i 0.1 -w 2 -b 2>&1 | grep $from &> /dev/null
174 check_err_fail $fail $?
175}
176
177ping_ipv4()
178{
179 sysctl_set net.ipv4.icmp_echo_ignore_broadcasts 0
180
181 bc_forwarding_disable
182 log_info "bc_forwarding disabled on r1 =>"
183 ping_test_from $h1 198.51.100.255 192.0.2.1
184 log_test "h1 -> net2: reply from r1 (not forwarding)"
185 ping_test_from $h1 198.51.200.255 192.0.2.1
186 log_test "h1 -> net3: reply from r1 (not forwarding)"
187 ping_test_from $h1 192.0.2.255 192.0.2.1
188 log_test "h1 -> net1: reply from r1 (not dropping)"
189 ping_test_from $h1 255.255.255.255 192.0.2.1
190 log_test "h1 -> 255.255.255.255: reply from r1 (not forwarding)"
191
192 ping_test_from $h2 192.0.2.255 198.51.100.1
193 log_test "h2 -> net1: reply from r1 (not forwarding)"
194 ping_test_from $h2 198.51.200.255 198.51.100.1
195 log_test "h2 -> net3: reply from r1 (not forwarding)"
196 ping_test_from $h2 198.51.100.255 198.51.100.1
197 log_test "h2 -> net2: reply from r1 (not dropping)"
198 ping_test_from $h2 255.255.255.255 198.51.100.1
199 log_test "h2 -> 255.255.255.255: reply from r1 (not forwarding)"
200 bc_forwarding_restore
201
202 bc_forwarding_enable
203 log_info "bc_forwarding enabled on r1 =>"
204 ping_test_from $h1 198.51.100.255 198.51.100.2
205 log_test "h1 -> net2: reply from h2 (forwarding)"
206 ping_test_from $h1 198.51.200.255 198.51.200.2
207 log_test "h1 -> net3: reply from h3 (forwarding)"
208 ping_test_from $h1 192.0.2.255 192.0.2.1 1
209 log_test "h1 -> net1: no reply (dropping)"
210 ping_test_from $h1 255.255.255.255 192.0.2.1
211 log_test "h1 -> 255.255.255.255: reply from r1 (not forwarding)"
212
213 ping_test_from $h2 192.0.2.255 192.0.2.2
214 log_test "h2 -> net1: reply from h1 (forwarding)"
215 ping_test_from $h2 198.51.200.255 198.51.200.2
216 log_test "h2 -> net3: reply from h3 (forwarding)"
217 ping_test_from $h2 198.51.100.255 198.51.100.1 1
218 log_test "h2 -> net2: no reply (dropping)"
219 ping_test_from $h2 255.255.255.255 198.51.100.1
220 log_test "h2 -> 255.255.255.255: reply from r1 (not forwarding)"
221 bc_forwarding_restore
222
223 sysctl_restore net.ipv4.icmp_echo_ignore_broadcasts
224}
225
226trap cleanup EXIT
227
228setup_prepare
229setup_wait
230
231tests_run
232
233exit $EXIT_STATUS
diff --git a/tools/testing/selftests/net/forwarding/router_multipath.sh b/tools/testing/selftests/net/forwarding/router_multipath.sh
index 8b6d0fb6d604..79a209927962 100755
--- a/tools/testing/selftests/net/forwarding/router_multipath.sh
+++ b/tools/testing/selftests/net/forwarding/router_multipath.sh
@@ -159,45 +159,6 @@ router2_destroy()
159 vrf_destroy "vrf-r2" 159 vrf_destroy "vrf-r2"
160} 160}
161 161
162multipath_eval()
163{
164 local desc="$1"
165 local weight_rp12=$2
166 local weight_rp13=$3
167 local packets_rp12=$4
168 local packets_rp13=$5
169 local weights_ratio packets_ratio diff
170
171 RET=0
172
173 if [[ "$packets_rp12" -eq "0" || "$packets_rp13" -eq "0" ]]; then
174 check_err 1 "Packet difference is 0"
175 log_test "Multipath"
176 log_info "Expected ratio $weights_ratio"
177 return
178 fi
179
180 if [[ "$weight_rp12" -gt "$weight_rp13" ]]; then
181 weights_ratio=$(echo "scale=2; $weight_rp12 / $weight_rp13" \
182 | bc -l)
183 packets_ratio=$(echo "scale=2; $packets_rp12 / $packets_rp13" \
184 | bc -l)
185 else
186 weights_ratio=$(echo "scale=2; $weight_rp13 / $weight_rp12" | \
187 bc -l)
188 packets_ratio=$(echo "scale=2; $packets_rp13 / $packets_rp12" | \
189 bc -l)
190 fi
191
192 diff=$(echo $weights_ratio - $packets_ratio | bc -l)
193 diff=${diff#-}
194
195 test "$(echo "$diff / $weights_ratio > 0.15" | bc -l)" -eq 0
196 check_err $? "Too large discrepancy between expected and measured ratios"
197 log_test "$desc"
198 log_info "Expected ratio $weights_ratio Measured ratio $packets_ratio"
199}
200
201multipath4_test() 162multipath4_test()
202{ 163{
203 local desc="$1" 164 local desc="$1"
diff --git a/tools/testing/selftests/net/forwarding/tc_chains.sh b/tools/testing/selftests/net/forwarding/tc_chains.sh
index d2c783e94df3..2934fb5ed2a2 100755
--- a/tools/testing/selftests/net/forwarding/tc_chains.sh
+++ b/tools/testing/selftests/net/forwarding/tc_chains.sh
@@ -1,7 +1,8 @@
1#!/bin/bash 1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0 2# SPDX-License-Identifier: GPL-2.0
3 3
4ALL_TESTS="unreachable_chain_test gact_goto_chain_test" 4ALL_TESTS="unreachable_chain_test gact_goto_chain_test create_destroy_chain \
5 template_filter_fits"
5NUM_NETIFS=2 6NUM_NETIFS=2
6source tc_common.sh 7source tc_common.sh
7source lib.sh 8source lib.sh
@@ -80,6 +81,87 @@ gact_goto_chain_test()
80 log_test "gact goto chain ($tcflags)" 81 log_test "gact goto chain ($tcflags)"
81} 82}
82 83
84create_destroy_chain()
85{
86 RET=0
87
88 tc chain add dev $h2 ingress
89 check_err $? "Failed to create default chain"
90
91 output="$(tc -j chain get dev $h2 ingress)"
92 check_err $? "Failed to get default chain"
93
94 echo $output | jq -e ".[] | select(.chain == 0)" &> /dev/null
95 check_err $? "Unexpected output for default chain"
96
97 tc chain add dev $h2 ingress chain 1
98 check_err $? "Failed to create chain 1"
99
100 output="$(tc -j chain get dev $h2 ingress chain 1)"
101 check_err $? "Failed to get chain 1"
102
103 echo $output | jq -e ".[] | select(.chain == 1)" &> /dev/null
104 check_err $? "Unexpected output for chain 1"
105
106 output="$(tc -j chain show dev $h2 ingress)"
107 check_err $? "Failed to dump chains"
108
109 echo $output | jq -e ".[] | select(.chain == 0)" &> /dev/null
110 check_err $? "Can't find default chain in dump"
111
112 echo $output | jq -e ".[] | select(.chain == 1)" &> /dev/null
113 check_err $? "Can't find chain 1 in dump"
114
115 tc chain del dev $h2 ingress
116 check_err $? "Failed to destroy default chain"
117
118 tc chain del dev $h2 ingress chain 1
119 check_err $? "Failed to destroy chain 1"
120
121 log_test "create destroy chain"
122}
123
124template_filter_fits()
125{
126 RET=0
127
128 tc chain add dev $h2 ingress protocol ip \
129 flower dst_mac 00:00:00:00:00:00/FF:FF:FF:FF:FF:FF &> /dev/null
130 tc chain add dev $h2 ingress chain 1 protocol ip \
131 flower src_mac 00:00:00:00:00:00/FF:FF:FF:FF:FF:FF &> /dev/null
132
133 tc filter add dev $h2 ingress protocol ip pref 1 handle 1101 \
134 flower dst_mac $h2mac action drop
135 check_err $? "Failed to insert filter which fits template"
136
137 tc filter add dev $h2 ingress protocol ip pref 1 handle 1102 \
138 flower src_mac $h2mac action drop &> /dev/null
139 check_fail $? "Incorrectly succeded to insert filter which does not template"
140
141 tc filter add dev $h2 ingress chain 1 protocol ip pref 1 handle 1101 \
142 flower src_mac $h2mac action drop
143 check_err $? "Failed to insert filter which fits template"
144
145 tc filter add dev $h2 ingress chain 1 protocol ip pref 1 handle 1102 \
146 flower dst_mac $h2mac action drop &> /dev/null
147 check_fail $? "Incorrectly succeded to insert filter which does not template"
148
149 tc filter del dev $h2 ingress chain 1 protocol ip pref 1 handle 1102 \
150 flower &> /dev/null
151 tc filter del dev $h2 ingress chain 1 protocol ip pref 1 handle 1101 \
152 flower &> /dev/null
153
154 tc filter del dev $h2 ingress protocol ip pref 1 handle 1102 \
155 flower &> /dev/null
156 tc filter del dev $h2 ingress protocol ip pref 1 handle 1101 \
157 flower &> /dev/null
158
159 tc chain del dev $h2 ingress chain 1
160 tc chain del dev $h2 ingress
161
162 log_test "template filter fits"
163}
164
83setup_prepare() 165setup_prepare()
84{ 166{
85 h1=${NETIFS[p1]} 167 h1=${NETIFS[p1]}
@@ -103,6 +185,8 @@ cleanup()
103 vrf_cleanup 185 vrf_cleanup
104} 186}
105 187
188check_tc_chain_support
189
106trap cleanup EXIT 190trap cleanup EXIT
107 191
108setup_prepare 192setup_prepare
diff --git a/tools/testing/selftests/net/forwarding/tc_shblocks.sh b/tools/testing/selftests/net/forwarding/tc_shblocks.sh
index b5b917203815..9826a446e2c0 100755
--- a/tools/testing/selftests/net/forwarding/tc_shblocks.sh
+++ b/tools/testing/selftests/net/forwarding/tc_shblocks.sh
@@ -105,6 +105,8 @@ cleanup()
105 ip link set $swp2 address $swp2origmac 105 ip link set $swp2 address $swp2origmac
106} 106}
107 107
108check_tc_shblock_support
109
108trap cleanup EXIT 110trap cleanup EXIT
109 111
110setup_prepare 112setup_prepare
diff --git a/tools/testing/selftests/net/ip6_gre_headroom.sh b/tools/testing/selftests/net/ip6_gre_headroom.sh
new file mode 100755
index 000000000000..5b41e8bb6e2d
--- /dev/null
+++ b/tools/testing/selftests/net/ip6_gre_headroom.sh
@@ -0,0 +1,65 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3#
4# Test that enough headroom is reserved for the first packet passing through an
5# IPv6 GRE-like netdevice.
6
7setup_prepare()
8{
9 ip link add h1 type veth peer name swp1
10 ip link add h3 type veth peer name swp3
11
12 ip link set dev h1 up
13 ip address add 192.0.2.1/28 dev h1
14
15 ip link add dev vh3 type vrf table 20
16 ip link set dev h3 master vh3
17 ip link set dev vh3 up
18 ip link set dev h3 up
19
20 ip link set dev swp3 up
21 ip address add dev swp3 2001:db8:2::1/64
22 ip address add dev swp3 2001:db8:2::3/64
23
24 ip link set dev swp1 up
25 tc qdisc add dev swp1 clsact
26
27 ip link add name er6 type ip6erspan \
28 local 2001:db8:2::1 remote 2001:db8:2::2 oseq okey 123
29 ip link set dev er6 up
30
31 ip link add name gt6 type ip6gretap \
32 local 2001:db8:2::3 remote 2001:db8:2::4
33 ip link set dev gt6 up
34
35 sleep 1
36}
37
38cleanup()
39{
40 ip link del dev gt6
41 ip link del dev er6
42 ip link del dev swp1
43 ip link del dev swp3
44 ip link del dev vh3
45}
46
47test_headroom()
48{
49 local type=$1; shift
50 local tundev=$1; shift
51
52 tc filter add dev swp1 ingress pref 1000 matchall skip_hw \
53 action mirred egress mirror dev $tundev
54 ping -I h1 192.0.2.2 -c 1 -w 2 &> /dev/null
55 tc filter del dev swp1 ingress pref 1000
56
57 # If it doesn't panic, it passes.
58 printf "TEST: %-60s [PASS]\n" "$type headroom"
59}
60
61trap cleanup EXIT
62
63setup_prepare
64test_headroom ip6gretap gt6
65test_headroom ip6erspan er6
diff --git a/tools/testing/selftests/net/rtnetlink.sh b/tools/testing/selftests/net/rtnetlink.sh
index 0d7a44fa30af..08c341b49760 100755
--- a/tools/testing/selftests/net/rtnetlink.sh
+++ b/tools/testing/selftests/net/rtnetlink.sh
@@ -525,18 +525,21 @@ kci_test_macsec()
525#------------------------------------------------------------------- 525#-------------------------------------------------------------------
526kci_test_ipsec() 526kci_test_ipsec()
527{ 527{
528 srcip="14.0.0.52" 528 ret=0
529 dstip="14.0.0.70"
530 algo="aead rfc4106(gcm(aes)) 0x3132333435363738393031323334353664636261 128" 529 algo="aead rfc4106(gcm(aes)) 0x3132333435363738393031323334353664636261 128"
530 srcip=192.168.123.1
531 dstip=192.168.123.2
532 spi=7
533
534 ip addr add $srcip dev $devdummy
531 535
532 # flush to be sure there's nothing configured 536 # flush to be sure there's nothing configured
533 ip x s flush ; ip x p flush 537 ip x s flush ; ip x p flush
534 check_err $? 538 check_err $?
535 539
536 # start the monitor in the background 540 # start the monitor in the background
537 tmpfile=`mktemp ipsectestXXX` 541 tmpfile=`mktemp /var/run/ipsectestXXX`
538 ip x m > $tmpfile & 542 mpid=`(ip x m > $tmpfile & echo $!) 2>/dev/null`
539 mpid=$!
540 sleep 0.2 543 sleep 0.2
541 544
542 ipsecid="proto esp src $srcip dst $dstip spi 0x07" 545 ipsecid="proto esp src $srcip dst $dstip spi 0x07"
@@ -599,6 +602,7 @@ kci_test_ipsec()
599 check_err $? 602 check_err $?
600 ip x p flush 603 ip x p flush
601 check_err $? 604 check_err $?
605 ip addr del $srcip/32 dev $devdummy
602 606
603 if [ $ret -ne 0 ]; then 607 if [ $ret -ne 0 ]; then
604 echo "FAIL: ipsec" 608 echo "FAIL: ipsec"
@@ -607,6 +611,119 @@ kci_test_ipsec()
607 echo "PASS: ipsec" 611 echo "PASS: ipsec"
608} 612}
609 613
614#-------------------------------------------------------------------
615# Example commands
616# ip x s add proto esp src 14.0.0.52 dst 14.0.0.70 \
617# spi 0x07 mode transport reqid 0x07 replay-window 32 \
618# aead 'rfc4106(gcm(aes))' 1234567890123456dcba 128 \
619# sel src 14.0.0.52/24 dst 14.0.0.70/24
620# offload dev sim1 dir out
621# ip x p add dir out src 14.0.0.52/24 dst 14.0.0.70/24 \
622# tmpl proto esp src 14.0.0.52 dst 14.0.0.70 \
623# spi 0x07 mode transport reqid 0x07
624#
625#-------------------------------------------------------------------
626kci_test_ipsec_offload()
627{
628 ret=0
629 algo="aead rfc4106(gcm(aes)) 0x3132333435363738393031323334353664636261 128"
630 srcip=192.168.123.3
631 dstip=192.168.123.4
632 dev=simx1
633 sysfsd=/sys/kernel/debug/netdevsim/$dev
634 sysfsf=$sysfsd/ipsec
635
636 # setup netdevsim since dummydev doesn't have offload support
637 modprobe netdevsim
638 check_err $?
639 if [ $ret -ne 0 ]; then
640 echo "FAIL: ipsec_offload can't load netdevsim"
641 return 1
642 fi
643
644 ip link add $dev type netdevsim
645 ip addr add $srcip dev $dev
646 ip link set $dev up
647 if [ ! -d $sysfsd ] ; then
648 echo "FAIL: ipsec_offload can't create device $dev"
649 return 1
650 fi
651 if [ ! -f $sysfsf ] ; then
652 echo "FAIL: ipsec_offload netdevsim doesn't support IPsec offload"
653 return 1
654 fi
655
656 # flush to be sure there's nothing configured
657 ip x s flush ; ip x p flush
658
659 # create offloaded SAs, both in and out
660 ip x p add dir out src $srcip/24 dst $dstip/24 \
661 tmpl proto esp src $srcip dst $dstip spi 9 \
662 mode transport reqid 42
663 check_err $?
664 ip x p add dir out src $dstip/24 dst $srcip/24 \
665 tmpl proto esp src $dstip dst $srcip spi 9 \
666 mode transport reqid 42
667 check_err $?
668
669 ip x s add proto esp src $srcip dst $dstip spi 9 \
670 mode transport reqid 42 $algo sel src $srcip/24 dst $dstip/24 \
671 offload dev $dev dir out
672 check_err $?
673 ip x s add proto esp src $dstip dst $srcip spi 9 \
674 mode transport reqid 42 $algo sel src $dstip/24 dst $srcip/24 \
675 offload dev $dev dir in
676 check_err $?
677 if [ $ret -ne 0 ]; then
678 echo "FAIL: ipsec_offload can't create SA"
679 return 1
680 fi
681
682 # does offload show up in ip output
683 lines=`ip x s list | grep -c "crypto offload parameters: dev $dev dir"`
684 if [ $lines -ne 2 ] ; then
685 echo "FAIL: ipsec_offload SA offload missing from list output"
686 check_err 1
687 fi
688
689 # use ping to exercise the Tx path
690 ping -I $dev -c 3 -W 1 -i 0 $dstip >/dev/null
691
692 # does driver have correct offload info
693 diff $sysfsf - << EOF
694SA count=2 tx=3
695sa[0] tx ipaddr=0x00000000 00000000 00000000 00000000
696sa[0] spi=0x00000009 proto=0x32 salt=0x61626364 crypt=1
697sa[0] key=0x34333231 38373635 32313039 36353433
698sa[1] rx ipaddr=0x00000000 00000000 00000000 037ba8c0
699sa[1] spi=0x00000009 proto=0x32 salt=0x61626364 crypt=1
700sa[1] key=0x34333231 38373635 32313039 36353433
701EOF
702 if [ $? -ne 0 ] ; then
703 echo "FAIL: ipsec_offload incorrect driver data"
704 check_err 1
705 fi
706
707 # does offload get removed from driver
708 ip x s flush
709 ip x p flush
710 lines=`grep -c "SA count=0" $sysfsf`
711 if [ $lines -ne 1 ] ; then
712 echo "FAIL: ipsec_offload SA not removed from driver"
713 check_err 1
714 fi
715
716 # clean up any leftovers
717 ip link del $dev
718 rmmod netdevsim
719
720 if [ $ret -ne 0 ]; then
721 echo "FAIL: ipsec_offload"
722 return 1
723 fi
724 echo "PASS: ipsec_offload"
725}
726
610kci_test_gretap() 727kci_test_gretap()
611{ 728{
612 testns="testns" 729 testns="testns"
@@ -861,6 +978,7 @@ kci_test_rtnl()
861 kci_test_encap 978 kci_test_encap
862 kci_test_macsec 979 kci_test_macsec
863 kci_test_ipsec 980 kci_test_ipsec
981 kci_test_ipsec_offload
864 982
865 kci_del_dummy 983 kci_del_dummy
866} 984}
diff --git a/tools/testing/selftests/net/tls.c b/tools/testing/selftests/net/tls.c
new file mode 100644
index 000000000000..b3ebf2646e52
--- /dev/null
+++ b/tools/testing/selftests/net/tls.c
@@ -0,0 +1,692 @@
1// SPDX-License-Identifier: GPL-2.0
2
3#define _GNU_SOURCE
4
5#include <arpa/inet.h>
6#include <errno.h>
7#include <error.h>
8#include <fcntl.h>
9#include <poll.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <unistd.h>
13
14#include <linux/tls.h>
15#include <linux/tcp.h>
16#include <linux/socket.h>
17
18#include <sys/types.h>
19#include <sys/sendfile.h>
20#include <sys/socket.h>
21#include <sys/stat.h>
22
23#include "../kselftest_harness.h"
24
25#define TLS_PAYLOAD_MAX_LEN 16384
26#define SOL_TLS 282
27
28FIXTURE(tls)
29{
30 int fd, cfd;
31 bool notls;
32};
33
34FIXTURE_SETUP(tls)
35{
36 struct tls12_crypto_info_aes_gcm_128 tls12;
37 struct sockaddr_in addr;
38 socklen_t len;
39 int sfd, ret;
40
41 self->notls = false;
42 len = sizeof(addr);
43
44 memset(&tls12, 0, sizeof(tls12));
45 tls12.info.version = TLS_1_2_VERSION;
46 tls12.info.cipher_type = TLS_CIPHER_AES_GCM_128;
47
48 addr.sin_family = AF_INET;
49 addr.sin_addr.s_addr = htonl(INADDR_ANY);
50 addr.sin_port = 0;
51
52 self->fd = socket(AF_INET, SOCK_STREAM, 0);
53 sfd = socket(AF_INET, SOCK_STREAM, 0);
54
55 ret = bind(sfd, &addr, sizeof(addr));
56 ASSERT_EQ(ret, 0);
57 ret = listen(sfd, 10);
58 ASSERT_EQ(ret, 0);
59
60 ret = getsockname(sfd, &addr, &len);
61 ASSERT_EQ(ret, 0);
62
63 ret = connect(self->fd, &addr, sizeof(addr));
64 ASSERT_EQ(ret, 0);
65
66 ret = setsockopt(self->fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
67 if (ret != 0) {
68 self->notls = true;
69 printf("Failure setting TCP_ULP, testing without tls\n");
70 }
71
72 if (!self->notls) {
73 ret = setsockopt(self->fd, SOL_TLS, TLS_TX, &tls12,
74 sizeof(tls12));
75 ASSERT_EQ(ret, 0);
76 }
77
78 self->cfd = accept(sfd, &addr, &len);
79 ASSERT_GE(self->cfd, 0);
80
81 if (!self->notls) {
82 ret = setsockopt(self->cfd, IPPROTO_TCP, TCP_ULP, "tls",
83 sizeof("tls"));
84 ASSERT_EQ(ret, 0);
85
86 ret = setsockopt(self->cfd, SOL_TLS, TLS_RX, &tls12,
87 sizeof(tls12));
88 ASSERT_EQ(ret, 0);
89 }
90
91 close(sfd);
92}
93
94FIXTURE_TEARDOWN(tls)
95{
96 close(self->fd);
97 close(self->cfd);
98}
99
100TEST_F(tls, sendfile)
101{
102 int filefd = open("/proc/self/exe", O_RDONLY);
103 struct stat st;
104
105 EXPECT_GE(filefd, 0);
106 fstat(filefd, &st);
107 EXPECT_GE(sendfile(self->fd, filefd, 0, st.st_size), 0);
108}
109
110TEST_F(tls, send_then_sendfile)
111{
112 int filefd = open("/proc/self/exe", O_RDONLY);
113 char const *test_str = "test_send";
114 int to_send = strlen(test_str) + 1;
115 char recv_buf[10];
116 struct stat st;
117 char *buf;
118
119 EXPECT_GE(filefd, 0);
120 fstat(filefd, &st);
121 buf = (char *)malloc(st.st_size);
122
123 EXPECT_EQ(send(self->fd, test_str, to_send, 0), to_send);
124 EXPECT_EQ(recv(self->cfd, recv_buf, to_send, 0), to_send);
125 EXPECT_EQ(memcmp(test_str, recv_buf, to_send), 0);
126
127 EXPECT_GE(sendfile(self->fd, filefd, 0, st.st_size), 0);
128 EXPECT_EQ(recv(self->cfd, buf, st.st_size, 0), st.st_size);
129}
130
131TEST_F(tls, recv_max)
132{
133 unsigned int send_len = TLS_PAYLOAD_MAX_LEN;
134 char recv_mem[TLS_PAYLOAD_MAX_LEN];
135 char buf[TLS_PAYLOAD_MAX_LEN];
136
137 EXPECT_GE(send(self->fd, buf, send_len, 0), 0);
138 EXPECT_NE(recv(self->cfd, recv_mem, send_len, 0), -1);
139 EXPECT_EQ(memcmp(buf, recv_mem, send_len), 0);
140}
141
142TEST_F(tls, recv_small)
143{
144 char const *test_str = "test_read";
145 int send_len = 10;
146 char buf[10];
147
148 send_len = strlen(test_str) + 1;
149 EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
150 EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1);
151 EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
152}
153
154TEST_F(tls, msg_more)
155{
156 char const *test_str = "test_read";
157 int send_len = 10;
158 char buf[10 * 2];
159
160 EXPECT_EQ(send(self->fd, test_str, send_len, MSG_MORE), send_len);
161 EXPECT_EQ(recv(self->cfd, buf, send_len, MSG_DONTWAIT), -1);
162 EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
163 EXPECT_EQ(recv(self->cfd, buf, send_len * 2, MSG_DONTWAIT),
164 send_len * 2);
165 EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
166}
167
168TEST_F(tls, sendmsg_single)
169{
170 struct msghdr msg;
171
172 char const *test_str = "test_sendmsg";
173 size_t send_len = 13;
174 struct iovec vec;
175 char buf[13];
176
177 vec.iov_base = (char *)test_str;
178 vec.iov_len = send_len;
179 memset(&msg, 0, sizeof(struct msghdr));
180 msg.msg_iov = &vec;
181 msg.msg_iovlen = 1;
182 EXPECT_EQ(sendmsg(self->fd, &msg, 0), send_len);
183 EXPECT_EQ(recv(self->cfd, buf, send_len, 0), send_len);
184 EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
185}
186
187TEST_F(tls, sendmsg_large)
188{
189 void *mem = malloc(16384);
190 size_t send_len = 16384;
191 size_t sends = 128;
192 struct msghdr msg;
193 size_t recvs = 0;
194 size_t sent = 0;
195
196 memset(&msg, 0, sizeof(struct msghdr));
197 while (sent++ < sends) {
198 struct iovec vec = { (void *)mem, send_len };
199
200 msg.msg_iov = &vec;
201 msg.msg_iovlen = 1;
202 EXPECT_EQ(sendmsg(self->cfd, &msg, 0), send_len);
203 }
204
205 while (recvs++ < sends)
206 EXPECT_NE(recv(self->fd, mem, send_len, 0), -1);
207
208 free(mem);
209}
210
211TEST_F(tls, sendmsg_multiple)
212{
213 char const *test_str = "test_sendmsg_multiple";
214 struct iovec vec[5];
215 char *test_strs[5];
216 struct msghdr msg;
217 int total_len = 0;
218 int len_cmp = 0;
219 int iov_len = 5;
220 char *buf;
221 int i;
222
223 memset(&msg, 0, sizeof(struct msghdr));
224 for (i = 0; i < iov_len; i++) {
225 test_strs[i] = (char *)malloc(strlen(test_str) + 1);
226 snprintf(test_strs[i], strlen(test_str) + 1, "%s", test_str);
227 vec[i].iov_base = (void *)test_strs[i];
228 vec[i].iov_len = strlen(test_strs[i]) + 1;
229 total_len += vec[i].iov_len;
230 }
231 msg.msg_iov = vec;
232 msg.msg_iovlen = iov_len;
233
234 EXPECT_EQ(sendmsg(self->cfd, &msg, 0), total_len);
235 buf = malloc(total_len);
236 EXPECT_NE(recv(self->fd, buf, total_len, 0), -1);
237 for (i = 0; i < iov_len; i++) {
238 EXPECT_EQ(memcmp(test_strs[i], buf + len_cmp,
239 strlen(test_strs[i])),
240 0);
241 len_cmp += strlen(buf + len_cmp) + 1;
242 }
243 for (i = 0; i < iov_len; i++)
244 free(test_strs[i]);
245 free(buf);
246}
247
248TEST_F(tls, sendmsg_multiple_stress)
249{
250 char const *test_str = "abcdefghijklmno";
251 struct iovec vec[1024];
252 char *test_strs[1024];
253 int iov_len = 1024;
254 int total_len = 0;
255 char buf[1 << 14];
256 struct msghdr msg;
257 int len_cmp = 0;
258 int i;
259
260 memset(&msg, 0, sizeof(struct msghdr));
261 for (i = 0; i < iov_len; i++) {
262 test_strs[i] = (char *)malloc(strlen(test_str) + 1);
263 snprintf(test_strs[i], strlen(test_str) + 1, "%s", test_str);
264 vec[i].iov_base = (void *)test_strs[i];
265 vec[i].iov_len = strlen(test_strs[i]) + 1;
266 total_len += vec[i].iov_len;
267 }
268 msg.msg_iov = vec;
269 msg.msg_iovlen = iov_len;
270
271 EXPECT_EQ(sendmsg(self->fd, &msg, 0), total_len);
272 EXPECT_NE(recv(self->cfd, buf, total_len, 0), -1);
273
274 for (i = 0; i < iov_len; i++)
275 len_cmp += strlen(buf + len_cmp) + 1;
276
277 for (i = 0; i < iov_len; i++)
278 free(test_strs[i]);
279}
280
281TEST_F(tls, splice_from_pipe)
282{
283 int send_len = TLS_PAYLOAD_MAX_LEN;
284 char mem_send[TLS_PAYLOAD_MAX_LEN];
285 char mem_recv[TLS_PAYLOAD_MAX_LEN];
286 int p[2];
287
288 ASSERT_GE(pipe(p), 0);
289 EXPECT_GE(write(p[1], mem_send, send_len), 0);
290 EXPECT_GE(splice(p[0], NULL, self->fd, NULL, send_len, 0), 0);
291 EXPECT_GE(recv(self->cfd, mem_recv, send_len, 0), 0);
292 EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
293}
294
295TEST_F(tls, splice_from_pipe2)
296{
297 int send_len = 16000;
298 char mem_send[16000];
299 char mem_recv[16000];
300 int p2[2];
301 int p[2];
302
303 ASSERT_GE(pipe(p), 0);
304 ASSERT_GE(pipe(p2), 0);
305 EXPECT_GE(write(p[1], mem_send, 8000), 0);
306 EXPECT_GE(splice(p[0], NULL, self->fd, NULL, 8000, 0), 0);
307 EXPECT_GE(write(p2[1], mem_send + 8000, 8000), 0);
308 EXPECT_GE(splice(p2[0], NULL, self->fd, NULL, 8000, 0), 0);
309 EXPECT_GE(recv(self->cfd, mem_recv, send_len, 0), 0);
310 EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
311}
312
313TEST_F(tls, send_and_splice)
314{
315 int send_len = TLS_PAYLOAD_MAX_LEN;
316 char mem_send[TLS_PAYLOAD_MAX_LEN];
317 char mem_recv[TLS_PAYLOAD_MAX_LEN];
318 char const *test_str = "test_read";
319 int send_len2 = 10;
320 char buf[10];
321 int p[2];
322
323 ASSERT_GE(pipe(p), 0);
324 EXPECT_EQ(send(self->fd, test_str, send_len2, 0), send_len2);
325 EXPECT_NE(recv(self->cfd, buf, send_len2, 0), -1);
326 EXPECT_EQ(memcmp(test_str, buf, send_len2), 0);
327
328 EXPECT_GE(write(p[1], mem_send, send_len), send_len);
329 EXPECT_GE(splice(p[0], NULL, self->fd, NULL, send_len, 0), send_len);
330
331 EXPECT_GE(recv(self->cfd, mem_recv, send_len, 0), 0);
332 EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
333}
334
335TEST_F(tls, splice_to_pipe)
336{
337 int send_len = TLS_PAYLOAD_MAX_LEN;
338 char mem_send[TLS_PAYLOAD_MAX_LEN];
339 char mem_recv[TLS_PAYLOAD_MAX_LEN];
340 int p[2];
341
342 ASSERT_GE(pipe(p), 0);
343 EXPECT_GE(send(self->fd, mem_send, send_len, 0), 0);
344 EXPECT_GE(splice(self->cfd, NULL, p[1], NULL, send_len, 0), 0);
345 EXPECT_GE(read(p[0], mem_recv, send_len), 0);
346 EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
347}
348
349TEST_F(tls, recvmsg_single)
350{
351 char const *test_str = "test_recvmsg_single";
352 int send_len = strlen(test_str) + 1;
353 char buf[20];
354 struct msghdr hdr;
355 struct iovec vec;
356
357 memset(&hdr, 0, sizeof(hdr));
358 EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
359 vec.iov_base = (char *)buf;
360 vec.iov_len = send_len;
361 hdr.msg_iovlen = 1;
362 hdr.msg_iov = &vec;
363 EXPECT_NE(recvmsg(self->cfd, &hdr, 0), -1);
364 EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
365}
366
367TEST_F(tls, recvmsg_single_max)
368{
369 int send_len = TLS_PAYLOAD_MAX_LEN;
370 char send_mem[TLS_PAYLOAD_MAX_LEN];
371 char recv_mem[TLS_PAYLOAD_MAX_LEN];
372 struct iovec vec;
373 struct msghdr hdr;
374
375 EXPECT_EQ(send(self->fd, send_mem, send_len, 0), send_len);
376 vec.iov_base = (char *)recv_mem;
377 vec.iov_len = TLS_PAYLOAD_MAX_LEN;
378
379 hdr.msg_iovlen = 1;
380 hdr.msg_iov = &vec;
381 EXPECT_NE(recvmsg(self->cfd, &hdr, 0), -1);
382 EXPECT_EQ(memcmp(send_mem, recv_mem, send_len), 0);
383}
384
385TEST_F(tls, recvmsg_multiple)
386{
387 unsigned int msg_iovlen = 1024;
388 unsigned int len_compared = 0;
389 struct iovec vec[1024];
390 char *iov_base[1024];
391 unsigned int iov_len = 16;
392 int send_len = 1 << 14;
393 char buf[1 << 14];
394 struct msghdr hdr;
395 int i;
396
397 EXPECT_EQ(send(self->fd, buf, send_len, 0), send_len);
398 for (i = 0; i < msg_iovlen; i++) {
399 iov_base[i] = (char *)malloc(iov_len);
400 vec[i].iov_base = iov_base[i];
401 vec[i].iov_len = iov_len;
402 }
403
404 hdr.msg_iovlen = msg_iovlen;
405 hdr.msg_iov = vec;
406 EXPECT_NE(recvmsg(self->cfd, &hdr, 0), -1);
407 for (i = 0; i < msg_iovlen; i++)
408 len_compared += iov_len;
409
410 for (i = 0; i < msg_iovlen; i++)
411 free(iov_base[i]);
412}
413
414TEST_F(tls, single_send_multiple_recv)
415{
416 unsigned int total_len = TLS_PAYLOAD_MAX_LEN * 2;
417 unsigned int send_len = TLS_PAYLOAD_MAX_LEN;
418 char send_mem[TLS_PAYLOAD_MAX_LEN * 2];
419 char recv_mem[TLS_PAYLOAD_MAX_LEN * 2];
420
421 EXPECT_GE(send(self->fd, send_mem, total_len, 0), 0);
422 memset(recv_mem, 0, total_len);
423
424 EXPECT_NE(recv(self->cfd, recv_mem, send_len, 0), -1);
425 EXPECT_NE(recv(self->cfd, recv_mem + send_len, send_len, 0), -1);
426 EXPECT_EQ(memcmp(send_mem, recv_mem, total_len), 0);
427}
428
429TEST_F(tls, multiple_send_single_recv)
430{
431 unsigned int total_len = 2 * 10;
432 unsigned int send_len = 10;
433 char recv_mem[2 * 10];
434 char send_mem[10];
435
436 EXPECT_GE(send(self->fd, send_mem, send_len, 0), 0);
437 EXPECT_GE(send(self->fd, send_mem, send_len, 0), 0);
438 memset(recv_mem, 0, total_len);
439 EXPECT_EQ(recv(self->cfd, recv_mem, total_len, 0), total_len);
440
441 EXPECT_EQ(memcmp(send_mem, recv_mem, send_len), 0);
442 EXPECT_EQ(memcmp(send_mem, recv_mem + send_len, send_len), 0);
443}
444
445TEST_F(tls, recv_partial)
446{
447 char const *test_str = "test_read_partial";
448 char const *test_str_first = "test_read";
449 char const *test_str_second = "_partial";
450 int send_len = strlen(test_str) + 1;
451 char recv_mem[18];
452
453 memset(recv_mem, 0, sizeof(recv_mem));
454 EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
455 EXPECT_NE(recv(self->cfd, recv_mem, strlen(test_str_first), 0), -1);
456 EXPECT_EQ(memcmp(test_str_first, recv_mem, strlen(test_str_first)), 0);
457 memset(recv_mem, 0, sizeof(recv_mem));
458 EXPECT_NE(recv(self->cfd, recv_mem, strlen(test_str_second), 0), -1);
459 EXPECT_EQ(memcmp(test_str_second, recv_mem, strlen(test_str_second)),
460 0);
461}
462
463TEST_F(tls, recv_nonblock)
464{
465 char buf[4096];
466 bool err;
467
468 EXPECT_EQ(recv(self->cfd, buf, sizeof(buf), MSG_DONTWAIT), -1);
469 err = (errno == EAGAIN || errno == EWOULDBLOCK);
470 EXPECT_EQ(err, true);
471}
472
473TEST_F(tls, recv_peek)
474{
475 char const *test_str = "test_read_peek";
476 int send_len = strlen(test_str) + 1;
477 char buf[15];
478
479 EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
480 EXPECT_NE(recv(self->cfd, buf, send_len, MSG_PEEK), -1);
481 EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
482 memset(buf, 0, sizeof(buf));
483 EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1);
484 EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
485}
486
487TEST_F(tls, recv_peek_multiple)
488{
489 char const *test_str = "test_read_peek";
490 int send_len = strlen(test_str) + 1;
491 unsigned int num_peeks = 100;
492 char buf[15];
493 int i;
494
495 EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
496 for (i = 0; i < num_peeks; i++) {
497 EXPECT_NE(recv(self->cfd, buf, send_len, MSG_PEEK), -1);
498 EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
499 memset(buf, 0, sizeof(buf));
500 }
501 EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1);
502 EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
503}
504
505TEST_F(tls, pollin)
506{
507 char const *test_str = "test_poll";
508 struct pollfd fd = { 0, 0, 0 };
509 char buf[10];
510 int send_len = 10;
511
512 EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
513 fd.fd = self->cfd;
514 fd.events = POLLIN;
515
516 EXPECT_EQ(poll(&fd, 1, 20), 1);
517 EXPECT_EQ(fd.revents & POLLIN, 1);
518 EXPECT_EQ(recv(self->cfd, buf, send_len, 0), send_len);
519 /* Test timing out */
520 EXPECT_EQ(poll(&fd, 1, 20), 0);
521}
522
523TEST_F(tls, poll_wait)
524{
525 char const *test_str = "test_poll_wait";
526 int send_len = strlen(test_str) + 1;
527 struct pollfd fd = { 0, 0, 0 };
528 char recv_mem[15];
529
530 fd.fd = self->cfd;
531 fd.events = POLLIN;
532 EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
533 /* Set timeout to inf. secs */
534 EXPECT_EQ(poll(&fd, 1, -1), 1);
535 EXPECT_EQ(fd.revents & POLLIN, 1);
536 EXPECT_EQ(recv(self->cfd, recv_mem, send_len, 0), send_len);
537}
538
539TEST_F(tls, blocking)
540{
541 size_t data = 100000;
542 int res = fork();
543
544 EXPECT_NE(res, -1);
545
546 if (res) {
547 /* parent */
548 size_t left = data;
549 char buf[16384];
550 int status;
551 int pid2;
552
553 while (left) {
554 int res = send(self->fd, buf,
555 left > 16384 ? 16384 : left, 0);
556
557 EXPECT_GE(res, 0);
558 left -= res;
559 }
560
561 pid2 = wait(&status);
562 EXPECT_EQ(status, 0);
563 EXPECT_EQ(res, pid2);
564 } else {
565 /* child */
566 size_t left = data;
567 char buf[16384];
568
569 while (left) {
570 int res = recv(self->cfd, buf,
571 left > 16384 ? 16384 : left, 0);
572
573 EXPECT_GE(res, 0);
574 left -= res;
575 }
576 }
577}
578
579TEST_F(tls, nonblocking)
580{
581 size_t data = 100000;
582 int sendbuf = 100;
583 int flags;
584 int res;
585
586 flags = fcntl(self->fd, F_GETFL, 0);
587 fcntl(self->fd, F_SETFL, flags | O_NONBLOCK);
588 fcntl(self->cfd, F_SETFL, flags | O_NONBLOCK);
589
590 /* Ensure nonblocking behavior by imposing a small send
591 * buffer.
592 */
593 EXPECT_EQ(setsockopt(self->fd, SOL_SOCKET, SO_SNDBUF,
594 &sendbuf, sizeof(sendbuf)), 0);
595
596 res = fork();
597 EXPECT_NE(res, -1);
598
599 if (res) {
600 /* parent */
601 bool eagain = false;
602 size_t left = data;
603 char buf[16384];
604 int status;
605 int pid2;
606
607 while (left) {
608 int res = send(self->fd, buf,
609 left > 16384 ? 16384 : left, 0);
610
611 if (res == -1 && errno == EAGAIN) {
612 eagain = true;
613 usleep(10000);
614 continue;
615 }
616 EXPECT_GE(res, 0);
617 left -= res;
618 }
619
620 EXPECT_TRUE(eagain);
621 pid2 = wait(&status);
622
623 EXPECT_EQ(status, 0);
624 EXPECT_EQ(res, pid2);
625 } else {
626 /* child */
627 bool eagain = false;
628 size_t left = data;
629 char buf[16384];
630
631 while (left) {
632 int res = recv(self->cfd, buf,
633 left > 16384 ? 16384 : left, 0);
634
635 if (res == -1 && errno == EAGAIN) {
636 eagain = true;
637 usleep(10000);
638 continue;
639 }
640 EXPECT_GE(res, 0);
641 left -= res;
642 }
643 EXPECT_TRUE(eagain);
644 }
645}
646
647TEST_F(tls, control_msg)
648{
649 if (self->notls)
650 return;
651
652 char cbuf[CMSG_SPACE(sizeof(char))];
653 char const *test_str = "test_read";
654 int cmsg_len = sizeof(char);
655 char record_type = 100;
656 struct cmsghdr *cmsg;
657 struct msghdr msg;
658 int send_len = 10;
659 struct iovec vec;
660 char buf[10];
661
662 vec.iov_base = (char *)test_str;
663 vec.iov_len = 10;
664 memset(&msg, 0, sizeof(struct msghdr));
665 msg.msg_iov = &vec;
666 msg.msg_iovlen = 1;
667 msg.msg_control = cbuf;
668 msg.msg_controllen = sizeof(cbuf);
669 cmsg = CMSG_FIRSTHDR(&msg);
670 cmsg->cmsg_level = SOL_TLS;
671 /* test sending non-record types. */
672 cmsg->cmsg_type = TLS_SET_RECORD_TYPE;
673 cmsg->cmsg_len = CMSG_LEN(cmsg_len);
674 *CMSG_DATA(cmsg) = record_type;
675 msg.msg_controllen = cmsg->cmsg_len;
676
677 EXPECT_EQ(sendmsg(self->fd, &msg, 0), send_len);
678 /* Should fail because we didn't provide a control message */
679 EXPECT_EQ(recv(self->cfd, buf, send_len, 0), -1);
680
681 vec.iov_base = buf;
682 EXPECT_EQ(recvmsg(self->cfd, &msg, 0), send_len);
683 cmsg = CMSG_FIRSTHDR(&msg);
684 EXPECT_NE(cmsg, NULL);
685 EXPECT_EQ(cmsg->cmsg_level, SOL_TLS);
686 EXPECT_EQ(cmsg->cmsg_type, TLS_GET_RECORD_TYPE);
687 record_type = *((unsigned char *)CMSG_DATA(cmsg));
688 EXPECT_EQ(record_type, 100);
689 EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
690}
691
692TEST_HARNESS_MAIN
diff --git a/tools/testing/selftests/rcutorture/bin/configinit.sh b/tools/testing/selftests/rcutorture/bin/configinit.sh
index c15f270e121d..65541c21a544 100755
--- a/tools/testing/selftests/rcutorture/bin/configinit.sh
+++ b/tools/testing/selftests/rcutorture/bin/configinit.sh
@@ -1,6 +1,6 @@
1#!/bin/bash 1#!/bin/bash
2# 2#
3# Usage: configinit.sh config-spec-file [ build output dir ] 3# Usage: configinit.sh config-spec-file build-output-dir results-dir
4# 4#
5# Create a .config file from the spec file. Run from the kernel source tree. 5# Create a .config file from the spec file. Run from the kernel source tree.
6# Exits with 0 if all went well, with 1 if all went well but the config 6# Exits with 0 if all went well, with 1 if all went well but the config
@@ -40,20 +40,18 @@ mkdir $T
40 40
41c=$1 41c=$1
42buildloc=$2 42buildloc=$2
43resdir=$3
43builddir= 44builddir=
44if test -n $buildloc 45if echo $buildloc | grep -q '^O='
45then 46then
46 if echo $buildloc | grep -q '^O=' 47 builddir=`echo $buildloc | sed -e 's/^O=//'`
48 if test ! -d $builddir
47 then 49 then
48 builddir=`echo $buildloc | sed -e 's/^O=//'` 50 mkdir $builddir
49 if test ! -d $builddir
50 then
51 mkdir $builddir
52 fi
53 else
54 echo Bad build directory: \"$buildloc\"
55 exit 2
56 fi 51 fi
52else
53 echo Bad build directory: \"$buildloc\"
54 exit 2
57fi 55fi
58 56
59sed -e 's/^\(CONFIG[0-9A-Z_]*\)=.*$/grep -v "^# \1" |/' < $c > $T/u.sh 57sed -e 's/^\(CONFIG[0-9A-Z_]*\)=.*$/grep -v "^# \1" |/' < $c > $T/u.sh
@@ -61,12 +59,12 @@ sed -e 's/^\(CONFIG[0-9A-Z_]*=\).*$/grep -v \1 |/' < $c >> $T/u.sh
61grep '^grep' < $T/u.sh > $T/upd.sh 59grep '^grep' < $T/u.sh > $T/upd.sh
62echo "cat - $c" >> $T/upd.sh 60echo "cat - $c" >> $T/upd.sh
63make mrproper 61make mrproper
64make $buildloc distclean > $builddir/Make.distclean 2>&1 62make $buildloc distclean > $resdir/Make.distclean 2>&1
65make $buildloc $TORTURE_DEFCONFIG > $builddir/Make.defconfig.out 2>&1 63make $buildloc $TORTURE_DEFCONFIG > $resdir/Make.defconfig.out 2>&1
66mv $builddir/.config $builddir/.config.sav 64mv $builddir/.config $builddir/.config.sav
67sh $T/upd.sh < $builddir/.config.sav > $builddir/.config 65sh $T/upd.sh < $builddir/.config.sav > $builddir/.config
68cp $builddir/.config $builddir/.config.new 66cp $builddir/.config $builddir/.config.new
69yes '' | make $buildloc oldconfig > $builddir/Make.oldconfig.out 2> $builddir/Make.oldconfig.err 67yes '' | make $buildloc oldconfig > $resdir/Make.oldconfig.out 2> $resdir/Make.oldconfig.err
70 68
71# verify new config matches specification. 69# verify new config matches specification.
72configcheck.sh $builddir/.config $c 70configcheck.sh $builddir/.config $c
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-build.sh b/tools/testing/selftests/rcutorture/bin/kvm-build.sh
index 34d126734cde..9115fcdb5617 100755
--- a/tools/testing/selftests/rcutorture/bin/kvm-build.sh
+++ b/tools/testing/selftests/rcutorture/bin/kvm-build.sh
@@ -2,7 +2,7 @@
2# 2#
3# Build a kvm-ready Linux kernel from the tree in the current directory. 3# Build a kvm-ready Linux kernel from the tree in the current directory.
4# 4#
5# Usage: kvm-build.sh config-template build-dir 5# Usage: kvm-build.sh config-template build-dir resdir
6# 6#
7# This program is free software; you can redistribute it and/or modify 7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by 8# it under the terms of the GNU General Public License as published by
@@ -29,6 +29,7 @@ then
29 exit 1 29 exit 1
30fi 30fi
31builddir=${2} 31builddir=${2}
32resdir=${3}
32 33
33T=${TMPDIR-/tmp}/test-linux.sh.$$ 34T=${TMPDIR-/tmp}/test-linux.sh.$$
34trap 'rm -rf $T' 0 35trap 'rm -rf $T' 0
@@ -41,19 +42,19 @@ CONFIG_VIRTIO_PCI=y
41CONFIG_VIRTIO_CONSOLE=y 42CONFIG_VIRTIO_CONSOLE=y
42___EOF___ 43___EOF___
43 44
44configinit.sh $T/config O=$builddir 45configinit.sh $T/config O=$builddir $resdir
45retval=$? 46retval=$?
46if test $retval -gt 1 47if test $retval -gt 1
47then 48then
48 exit 2 49 exit 2
49fi 50fi
50ncpus=`cpus2use.sh` 51ncpus=`cpus2use.sh`
51make O=$builddir -j$ncpus $TORTURE_KMAKE_ARG > $builddir/Make.out 2>&1 52make O=$builddir -j$ncpus $TORTURE_KMAKE_ARG > $resdir/Make.out 2>&1
52retval=$? 53retval=$?
53if test $retval -ne 0 || grep "rcu[^/]*": < $builddir/Make.out | egrep -q "Stop|Error|error:|warning:" || egrep -q "Stop|Error|error:" < $builddir/Make.out 54if test $retval -ne 0 || grep "rcu[^/]*": < $resdir/Make.out | egrep -q "Stop|Error|error:|warning:" || egrep -q "Stop|Error|error:" < $resdir/Make.out
54then 55then
55 echo Kernel build error 56 echo Kernel build error
56 egrep "Stop|Error|error:|warning:" < $builddir/Make.out 57 egrep "Stop|Error|error:|warning:" < $resdir/Make.out
57 echo Run aborted. 58 echo Run aborted.
58 exit 3 59 exit 3
59fi 60fi
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh b/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh
index 477ecb1293ab..0fa8a61ccb7b 100755
--- a/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh
+++ b/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh
@@ -70,4 +70,5 @@ else
70 else 70 else
71 print_warning $nclosecalls "Reader Batch close calls in" $(($dur/60)) minute run: $i 71 print_warning $nclosecalls "Reader Batch close calls in" $(($dur/60)) minute run: $i
72 fi 72 fi
73 echo $nclosecalls "Reader Batch close calls in" $(($dur/60)) minute run: $i > $i/console.log.rcu.diags
73fi 74fi
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh b/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh
index c27e97824163..c9bab57a77eb 100755
--- a/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh
+++ b/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh
@@ -39,6 +39,7 @@ do
39 head -1 $resdir/log 39 head -1 $resdir/log
40 fi 40 fi
41 TORTURE_SUITE="`cat $i/../TORTURE_SUITE`" 41 TORTURE_SUITE="`cat $i/../TORTURE_SUITE`"
42 rm -f $i/console.log.*.diags
42 kvm-recheck-${TORTURE_SUITE}.sh $i 43 kvm-recheck-${TORTURE_SUITE}.sh $i
43 if test -f "$i/console.log" 44 if test -f "$i/console.log"
44 then 45 then
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh b/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh
index c5b0f94341d9..f7247ee00514 100755
--- a/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh
+++ b/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh
@@ -98,14 +98,15 @@ then
98 ln -s $base_resdir/.config $resdir # for kvm-recheck.sh 98 ln -s $base_resdir/.config $resdir # for kvm-recheck.sh
99 # Arch-independent indicator 99 # Arch-independent indicator
100 touch $resdir/builtkernel 100 touch $resdir/builtkernel
101elif kvm-build.sh $T/Kc2 $builddir 101elif kvm-build.sh $T/Kc2 $builddir $resdir
102then 102then
103 # Had to build a kernel for this test. 103 # Had to build a kernel for this test.
104 QEMU="`identify_qemu $builddir/vmlinux`" 104 QEMU="`identify_qemu $builddir/vmlinux`"
105 BOOT_IMAGE="`identify_boot_image $QEMU`" 105 BOOT_IMAGE="`identify_boot_image $QEMU`"
106 cp $builddir/Make*.out $resdir
107 cp $builddir/vmlinux $resdir 106 cp $builddir/vmlinux $resdir
108 cp $builddir/.config $resdir 107 cp $builddir/.config $resdir
108 cp $builddir/Module.symvers $resdir > /dev/null || :
109 cp $builddir/System.map $resdir > /dev/null || :
109 if test -n "$BOOT_IMAGE" 110 if test -n "$BOOT_IMAGE"
110 then 111 then
111 cp $builddir/$BOOT_IMAGE $resdir 112 cp $builddir/$BOOT_IMAGE $resdir
diff --git a/tools/testing/selftests/rcutorture/bin/kvm.sh b/tools/testing/selftests/rcutorture/bin/kvm.sh
index 56610dbbdf73..5a7a62d76a50 100755
--- a/tools/testing/selftests/rcutorture/bin/kvm.sh
+++ b/tools/testing/selftests/rcutorture/bin/kvm.sh
@@ -347,7 +347,7 @@ function dump(first, pastlast, batchnum)
347 print "needqemurun=" 347 print "needqemurun="
348 jn=1 348 jn=1
349 for (j = first; j < pastlast; j++) { 349 for (j = first; j < pastlast; j++) {
350 builddir=KVM "/b" jn 350 builddir=KVM "/b1"
351 cpusr[jn] = cpus[j]; 351 cpusr[jn] = cpus[j];
352 if (cfrep[cf[j]] == "") { 352 if (cfrep[cf[j]] == "") {
353 cfr[jn] = cf[j]; 353 cfr[jn] = cf[j];
diff --git a/tools/testing/selftests/rcutorture/bin/parse-console.sh b/tools/testing/selftests/rcutorture/bin/parse-console.sh
index 17293436f551..84933f6aed77 100755
--- a/tools/testing/selftests/rcutorture/bin/parse-console.sh
+++ b/tools/testing/selftests/rcutorture/bin/parse-console.sh
@@ -163,6 +163,13 @@ then
163 print_warning Summary: $summary 163 print_warning Summary: $summary
164 cat $T.diags >> $file.diags 164 cat $T.diags >> $file.diags
165fi 165fi
166for i in $file.*.diags
167do
168 if test -f "$i"
169 then
170 cat $i >> $file.diags
171 fi
172done
166if ! test -s $file.diags 173if ! test -s $file.diags
167then 174then
168 rm -f $file.diags 175 rm -f $file.diags
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot b/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot
index 5d2cc0bd50a0..5c3213cc3ad7 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot
@@ -1,5 +1,5 @@
1rcutorture.onoff_interval=1 rcutorture.onoff_holdoff=30 1rcutorture.onoff_interval=200 rcutorture.onoff_holdoff=30
2rcutree.gp_preinit_delay=3 2rcutree.gp_preinit_delay=12
3rcutree.gp_init_delay=3 3rcutree.gp_init_delay=3
4rcutree.gp_cleanup_delay=3 4rcutree.gp_cleanup_delay=3
5rcutree.kthread_prio=2 5rcutree.kthread_prio=2
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE08-T.boot b/tools/testing/selftests/rcutorture/configs/rcu/TREE08-T.boot
deleted file mode 100644
index 883149b5f2d1..000000000000
--- a/tools/testing/selftests/rcutorture/configs/rcu/TREE08-T.boot
+++ /dev/null
@@ -1 +0,0 @@
1rcutree.rcu_fanout_exact=1
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/ver_functions.sh b/tools/testing/selftests/rcutorture/configs/rcu/ver_functions.sh
index 24ec91041957..7bab8246392b 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/ver_functions.sh
+++ b/tools/testing/selftests/rcutorture/configs/rcu/ver_functions.sh
@@ -39,7 +39,7 @@ rcutorture_param_onoff () {
39 if ! bootparam_hotplug_cpu "$1" && configfrag_hotplug_cpu "$2" 39 if ! bootparam_hotplug_cpu "$1" && configfrag_hotplug_cpu "$2"
40 then 40 then
41 echo CPU-hotplug kernel, adding rcutorture onoff. 1>&2 41 echo CPU-hotplug kernel, adding rcutorture onoff. 1>&2
42 echo rcutorture.onoff_interval=3 rcutorture.onoff_holdoff=30 42 echo rcutorture.onoff_interval=1000 rcutorture.onoff_holdoff=30
43 fi 43 fi
44} 44}
45 45
diff --git a/tools/testing/selftests/rseq/param_test.c b/tools/testing/selftests/rseq/param_test.c
index 615252331813..642d4e12abea 100644
--- a/tools/testing/selftests/rseq/param_test.c
+++ b/tools/testing/selftests/rseq/param_test.c
@@ -90,6 +90,30 @@ unsigned int yield_mod_cnt, nr_abort;
90#error "Unsupported architecture" 90#error "Unsupported architecture"
91#endif 91#endif
92 92
93#elif defined(__s390__)
94
95#define RSEQ_INJECT_INPUT \
96 , [loop_cnt_1]"m"(loop_cnt[1]) \
97 , [loop_cnt_2]"m"(loop_cnt[2]) \
98 , [loop_cnt_3]"m"(loop_cnt[3]) \
99 , [loop_cnt_4]"m"(loop_cnt[4]) \
100 , [loop_cnt_5]"m"(loop_cnt[5]) \
101 , [loop_cnt_6]"m"(loop_cnt[6])
102
103#define INJECT_ASM_REG "r12"
104
105#define RSEQ_INJECT_CLOBBER \
106 , INJECT_ASM_REG
107
108#define RSEQ_INJECT_ASM(n) \
109 "l %%" INJECT_ASM_REG ", %[loop_cnt_" #n "]\n\t" \
110 "ltr %%" INJECT_ASM_REG ", %%" INJECT_ASM_REG "\n\t" \
111 "je 333f\n\t" \
112 "222:\n\t" \
113 "ahi %%" INJECT_ASM_REG ", -1\n\t" \
114 "jnz 222b\n\t" \
115 "333:\n\t"
116
93#elif defined(__ARMEL__) 117#elif defined(__ARMEL__)
94 118
95#define RSEQ_INJECT_INPUT \ 119#define RSEQ_INJECT_INPUT \
@@ -114,6 +138,26 @@ unsigned int yield_mod_cnt, nr_abort;
114 "bne 222b\n\t" \ 138 "bne 222b\n\t" \
115 "333:\n\t" 139 "333:\n\t"
116 140
141#elif defined(__AARCH64EL__)
142
143#define RSEQ_INJECT_INPUT \
144 , [loop_cnt_1] "Qo" (loop_cnt[1]) \
145 , [loop_cnt_2] "Qo" (loop_cnt[2]) \
146 , [loop_cnt_3] "Qo" (loop_cnt[3]) \
147 , [loop_cnt_4] "Qo" (loop_cnt[4]) \
148 , [loop_cnt_5] "Qo" (loop_cnt[5]) \
149 , [loop_cnt_6] "Qo" (loop_cnt[6])
150
151#define INJECT_ASM_REG RSEQ_ASM_TMP_REG32
152
153#define RSEQ_INJECT_ASM(n) \
154 " ldr " INJECT_ASM_REG ", %[loop_cnt_" #n "]\n" \
155 " cbz " INJECT_ASM_REG ", 333f\n" \
156 "222:\n" \
157 " sub " INJECT_ASM_REG ", " INJECT_ASM_REG ", #1\n" \
158 " cbnz " INJECT_ASM_REG ", 222b\n" \
159 "333:\n"
160
117#elif __PPC__ 161#elif __PPC__
118 162
119#define RSEQ_INJECT_INPUT \ 163#define RSEQ_INJECT_INPUT \
diff --git a/tools/testing/selftests/rseq/rseq-arm64.h b/tools/testing/selftests/rseq/rseq-arm64.h
new file mode 100644
index 000000000000..954f34671ca6
--- /dev/null
+++ b/tools/testing/selftests/rseq/rseq-arm64.h
@@ -0,0 +1,594 @@
1/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
2/*
3 * rseq-arm64.h
4 *
5 * (C) Copyright 2016-2018 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6 * (C) Copyright 2018 - Will Deacon <will.deacon@arm.com>
7 */
8
9#define RSEQ_SIG 0xd428bc00 /* BRK #0x45E0 */
10
11#define rseq_smp_mb() __asm__ __volatile__ ("dmb ish" ::: "memory")
12#define rseq_smp_rmb() __asm__ __volatile__ ("dmb ishld" ::: "memory")
13#define rseq_smp_wmb() __asm__ __volatile__ ("dmb ishst" ::: "memory")
14
15#define rseq_smp_load_acquire(p) \
16__extension__ ({ \
17 __typeof(*p) ____p1; \
18 switch (sizeof(*p)) { \
19 case 1: \
20 asm volatile ("ldarb %w0, %1" \
21 : "=r" (*(__u8 *)p) \
22 : "Q" (*p) : "memory"); \
23 break; \
24 case 2: \
25 asm volatile ("ldarh %w0, %1" \
26 : "=r" (*(__u16 *)p) \
27 : "Q" (*p) : "memory"); \
28 break; \
29 case 4: \
30 asm volatile ("ldar %w0, %1" \
31 : "=r" (*(__u32 *)p) \
32 : "Q" (*p) : "memory"); \
33 break; \
34 case 8: \
35 asm volatile ("ldar %0, %1" \
36 : "=r" (*(__u64 *)p) \
37 : "Q" (*p) : "memory"); \
38 break; \
39 } \
40 ____p1; \
41})
42
43#define rseq_smp_acquire__after_ctrl_dep() rseq_smp_rmb()
44
45#define rseq_smp_store_release(p, v) \
46do { \
47 switch (sizeof(*p)) { \
48 case 1: \
49 asm volatile ("stlrb %w1, %0" \
50 : "=Q" (*p) \
51 : "r" ((__u8)v) \
52 : "memory"); \
53 break; \
54 case 2: \
55 asm volatile ("stlrh %w1, %0" \
56 : "=Q" (*p) \
57 : "r" ((__u16)v) \
58 : "memory"); \
59 break; \
60 case 4: \
61 asm volatile ("stlr %w1, %0" \
62 : "=Q" (*p) \
63 : "r" ((__u32)v) \
64 : "memory"); \
65 break; \
66 case 8: \
67 asm volatile ("stlr %1, %0" \
68 : "=Q" (*p) \
69 : "r" ((__u64)v) \
70 : "memory"); \
71 break; \
72 } \
73} while (0)
74
75#ifdef RSEQ_SKIP_FASTPATH
76#include "rseq-skip.h"
77#else /* !RSEQ_SKIP_FASTPATH */
78
79#define RSEQ_ASM_TMP_REG32 "w15"
80#define RSEQ_ASM_TMP_REG "x15"
81#define RSEQ_ASM_TMP_REG_2 "x14"
82
83#define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, start_ip, \
84 post_commit_offset, abort_ip) \
85 " .pushsection __rseq_table, \"aw\"\n" \
86 " .balign 32\n" \
87 __rseq_str(label) ":\n" \
88 " .long " __rseq_str(version) ", " __rseq_str(flags) "\n" \
89 " .quad " __rseq_str(start_ip) ", " \
90 __rseq_str(post_commit_offset) ", " \
91 __rseq_str(abort_ip) "\n" \
92 " .popsection\n"
93
94#define RSEQ_ASM_DEFINE_TABLE(label, start_ip, post_commit_ip, abort_ip) \
95 __RSEQ_ASM_DEFINE_TABLE(label, 0x0, 0x0, start_ip, \
96 (post_commit_ip - start_ip), abort_ip)
97
98#define RSEQ_ASM_STORE_RSEQ_CS(label, cs_label, rseq_cs) \
99 RSEQ_INJECT_ASM(1) \
100 " adrp " RSEQ_ASM_TMP_REG ", " __rseq_str(cs_label) "\n" \
101 " add " RSEQ_ASM_TMP_REG ", " RSEQ_ASM_TMP_REG \
102 ", :lo12:" __rseq_str(cs_label) "\n" \
103 " str " RSEQ_ASM_TMP_REG ", %[" __rseq_str(rseq_cs) "]\n" \
104 __rseq_str(label) ":\n"
105
106#define RSEQ_ASM_DEFINE_ABORT(label, abort_label) \
107 " b 222f\n" \
108 " .inst " __rseq_str(RSEQ_SIG) "\n" \
109 __rseq_str(label) ":\n" \
110 " b %l[" __rseq_str(abort_label) "]\n" \
111 "222:\n"
112
113#define RSEQ_ASM_OP_STORE(value, var) \
114 " str %[" __rseq_str(value) "], %[" __rseq_str(var) "]\n"
115
116#define RSEQ_ASM_OP_STORE_RELEASE(value, var) \
117 " stlr %[" __rseq_str(value) "], %[" __rseq_str(var) "]\n"
118
119#define RSEQ_ASM_OP_FINAL_STORE(value, var, post_commit_label) \
120 RSEQ_ASM_OP_STORE(value, var) \
121 __rseq_str(post_commit_label) ":\n"
122
123#define RSEQ_ASM_OP_FINAL_STORE_RELEASE(value, var, post_commit_label) \
124 RSEQ_ASM_OP_STORE_RELEASE(value, var) \
125 __rseq_str(post_commit_label) ":\n"
126
127#define RSEQ_ASM_OP_CMPEQ(var, expect, label) \
128 " ldr " RSEQ_ASM_TMP_REG ", %[" __rseq_str(var) "]\n" \
129 " sub " RSEQ_ASM_TMP_REG ", " RSEQ_ASM_TMP_REG \
130 ", %[" __rseq_str(expect) "]\n" \
131 " cbnz " RSEQ_ASM_TMP_REG ", " __rseq_str(label) "\n"
132
133#define RSEQ_ASM_OP_CMPEQ32(var, expect, label) \
134 " ldr " RSEQ_ASM_TMP_REG32 ", %[" __rseq_str(var) "]\n" \
135 " sub " RSEQ_ASM_TMP_REG32 ", " RSEQ_ASM_TMP_REG32 \
136 ", %w[" __rseq_str(expect) "]\n" \
137 " cbnz " RSEQ_ASM_TMP_REG32 ", " __rseq_str(label) "\n"
138
139#define RSEQ_ASM_OP_CMPNE(var, expect, label) \
140 " ldr " RSEQ_ASM_TMP_REG ", %[" __rseq_str(var) "]\n" \
141 " sub " RSEQ_ASM_TMP_REG ", " RSEQ_ASM_TMP_REG \
142 ", %[" __rseq_str(expect) "]\n" \
143 " cbz " RSEQ_ASM_TMP_REG ", " __rseq_str(label) "\n"
144
145#define RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, label) \
146 RSEQ_INJECT_ASM(2) \
147 RSEQ_ASM_OP_CMPEQ32(current_cpu_id, cpu_id, label)
148
149#define RSEQ_ASM_OP_R_LOAD(var) \
150 " ldr " RSEQ_ASM_TMP_REG ", %[" __rseq_str(var) "]\n"
151
152#define RSEQ_ASM_OP_R_STORE(var) \
153 " str " RSEQ_ASM_TMP_REG ", %[" __rseq_str(var) "]\n"
154
155#define RSEQ_ASM_OP_R_LOAD_OFF(offset) \
156 " ldr " RSEQ_ASM_TMP_REG ", [" RSEQ_ASM_TMP_REG \
157 ", %[" __rseq_str(offset) "]]\n"
158
159#define RSEQ_ASM_OP_R_ADD(count) \
160 " add " RSEQ_ASM_TMP_REG ", " RSEQ_ASM_TMP_REG \
161 ", %[" __rseq_str(count) "]\n"
162
163#define RSEQ_ASM_OP_R_FINAL_STORE(var, post_commit_label) \
164 " str " RSEQ_ASM_TMP_REG ", %[" __rseq_str(var) "]\n" \
165 __rseq_str(post_commit_label) ":\n"
166
167#define RSEQ_ASM_OP_R_BAD_MEMCPY(dst, src, len) \
168 " cbz %[" __rseq_str(len) "], 333f\n" \
169 " mov " RSEQ_ASM_TMP_REG_2 ", %[" __rseq_str(len) "]\n" \
170 "222: sub " RSEQ_ASM_TMP_REG_2 ", " RSEQ_ASM_TMP_REG_2 ", #1\n" \
171 " ldrb " RSEQ_ASM_TMP_REG32 ", [%[" __rseq_str(src) "]" \
172 ", " RSEQ_ASM_TMP_REG_2 "]\n" \
173 " strb " RSEQ_ASM_TMP_REG32 ", [%[" __rseq_str(dst) "]" \
174 ", " RSEQ_ASM_TMP_REG_2 "]\n" \
175 " cbnz " RSEQ_ASM_TMP_REG_2 ", 222b\n" \
176 "333:\n"
177
178static inline __attribute__((always_inline))
179int rseq_cmpeqv_storev(intptr_t *v, intptr_t expect, intptr_t newv, int cpu)
180{
181 RSEQ_INJECT_C(9)
182
183 __asm__ __volatile__ goto (
184 RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
185 RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
186 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
187 RSEQ_INJECT_ASM(3)
188 RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail])
189 RSEQ_INJECT_ASM(4)
190#ifdef RSEQ_COMPARE_TWICE
191 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
192 RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2])
193#endif
194 RSEQ_ASM_OP_FINAL_STORE(newv, v, 3)
195 RSEQ_INJECT_ASM(5)
196 RSEQ_ASM_DEFINE_ABORT(4, abort)
197 : /* gcc asm goto does not allow outputs */
198 : [cpu_id] "r" (cpu),
199 [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
200 [rseq_cs] "m" (__rseq_abi.rseq_cs),
201 [v] "Qo" (*v),
202 [expect] "r" (expect),
203 [newv] "r" (newv)
204 RSEQ_INJECT_INPUT
205 : "memory", RSEQ_ASM_TMP_REG
206 : abort, cmpfail
207#ifdef RSEQ_COMPARE_TWICE
208 , error1, error2
209#endif
210 );
211
212 return 0;
213abort:
214 RSEQ_INJECT_FAILED
215 return -1;
216cmpfail:
217 return 1;
218#ifdef RSEQ_COMPARE_TWICE
219error1:
220 rseq_bug("cpu_id comparison failed");
221error2:
222 rseq_bug("expected value comparison failed");
223#endif
224}
225
226static inline __attribute__((always_inline))
227int rseq_cmpnev_storeoffp_load(intptr_t *v, intptr_t expectnot,
228 off_t voffp, intptr_t *load, int cpu)
229{
230 RSEQ_INJECT_C(9)
231
232 __asm__ __volatile__ goto (
233 RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
234 RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
235 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
236 RSEQ_INJECT_ASM(3)
237 RSEQ_ASM_OP_CMPNE(v, expectnot, %l[cmpfail])
238 RSEQ_INJECT_ASM(4)
239#ifdef RSEQ_COMPARE_TWICE
240 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
241 RSEQ_ASM_OP_CMPNE(v, expectnot, %l[error2])
242#endif
243 RSEQ_ASM_OP_R_LOAD(v)
244 RSEQ_ASM_OP_R_STORE(load)
245 RSEQ_ASM_OP_R_LOAD_OFF(voffp)
246 RSEQ_ASM_OP_R_FINAL_STORE(v, 3)
247 RSEQ_INJECT_ASM(5)
248 RSEQ_ASM_DEFINE_ABORT(4, abort)
249 : /* gcc asm goto does not allow outputs */
250 : [cpu_id] "r" (cpu),
251 [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
252 [rseq_cs] "m" (__rseq_abi.rseq_cs),
253 [v] "Qo" (*v),
254 [expectnot] "r" (expectnot),
255 [load] "Qo" (*load),
256 [voffp] "r" (voffp)
257 RSEQ_INJECT_INPUT
258 : "memory", RSEQ_ASM_TMP_REG
259 : abort, cmpfail
260#ifdef RSEQ_COMPARE_TWICE
261 , error1, error2
262#endif
263 );
264 return 0;
265abort:
266 RSEQ_INJECT_FAILED
267 return -1;
268cmpfail:
269 return 1;
270#ifdef RSEQ_COMPARE_TWICE
271error1:
272 rseq_bug("cpu_id comparison failed");
273error2:
274 rseq_bug("expected value comparison failed");
275#endif
276}
277
278static inline __attribute__((always_inline))
279int rseq_addv(intptr_t *v, intptr_t count, int cpu)
280{
281 RSEQ_INJECT_C(9)
282
283 __asm__ __volatile__ goto (
284 RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
285 RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
286 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
287 RSEQ_INJECT_ASM(3)
288#ifdef RSEQ_COMPARE_TWICE
289 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
290#endif
291 RSEQ_ASM_OP_R_LOAD(v)
292 RSEQ_ASM_OP_R_ADD(count)
293 RSEQ_ASM_OP_R_FINAL_STORE(v, 3)
294 RSEQ_INJECT_ASM(4)
295 RSEQ_ASM_DEFINE_ABORT(4, abort)
296 : /* gcc asm goto does not allow outputs */
297 : [cpu_id] "r" (cpu),
298 [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
299 [rseq_cs] "m" (__rseq_abi.rseq_cs),
300 [v] "Qo" (*v),
301 [count] "r" (count)
302 RSEQ_INJECT_INPUT
303 : "memory", RSEQ_ASM_TMP_REG
304 : abort
305#ifdef RSEQ_COMPARE_TWICE
306 , error1
307#endif
308 );
309 return 0;
310abort:
311 RSEQ_INJECT_FAILED
312 return -1;
313#ifdef RSEQ_COMPARE_TWICE
314error1:
315 rseq_bug("cpu_id comparison failed");
316#endif
317}
318
319static inline __attribute__((always_inline))
320int rseq_cmpeqv_trystorev_storev(intptr_t *v, intptr_t expect,
321 intptr_t *v2, intptr_t newv2,
322 intptr_t newv, int cpu)
323{
324 RSEQ_INJECT_C(9)
325
326 __asm__ __volatile__ goto (
327 RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
328 RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
329 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
330 RSEQ_INJECT_ASM(3)
331 RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail])
332 RSEQ_INJECT_ASM(4)
333#ifdef RSEQ_COMPARE_TWICE
334 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
335 RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2])
336#endif
337 RSEQ_ASM_OP_STORE(newv2, v2)
338 RSEQ_INJECT_ASM(5)
339 RSEQ_ASM_OP_FINAL_STORE(newv, v, 3)
340 RSEQ_INJECT_ASM(6)
341 RSEQ_ASM_DEFINE_ABORT(4, abort)
342 : /* gcc asm goto does not allow outputs */
343 : [cpu_id] "r" (cpu),
344 [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
345 [rseq_cs] "m" (__rseq_abi.rseq_cs),
346 [expect] "r" (expect),
347 [v] "Qo" (*v),
348 [newv] "r" (newv),
349 [v2] "Qo" (*v2),
350 [newv2] "r" (newv2)
351 RSEQ_INJECT_INPUT
352 : "memory", RSEQ_ASM_TMP_REG
353 : abort, cmpfail
354#ifdef RSEQ_COMPARE_TWICE
355 , error1, error2
356#endif
357 );
358
359 return 0;
360abort:
361 RSEQ_INJECT_FAILED
362 return -1;
363cmpfail:
364 return 1;
365#ifdef RSEQ_COMPARE_TWICE
366error1:
367 rseq_bug("cpu_id comparison failed");
368error2:
369 rseq_bug("expected value comparison failed");
370#endif
371}
372
373static inline __attribute__((always_inline))
374int rseq_cmpeqv_trystorev_storev_release(intptr_t *v, intptr_t expect,
375 intptr_t *v2, intptr_t newv2,
376 intptr_t newv, int cpu)
377{
378 RSEQ_INJECT_C(9)
379
380 __asm__ __volatile__ goto (
381 RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
382 RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
383 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
384 RSEQ_INJECT_ASM(3)
385 RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail])
386 RSEQ_INJECT_ASM(4)
387#ifdef RSEQ_COMPARE_TWICE
388 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
389 RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2])
390#endif
391 RSEQ_ASM_OP_STORE(newv2, v2)
392 RSEQ_INJECT_ASM(5)
393 RSEQ_ASM_OP_FINAL_STORE_RELEASE(newv, v, 3)
394 RSEQ_INJECT_ASM(6)
395 RSEQ_ASM_DEFINE_ABORT(4, abort)
396 : /* gcc asm goto does not allow outputs */
397 : [cpu_id] "r" (cpu),
398 [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
399 [rseq_cs] "m" (__rseq_abi.rseq_cs),
400 [expect] "r" (expect),
401 [v] "Qo" (*v),
402 [newv] "r" (newv),
403 [v2] "Qo" (*v2),
404 [newv2] "r" (newv2)
405 RSEQ_INJECT_INPUT
406 : "memory", RSEQ_ASM_TMP_REG
407 : abort, cmpfail
408#ifdef RSEQ_COMPARE_TWICE
409 , error1, error2
410#endif
411 );
412
413 return 0;
414abort:
415 RSEQ_INJECT_FAILED
416 return -1;
417cmpfail:
418 return 1;
419#ifdef RSEQ_COMPARE_TWICE
420error1:
421 rseq_bug("cpu_id comparison failed");
422error2:
423 rseq_bug("expected value comparison failed");
424#endif
425}
426
427static inline __attribute__((always_inline))
428int rseq_cmpeqv_cmpeqv_storev(intptr_t *v, intptr_t expect,
429 intptr_t *v2, intptr_t expect2,
430 intptr_t newv, int cpu)
431{
432 RSEQ_INJECT_C(9)
433
434 __asm__ __volatile__ goto (
435 RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
436 RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
437 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
438 RSEQ_INJECT_ASM(3)
439 RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail])
440 RSEQ_INJECT_ASM(4)
441 RSEQ_ASM_OP_CMPEQ(v2, expect2, %l[cmpfail])
442 RSEQ_INJECT_ASM(5)
443#ifdef RSEQ_COMPARE_TWICE
444 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
445 RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2])
446 RSEQ_ASM_OP_CMPEQ(v2, expect2, %l[error3])
447#endif
448 RSEQ_ASM_OP_FINAL_STORE(newv, v, 3)
449 RSEQ_INJECT_ASM(6)
450 RSEQ_ASM_DEFINE_ABORT(4, abort)
451 : /* gcc asm goto does not allow outputs */
452 : [cpu_id] "r" (cpu),
453 [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
454 [rseq_cs] "m" (__rseq_abi.rseq_cs),
455 [v] "Qo" (*v),
456 [expect] "r" (expect),
457 [v2] "Qo" (*v2),
458 [expect2] "r" (expect2),
459 [newv] "r" (newv)
460 RSEQ_INJECT_INPUT
461 : "memory", RSEQ_ASM_TMP_REG
462 : abort, cmpfail
463#ifdef RSEQ_COMPARE_TWICE
464 , error1, error2, error3
465#endif
466 );
467
468 return 0;
469abort:
470 RSEQ_INJECT_FAILED
471 return -1;
472cmpfail:
473 return 1;
474#ifdef RSEQ_COMPARE_TWICE
475error1:
476 rseq_bug("cpu_id comparison failed");
477error2:
478 rseq_bug("expected value comparison failed");
479error3:
480 rseq_bug("2nd expected value comparison failed");
481#endif
482}
483
484static inline __attribute__((always_inline))
485int rseq_cmpeqv_trymemcpy_storev(intptr_t *v, intptr_t expect,
486 void *dst, void *src, size_t len,
487 intptr_t newv, int cpu)
488{
489 RSEQ_INJECT_C(9)
490
491 __asm__ __volatile__ goto (
492 RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
493 RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
494 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
495 RSEQ_INJECT_ASM(3)
496 RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail])
497 RSEQ_INJECT_ASM(4)
498#ifdef RSEQ_COMPARE_TWICE
499 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
500 RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2])
501#endif
502 RSEQ_ASM_OP_R_BAD_MEMCPY(dst, src, len)
503 RSEQ_INJECT_ASM(5)
504 RSEQ_ASM_OP_FINAL_STORE(newv, v, 3)
505 RSEQ_INJECT_ASM(6)
506 RSEQ_ASM_DEFINE_ABORT(4, abort)
507 : /* gcc asm goto does not allow outputs */
508 : [cpu_id] "r" (cpu),
509 [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
510 [rseq_cs] "m" (__rseq_abi.rseq_cs),
511 [expect] "r" (expect),
512 [v] "Qo" (*v),
513 [newv] "r" (newv),
514 [dst] "r" (dst),
515 [src] "r" (src),
516 [len] "r" (len)
517 RSEQ_INJECT_INPUT
518 : "memory", RSEQ_ASM_TMP_REG, RSEQ_ASM_TMP_REG_2
519 : abort, cmpfail
520#ifdef RSEQ_COMPARE_TWICE
521 , error1, error2
522#endif
523 );
524
525 return 0;
526abort:
527 RSEQ_INJECT_FAILED
528 return -1;
529cmpfail:
530 return 1;
531#ifdef RSEQ_COMPARE_TWICE
532error1:
533 rseq_bug("cpu_id comparison failed");
534error2:
535 rseq_bug("expected value comparison failed");
536#endif
537}
538
539static inline __attribute__((always_inline))
540int rseq_cmpeqv_trymemcpy_storev_release(intptr_t *v, intptr_t expect,
541 void *dst, void *src, size_t len,
542 intptr_t newv, int cpu)
543{
544 RSEQ_INJECT_C(9)
545
546 __asm__ __volatile__ goto (
547 RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f)
548 RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs)
549 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
550 RSEQ_INJECT_ASM(3)
551 RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail])
552 RSEQ_INJECT_ASM(4)
553#ifdef RSEQ_COMPARE_TWICE
554 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
555 RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2])
556#endif
557 RSEQ_ASM_OP_R_BAD_MEMCPY(dst, src, len)
558 RSEQ_INJECT_ASM(5)
559 RSEQ_ASM_OP_FINAL_STORE_RELEASE(newv, v, 3)
560 RSEQ_INJECT_ASM(6)
561 RSEQ_ASM_DEFINE_ABORT(4, abort)
562 : /* gcc asm goto does not allow outputs */
563 : [cpu_id] "r" (cpu),
564 [current_cpu_id] "Qo" (__rseq_abi.cpu_id),
565 [rseq_cs] "m" (__rseq_abi.rseq_cs),
566 [expect] "r" (expect),
567 [v] "Qo" (*v),
568 [newv] "r" (newv),
569 [dst] "r" (dst),
570 [src] "r" (src),
571 [len] "r" (len)
572 RSEQ_INJECT_INPUT
573 : "memory", RSEQ_ASM_TMP_REG, RSEQ_ASM_TMP_REG_2
574 : abort, cmpfail
575#ifdef RSEQ_COMPARE_TWICE
576 , error1, error2
577#endif
578 );
579
580 return 0;
581abort:
582 RSEQ_INJECT_FAILED
583 return -1;
584cmpfail:
585 return 1;
586#ifdef RSEQ_COMPARE_TWICE
587error1:
588 rseq_bug("cpu_id comparison failed");
589error2:
590 rseq_bug("expected value comparison failed");
591#endif
592}
593
594#endif /* !RSEQ_SKIP_FASTPATH */
diff --git a/tools/testing/selftests/rseq/rseq-s390.h b/tools/testing/selftests/rseq/rseq-s390.h
new file mode 100644
index 000000000000..1069e85258ce
--- /dev/null
+++ b/tools/testing/selftests/rseq/rseq-s390.h
@@ -0,0 +1,513 @@
1/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
2
3#define RSEQ_SIG 0x53053053
4
5#define rseq_smp_mb() __asm__ __volatile__ ("bcr 15,0" ::: "memory")
6#define rseq_smp_rmb() rseq_smp_mb()
7#define rseq_smp_wmb() rseq_smp_mb()
8
9#define rseq_smp_load_acquire(p) \
10__extension__ ({ \
11 __typeof(*p) ____p1 = RSEQ_READ_ONCE(*p); \
12 rseq_barrier(); \
13 ____p1; \
14})
15
16#define rseq_smp_acquire__after_ctrl_dep() rseq_smp_rmb()
17
18#define rseq_smp_store_release(p, v) \
19do { \
20 rseq_barrier(); \
21 RSEQ_WRITE_ONCE(*p, v); \
22} while (0)
23
24#ifdef RSEQ_SKIP_FASTPATH
25#include "rseq-skip.h"
26#else /* !RSEQ_SKIP_FASTPATH */
27
28#ifdef __s390x__
29
30#define LONG_L "lg"
31#define LONG_S "stg"
32#define LONG_LT_R "ltgr"
33#define LONG_CMP "cg"
34#define LONG_CMP_R "cgr"
35#define LONG_ADDI "aghi"
36#define LONG_ADD_R "agr"
37
38#define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, \
39 start_ip, post_commit_offset, abort_ip) \
40 ".pushsection __rseq_table, \"aw\"\n\t" \
41 ".balign 32\n\t" \
42 __rseq_str(label) ":\n\t" \
43 ".long " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \
44 ".quad " __rseq_str(start_ip) ", " __rseq_str(post_commit_offset) ", " __rseq_str(abort_ip) "\n\t" \
45 ".popsection\n\t"
46
47#elif __s390__
48
49#define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, \
50 start_ip, post_commit_offset, abort_ip) \
51 ".pushsection __rseq_table, \"aw\"\n\t" \
52 ".balign 32\n\t" \
53 __rseq_str(label) ":\n\t" \
54 ".long " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \
55 ".long 0x0, " __rseq_str(start_ip) ", 0x0, " __rseq_str(post_commit_offset) ", 0x0, " __rseq_str(abort_ip) "\n\t" \
56 ".popsection\n\t"
57
58#define LONG_L "l"
59#define LONG_S "st"
60#define LONG_LT_R "ltr"
61#define LONG_CMP "c"
62#define LONG_CMP_R "cr"
63#define LONG_ADDI "ahi"
64#define LONG_ADD_R "ar"
65
66#endif
67
68#define RSEQ_ASM_DEFINE_TABLE(label, start_ip, post_commit_ip, abort_ip) \
69 __RSEQ_ASM_DEFINE_TABLE(label, 0x0, 0x0, start_ip, \
70 (post_commit_ip - start_ip), abort_ip)
71
72#define RSEQ_ASM_STORE_RSEQ_CS(label, cs_label, rseq_cs) \
73 RSEQ_INJECT_ASM(1) \
74 "larl %%r0, " __rseq_str(cs_label) "\n\t" \
75 LONG_S " %%r0, %[" __rseq_str(rseq_cs) "]\n\t" \
76 __rseq_str(label) ":\n\t"
77
78#define RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, label) \
79 RSEQ_INJECT_ASM(2) \
80 "c %[" __rseq_str(cpu_id) "], %[" __rseq_str(current_cpu_id) "]\n\t" \
81 "jnz " __rseq_str(label) "\n\t"
82
83#define RSEQ_ASM_DEFINE_ABORT(label, teardown, abort_label) \
84 ".pushsection __rseq_failure, \"ax\"\n\t" \
85 ".long " __rseq_str(RSEQ_SIG) "\n\t" \
86 __rseq_str(label) ":\n\t" \
87 teardown \
88 "j %l[" __rseq_str(abort_label) "]\n\t" \
89 ".popsection\n\t"
90
91#define RSEQ_ASM_DEFINE_CMPFAIL(label, teardown, cmpfail_label) \
92 ".pushsection __rseq_failure, \"ax\"\n\t" \
93 __rseq_str(label) ":\n\t" \
94 teardown \
95 "j %l[" __rseq_str(cmpfail_label) "]\n\t" \
96 ".popsection\n\t"
97
98static inline __attribute__((always_inline))
99int rseq_cmpeqv_storev(intptr_t *v, intptr_t expect, intptr_t newv, int cpu)
100{
101 RSEQ_INJECT_C(9)
102
103 __asm__ __volatile__ goto (
104 RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
105 /* Start rseq by storing table entry pointer into rseq_cs. */
106 RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
107 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
108 RSEQ_INJECT_ASM(3)
109 LONG_CMP " %[expect], %[v]\n\t"
110 "jnz %l[cmpfail]\n\t"
111 RSEQ_INJECT_ASM(4)
112#ifdef RSEQ_COMPARE_TWICE
113 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
114 LONG_CMP " %[expect], %[v]\n\t"
115 "jnz %l[error2]\n\t"
116#endif
117 /* final store */
118 LONG_S " %[newv], %[v]\n\t"
119 "2:\n\t"
120 RSEQ_INJECT_ASM(5)
121 RSEQ_ASM_DEFINE_ABORT(4, "", abort)
122 : /* gcc asm goto does not allow outputs */
123 : [cpu_id] "r" (cpu),
124 [current_cpu_id] "m" (__rseq_abi.cpu_id),
125 [rseq_cs] "m" (__rseq_abi.rseq_cs),
126 [v] "m" (*v),
127 [expect] "r" (expect),
128 [newv] "r" (newv)
129 RSEQ_INJECT_INPUT
130 : "memory", "cc", "r0"
131 RSEQ_INJECT_CLOBBER
132 : abort, cmpfail
133#ifdef RSEQ_COMPARE_TWICE
134 , error1, error2
135#endif
136 );
137 return 0;
138abort:
139 RSEQ_INJECT_FAILED
140 return -1;
141cmpfail:
142 return 1;
143#ifdef RSEQ_COMPARE_TWICE
144error1:
145 rseq_bug("cpu_id comparison failed");
146error2:
147 rseq_bug("expected value comparison failed");
148#endif
149}
150
151/*
152 * Compare @v against @expectnot. When it does _not_ match, load @v
153 * into @load, and store the content of *@v + voffp into @v.
154 */
155static inline __attribute__((always_inline))
156int rseq_cmpnev_storeoffp_load(intptr_t *v, intptr_t expectnot,
157 off_t voffp, intptr_t *load, int cpu)
158{
159 RSEQ_INJECT_C(9)
160
161 __asm__ __volatile__ goto (
162 RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
163 /* Start rseq by storing table entry pointer into rseq_cs. */
164 RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
165 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
166 RSEQ_INJECT_ASM(3)
167 LONG_L " %%r1, %[v]\n\t"
168 LONG_CMP_R " %%r1, %[expectnot]\n\t"
169 "je %l[cmpfail]\n\t"
170 RSEQ_INJECT_ASM(4)
171#ifdef RSEQ_COMPARE_TWICE
172 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
173 LONG_L " %%r1, %[v]\n\t"
174 LONG_CMP_R " %%r1, %[expectnot]\n\t"
175 "je %l[error2]\n\t"
176#endif
177 LONG_S " %%r1, %[load]\n\t"
178 LONG_ADD_R " %%r1, %[voffp]\n\t"
179 LONG_L " %%r1, 0(%%r1)\n\t"
180 /* final store */
181 LONG_S " %%r1, %[v]\n\t"
182 "2:\n\t"
183 RSEQ_INJECT_ASM(5)
184 RSEQ_ASM_DEFINE_ABORT(4, "", abort)
185 : /* gcc asm goto does not allow outputs */
186 : [cpu_id] "r" (cpu),
187 [current_cpu_id] "m" (__rseq_abi.cpu_id),
188 [rseq_cs] "m" (__rseq_abi.rseq_cs),
189 /* final store input */
190 [v] "m" (*v),
191 [expectnot] "r" (expectnot),
192 [voffp] "r" (voffp),
193 [load] "m" (*load)
194 RSEQ_INJECT_INPUT
195 : "memory", "cc", "r0", "r1"
196 RSEQ_INJECT_CLOBBER
197 : abort, cmpfail
198#ifdef RSEQ_COMPARE_TWICE
199 , error1, error2
200#endif
201 );
202 return 0;
203abort:
204 RSEQ_INJECT_FAILED
205 return -1;
206cmpfail:
207 return 1;
208#ifdef RSEQ_COMPARE_TWICE
209error1:
210 rseq_bug("cpu_id comparison failed");
211error2:
212 rseq_bug("expected value comparison failed");
213#endif
214}
215
216static inline __attribute__((always_inline))
217int rseq_addv(intptr_t *v, intptr_t count, int cpu)
218{
219 RSEQ_INJECT_C(9)
220
221 __asm__ __volatile__ goto (
222 RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
223 /* Start rseq by storing table entry pointer into rseq_cs. */
224 RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
225 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
226 RSEQ_INJECT_ASM(3)
227#ifdef RSEQ_COMPARE_TWICE
228 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
229#endif
230 LONG_L " %%r0, %[v]\n\t"
231 LONG_ADD_R " %%r0, %[count]\n\t"
232 /* final store */
233 LONG_S " %%r0, %[v]\n\t"
234 "2:\n\t"
235 RSEQ_INJECT_ASM(4)
236 RSEQ_ASM_DEFINE_ABORT(4, "", abort)
237 : /* gcc asm goto does not allow outputs */
238 : [cpu_id] "r" (cpu),
239 [current_cpu_id] "m" (__rseq_abi.cpu_id),
240 [rseq_cs] "m" (__rseq_abi.rseq_cs),
241 /* final store input */
242 [v] "m" (*v),
243 [count] "r" (count)
244 RSEQ_INJECT_INPUT
245 : "memory", "cc", "r0"
246 RSEQ_INJECT_CLOBBER
247 : abort
248#ifdef RSEQ_COMPARE_TWICE
249 , error1
250#endif
251 );
252 return 0;
253abort:
254 RSEQ_INJECT_FAILED
255 return -1;
256#ifdef RSEQ_COMPARE_TWICE
257error1:
258 rseq_bug("cpu_id comparison failed");
259#endif
260}
261
262static inline __attribute__((always_inline))
263int rseq_cmpeqv_trystorev_storev(intptr_t *v, intptr_t expect,
264 intptr_t *v2, intptr_t newv2,
265 intptr_t newv, int cpu)
266{
267 RSEQ_INJECT_C(9)
268
269 __asm__ __volatile__ goto (
270 RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
271 /* Start rseq by storing table entry pointer into rseq_cs. */
272 RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
273 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
274 RSEQ_INJECT_ASM(3)
275 LONG_CMP " %[expect], %[v]\n\t"
276 "jnz %l[cmpfail]\n\t"
277 RSEQ_INJECT_ASM(4)
278#ifdef RSEQ_COMPARE_TWICE
279 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
280 LONG_CMP " %[expect], %[v]\n\t"
281 "jnz %l[error2]\n\t"
282#endif
283 /* try store */
284 LONG_S " %[newv2], %[v2]\n\t"
285 RSEQ_INJECT_ASM(5)
286 /* final store */
287 LONG_S " %[newv], %[v]\n\t"
288 "2:\n\t"
289 RSEQ_INJECT_ASM(6)
290 RSEQ_ASM_DEFINE_ABORT(4, "", abort)
291 : /* gcc asm goto does not allow outputs */
292 : [cpu_id] "r" (cpu),
293 [current_cpu_id] "m" (__rseq_abi.cpu_id),
294 [rseq_cs] "m" (__rseq_abi.rseq_cs),
295 /* try store input */
296 [v2] "m" (*v2),
297 [newv2] "r" (newv2),
298 /* final store input */
299 [v] "m" (*v),
300 [expect] "r" (expect),
301 [newv] "r" (newv)
302 RSEQ_INJECT_INPUT
303 : "memory", "cc", "r0"
304 RSEQ_INJECT_CLOBBER
305 : abort, cmpfail
306#ifdef RSEQ_COMPARE_TWICE
307 , error1, error2
308#endif
309 );
310 return 0;
311abort:
312 RSEQ_INJECT_FAILED
313 return -1;
314cmpfail:
315 return 1;
316#ifdef RSEQ_COMPARE_TWICE
317error1:
318 rseq_bug("cpu_id comparison failed");
319error2:
320 rseq_bug("expected value comparison failed");
321#endif
322}
323
324/* s390 is TSO. */
325static inline __attribute__((always_inline))
326int rseq_cmpeqv_trystorev_storev_release(intptr_t *v, intptr_t expect,
327 intptr_t *v2, intptr_t newv2,
328 intptr_t newv, int cpu)
329{
330 return rseq_cmpeqv_trystorev_storev(v, expect, v2, newv2, newv, cpu);
331}
332
333static inline __attribute__((always_inline))
334int rseq_cmpeqv_cmpeqv_storev(intptr_t *v, intptr_t expect,
335 intptr_t *v2, intptr_t expect2,
336 intptr_t newv, int cpu)
337{
338 RSEQ_INJECT_C(9)
339
340 __asm__ __volatile__ goto (
341 RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
342 /* Start rseq by storing table entry pointer into rseq_cs. */
343 RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
344 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
345 RSEQ_INJECT_ASM(3)
346 LONG_CMP " %[expect], %[v]\n\t"
347 "jnz %l[cmpfail]\n\t"
348 RSEQ_INJECT_ASM(4)
349 LONG_CMP " %[expect2], %[v2]\n\t"
350 "jnz %l[cmpfail]\n\t"
351 RSEQ_INJECT_ASM(5)
352#ifdef RSEQ_COMPARE_TWICE
353 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
354 LONG_CMP " %[expect], %[v]\n\t"
355 "jnz %l[error2]\n\t"
356 LONG_CMP " %[expect2], %[v2]\n\t"
357 "jnz %l[error3]\n\t"
358#endif
359 /* final store */
360 LONG_S " %[newv], %[v]\n\t"
361 "2:\n\t"
362 RSEQ_INJECT_ASM(6)
363 RSEQ_ASM_DEFINE_ABORT(4, "", abort)
364 : /* gcc asm goto does not allow outputs */
365 : [cpu_id] "r" (cpu),
366 [current_cpu_id] "m" (__rseq_abi.cpu_id),
367 [rseq_cs] "m" (__rseq_abi.rseq_cs),
368 /* cmp2 input */
369 [v2] "m" (*v2),
370 [expect2] "r" (expect2),
371 /* final store input */
372 [v] "m" (*v),
373 [expect] "r" (expect),
374 [newv] "r" (newv)
375 RSEQ_INJECT_INPUT
376 : "memory", "cc", "r0"
377 RSEQ_INJECT_CLOBBER
378 : abort, cmpfail
379#ifdef RSEQ_COMPARE_TWICE
380 , error1, error2, error3
381#endif
382 );
383 return 0;
384abort:
385 RSEQ_INJECT_FAILED
386 return -1;
387cmpfail:
388 return 1;
389#ifdef RSEQ_COMPARE_TWICE
390error1:
391 rseq_bug("cpu_id comparison failed");
392error2:
393 rseq_bug("1st expected value comparison failed");
394error3:
395 rseq_bug("2nd expected value comparison failed");
396#endif
397}
398
399static inline __attribute__((always_inline))
400int rseq_cmpeqv_trymemcpy_storev(intptr_t *v, intptr_t expect,
401 void *dst, void *src, size_t len,
402 intptr_t newv, int cpu)
403{
404 uint64_t rseq_scratch[3];
405
406 RSEQ_INJECT_C(9)
407
408 __asm__ __volatile__ goto (
409 RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
410 LONG_S " %[src], %[rseq_scratch0]\n\t"
411 LONG_S " %[dst], %[rseq_scratch1]\n\t"
412 LONG_S " %[len], %[rseq_scratch2]\n\t"
413 /* Start rseq by storing table entry pointer into rseq_cs. */
414 RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
415 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
416 RSEQ_INJECT_ASM(3)
417 LONG_CMP " %[expect], %[v]\n\t"
418 "jnz 5f\n\t"
419 RSEQ_INJECT_ASM(4)
420#ifdef RSEQ_COMPARE_TWICE
421 RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 6f)
422 LONG_CMP " %[expect], %[v]\n\t"
423 "jnz 7f\n\t"
424#endif
425 /* try memcpy */
426 LONG_LT_R " %[len], %[len]\n\t"
427 "jz 333f\n\t"
428 "222:\n\t"
429 "ic %%r0,0(%[src])\n\t"
430 "stc %%r0,0(%[dst])\n\t"
431 LONG_ADDI " %[src], 1\n\t"
432 LONG_ADDI " %[dst], 1\n\t"
433 LONG_ADDI " %[len], -1\n\t"
434 "jnz 222b\n\t"
435 "333:\n\t"
436 RSEQ_INJECT_ASM(5)
437 /* final store */
438 LONG_S " %[newv], %[v]\n\t"
439 "2:\n\t"
440 RSEQ_INJECT_ASM(6)
441 /* teardown */
442 LONG_L " %[len], %[rseq_scratch2]\n\t"
443 LONG_L " %[dst], %[rseq_scratch1]\n\t"
444 LONG_L " %[src], %[rseq_scratch0]\n\t"
445 RSEQ_ASM_DEFINE_ABORT(4,
446 LONG_L " %[len], %[rseq_scratch2]\n\t"
447 LONG_L " %[dst], %[rseq_scratch1]\n\t"
448 LONG_L " %[src], %[rseq_scratch0]\n\t",
449 abort)
450 RSEQ_ASM_DEFINE_CMPFAIL(5,
451 LONG_L " %[len], %[rseq_scratch2]\n\t"
452 LONG_L " %[dst], %[rseq_scratch1]\n\t"
453 LONG_L " %[src], %[rseq_scratch0]\n\t",
454 cmpfail)
455#ifdef RSEQ_COMPARE_TWICE
456 RSEQ_ASM_DEFINE_CMPFAIL(6,
457 LONG_L " %[len], %[rseq_scratch2]\n\t"
458 LONG_L " %[dst], %[rseq_scratch1]\n\t"
459 LONG_L " %[src], %[rseq_scratch0]\n\t",
460 error1)
461 RSEQ_ASM_DEFINE_CMPFAIL(7,
462 LONG_L " %[len], %[rseq_scratch2]\n\t"
463 LONG_L " %[dst], %[rseq_scratch1]\n\t"
464 LONG_L " %[src], %[rseq_scratch0]\n\t",
465 error2)
466#endif
467 : /* gcc asm goto does not allow outputs */
468 : [cpu_id] "r" (cpu),
469 [current_cpu_id] "m" (__rseq_abi.cpu_id),
470 [rseq_cs] "m" (__rseq_abi.rseq_cs),
471 /* final store input */
472 [v] "m" (*v),
473 [expect] "r" (expect),
474 [newv] "r" (newv),
475 /* try memcpy input */
476 [dst] "r" (dst),
477 [src] "r" (src),
478 [len] "r" (len),
479 [rseq_scratch0] "m" (rseq_scratch[0]),
480 [rseq_scratch1] "m" (rseq_scratch[1]),
481 [rseq_scratch2] "m" (rseq_scratch[2])
482 RSEQ_INJECT_INPUT
483 : "memory", "cc", "r0"
484 RSEQ_INJECT_CLOBBER
485 : abort, cmpfail
486#ifdef RSEQ_COMPARE_TWICE
487 , error1, error2
488#endif
489 );
490 return 0;
491abort:
492 RSEQ_INJECT_FAILED
493 return -1;
494cmpfail:
495 return 1;
496#ifdef RSEQ_COMPARE_TWICE
497error1:
498 rseq_bug("cpu_id comparison failed");
499error2:
500 rseq_bug("expected value comparison failed");
501#endif
502}
503
504/* s390 is TSO. */
505static inline __attribute__((always_inline))
506int rseq_cmpeqv_trymemcpy_storev_release(intptr_t *v, intptr_t expect,
507 void *dst, void *src, size_t len,
508 intptr_t newv, int cpu)
509{
510 return rseq_cmpeqv_trymemcpy_storev(v, expect, dst, src, len,
511 newv, cpu);
512}
513#endif /* !RSEQ_SKIP_FASTPATH */
diff --git a/tools/testing/selftests/rseq/rseq.h b/tools/testing/selftests/rseq/rseq.h
index 86ce22417e0d..c72eb70f9b52 100644
--- a/tools/testing/selftests/rseq/rseq.h
+++ b/tools/testing/selftests/rseq/rseq.h
@@ -71,10 +71,14 @@ extern __thread volatile struct rseq __rseq_abi;
71#include <rseq-x86.h> 71#include <rseq-x86.h>
72#elif defined(__ARMEL__) 72#elif defined(__ARMEL__)
73#include <rseq-arm.h> 73#include <rseq-arm.h>
74#elif defined (__AARCH64EL__)
75#include <rseq-arm64.h>
74#elif defined(__PPC__) 76#elif defined(__PPC__)
75#include <rseq-ppc.h> 77#include <rseq-ppc.h>
76#elif defined(__mips__) 78#elif defined(__mips__)
77#include <rseq-mips.h> 79#include <rseq-mips.h>
80#elif defined(__s390__)
81#include <rseq-s390.h>
78#else 82#else
79#error unsupported target 83#error unsupported target
80#endif 84#endif
diff --git a/tools/testing/selftests/tc-testing/README b/tools/testing/selftests/tc-testing/README
index 3a0336782d2d..49a6f8c3fdae 100644
--- a/tools/testing/selftests/tc-testing/README
+++ b/tools/testing/selftests/tc-testing/README
@@ -17,6 +17,10 @@ REQUIREMENTS
17* The kernel must have veth support available, as a veth pair is created 17* The kernel must have veth support available, as a veth pair is created
18 prior to running the tests. 18 prior to running the tests.
19 19
20* The kernel must have the appropriate infrastructure enabled to run all tdc
21 unit tests. See the config file in this directory for minimum required
22 features. As new tests will be added, config options list will be updated.
23
20* All tc-related features being tested must be built in or available as 24* All tc-related features being tested must be built in or available as
21 modules. To check what is required in current setup run: 25 modules. To check what is required in current setup run:
22 ./tdc.py -c 26 ./tdc.py -c
@@ -109,8 +113,8 @@ COMMAND LINE ARGUMENTS
109Run tdc.py -h to see the full list of available arguments. 113Run tdc.py -h to see the full list of available arguments.
110 114
111usage: tdc.py [-h] [-p PATH] [-D DIR [DIR ...]] [-f FILE [FILE ...]] 115usage: tdc.py [-h] [-p PATH] [-D DIR [DIR ...]] [-f FILE [FILE ...]]
112 [-c [CATG [CATG ...]]] [-e ID [ID ...]] [-l] [-s] [-i] [-v] 116 [-c [CATG [CATG ...]]] [-e ID [ID ...]] [-l] [-s] [-i] [-v] [-N]
113 [-d DEVICE] [-n NS] [-V] 117 [-d DEVICE] [-P] [-n] [-V]
114 118
115Linux TC unit tests 119Linux TC unit tests
116 120
@@ -118,8 +122,10 @@ optional arguments:
118 -h, --help show this help message and exit 122 -h, --help show this help message and exit
119 -p PATH, --path PATH The full path to the tc executable to use 123 -p PATH, --path PATH The full path to the tc executable to use
120 -v, --verbose Show the commands that are being run 124 -v, --verbose Show the commands that are being run
125 -N, --notap Suppress tap results for command under test
121 -d DEVICE, --device DEVICE 126 -d DEVICE, --device DEVICE
122 Execute the test case in flower category 127 Execute the test case in flower category
128 -P, --pause Pause execution just before post-suite stage
123 129
124selection: 130selection:
125 select which test cases: files plus directories; filtered by categories 131 select which test cases: files plus directories; filtered by categories
@@ -146,10 +152,10 @@ action:
146 -i, --id Generate ID numbers for new test cases 152 -i, --id Generate ID numbers for new test cases
147 153
148netns: 154netns:
149 options for nsPlugin(run commands in net namespace) 155 options for nsPlugin (run commands in net namespace)
150 156
151 -n NS, --namespace NS 157 -n, --namespace
152 Run commands in namespace NS 158 Run commands in namespace as specified in tdc_config.py
153 159
154valgrind: 160valgrind:
155 options for valgrindPlugin (run command under test under Valgrind) 161 options for valgrindPlugin (run command under test under Valgrind)
diff --git a/tools/testing/selftests/tc-testing/config b/tools/testing/selftests/tc-testing/config
new file mode 100644
index 000000000000..203302065458
--- /dev/null
+++ b/tools/testing/selftests/tc-testing/config
@@ -0,0 +1,48 @@
1CONFIG_NET_SCHED=y
2
3#
4# Queueing/Scheduling
5#
6CONFIG_NET_SCH_PRIO=m
7CONFIG_NET_SCH_INGRESS=m
8
9#
10# Classification
11#
12CONFIG_NET_CLS=y
13CONFIG_NET_CLS_FW=m
14CONFIG_NET_CLS_U32=m
15CONFIG_CLS_U32_PERF=y
16CONFIG_CLS_U32_MARK=y
17CONFIG_NET_EMATCH=y
18CONFIG_NET_EMATCH_STACK=32
19CONFIG_NET_EMATCH_CMP=m
20CONFIG_NET_EMATCH_NBYTE=m
21CONFIG_NET_EMATCH_U32=m
22CONFIG_NET_EMATCH_META=m
23CONFIG_NET_EMATCH_TEXT=m
24CONFIG_NET_EMATCH_IPSET=m
25CONFIG_NET_EMATCH_IPT=m
26CONFIG_NET_CLS_ACT=y
27CONFIG_NET_ACT_POLICE=m
28CONFIG_NET_ACT_GACT=m
29CONFIG_GACT_PROB=y
30CONFIG_NET_ACT_MIRRED=m
31CONFIG_NET_ACT_SAMPLE=m
32CONFIG_NET_ACT_IPT=m
33CONFIG_NET_ACT_NAT=m
34CONFIG_NET_ACT_PEDIT=m
35CONFIG_NET_ACT_SIMP=m
36CONFIG_NET_ACT_SKBEDIT=m
37CONFIG_NET_ACT_CSUM=m
38CONFIG_NET_ACT_VLAN=m
39CONFIG_NET_ACT_BPF=m
40CONFIG_NET_ACT_CONNMARK=m
41CONFIG_NET_ACT_SKBMOD=m
42CONFIG_NET_ACT_IFE=m
43CONFIG_NET_ACT_TUNNEL_KEY=m
44CONFIG_NET_IFE_SKBMARK=m
45CONFIG_NET_IFE_SKBPRIO=m
46CONFIG_NET_IFE_SKBTCINDEX=m
47CONFIG_NET_CLS_IND=y
48CONFIG_NET_SCH_FIFO=y
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/connmark.json b/tools/testing/selftests/tc-testing/tc-tests/actions/connmark.json
index 70952bd98ff9..13147a1f5731 100644
--- a/tools/testing/selftests/tc-testing/tc-tests/actions/connmark.json
+++ b/tools/testing/selftests/tc-testing/tc-tests/actions/connmark.json
@@ -17,7 +17,7 @@
17 "cmdUnderTest": "$TC actions add action connmark", 17 "cmdUnderTest": "$TC actions add action connmark",
18 "expExitCode": "0", 18 "expExitCode": "0",
19 "verifyCmd": "$TC actions list action connmark", 19 "verifyCmd": "$TC actions list action connmark",
20 "matchPattern": "action order [0-9]+: connmark zone 0 pipe", 20 "matchPattern": "action order [0-9]+: connmark zone 0 pipe",
21 "matchCount": "1", 21 "matchCount": "1",
22 "teardown": [ 22 "teardown": [
23 "$TC actions flush action connmark" 23 "$TC actions flush action connmark"
@@ -41,7 +41,7 @@
41 "cmdUnderTest": "$TC actions add action connmark pass index 1", 41 "cmdUnderTest": "$TC actions add action connmark pass index 1",
42 "expExitCode": "0", 42 "expExitCode": "0",
43 "verifyCmd": "$TC actions get action connmark index 1", 43 "verifyCmd": "$TC actions get action connmark index 1",
44 "matchPattern": "action order [0-9]+: connmark zone 0 pass.*index 1 ref", 44 "matchPattern": "action order [0-9]+: connmark zone 0 pass.*index 1 ref",
45 "matchCount": "1", 45 "matchCount": "1",
46 "teardown": [ 46 "teardown": [
47 "$TC actions flush action connmark" 47 "$TC actions flush action connmark"
@@ -65,7 +65,7 @@
65 "cmdUnderTest": "$TC actions add action connmark drop index 100", 65 "cmdUnderTest": "$TC actions add action connmark drop index 100",
66 "expExitCode": "0", 66 "expExitCode": "0",
67 "verifyCmd": "$TC actions get action connmark index 100", 67 "verifyCmd": "$TC actions get action connmark index 100",
68 "matchPattern": "action order [0-9]+: connmark zone 0 drop.*index 100 ref", 68 "matchPattern": "action order [0-9]+: connmark zone 0 drop.*index 100 ref",
69 "matchCount": "1", 69 "matchCount": "1",
70 "teardown": [ 70 "teardown": [
71 "$TC actions flush action connmark" 71 "$TC actions flush action connmark"
@@ -89,7 +89,7 @@
89 "cmdUnderTest": "$TC actions add action connmark pipe index 455", 89 "cmdUnderTest": "$TC actions add action connmark pipe index 455",
90 "expExitCode": "0", 90 "expExitCode": "0",
91 "verifyCmd": "$TC actions get action connmark index 455", 91 "verifyCmd": "$TC actions get action connmark index 455",
92 "matchPattern": "action order [0-9]+: connmark zone 0 pipe.*index 455 ref", 92 "matchPattern": "action order [0-9]+: connmark zone 0 pipe.*index 455 ref",
93 "matchCount": "1", 93 "matchCount": "1",
94 "teardown": [ 94 "teardown": [
95 "$TC actions flush action connmark" 95 "$TC actions flush action connmark"
@@ -113,7 +113,7 @@
113 "cmdUnderTest": "$TC actions add action connmark reclassify index 7", 113 "cmdUnderTest": "$TC actions add action connmark reclassify index 7",
114 "expExitCode": "0", 114 "expExitCode": "0",
115 "verifyCmd": "$TC actions list action connmark", 115 "verifyCmd": "$TC actions list action connmark",
116 "matchPattern": "action order [0-9]+: connmark zone 0 reclassify.*index 7 ref", 116 "matchPattern": "action order [0-9]+: connmark zone 0 reclassify.*index 7 ref",
117 "matchCount": "1", 117 "matchCount": "1",
118 "teardown": [ 118 "teardown": [
119 "$TC actions flush action connmark" 119 "$TC actions flush action connmark"
@@ -137,7 +137,7 @@
137 "cmdUnderTest": "$TC actions add action connmark continue index 17", 137 "cmdUnderTest": "$TC actions add action connmark continue index 17",
138 "expExitCode": "0", 138 "expExitCode": "0",
139 "verifyCmd": "$TC actions list action connmark", 139 "verifyCmd": "$TC actions list action connmark",
140 "matchPattern": "action order [0-9]+: connmark zone 0 continue.*index 17 ref", 140 "matchPattern": "action order [0-9]+: connmark zone 0 continue.*index 17 ref",
141 "matchCount": "1", 141 "matchCount": "1",
142 "teardown": [ 142 "teardown": [
143 "$TC actions flush action connmark" 143 "$TC actions flush action connmark"
@@ -161,7 +161,7 @@
161 "cmdUnderTest": "$TC actions add action connmark jump 10 index 17", 161 "cmdUnderTest": "$TC actions add action connmark jump 10 index 17",
162 "expExitCode": "0", 162 "expExitCode": "0",
163 "verifyCmd": "$TC actions list action connmark", 163 "verifyCmd": "$TC actions list action connmark",
164 "matchPattern": "action order [0-9]+: connmark zone 0 jump 10.*index 17 ref", 164 "matchPattern": "action order [0-9]+: connmark zone 0 jump 10.*index 17 ref",
165 "matchCount": "1", 165 "matchCount": "1",
166 "teardown": [ 166 "teardown": [
167 "$TC actions flush action connmark" 167 "$TC actions flush action connmark"
@@ -185,7 +185,7 @@
185 "cmdUnderTest": "$TC actions add action connmark zone 100 pipe index 1", 185 "cmdUnderTest": "$TC actions add action connmark zone 100 pipe index 1",
186 "expExitCode": "0", 186 "expExitCode": "0",
187 "verifyCmd": "$TC actions get action connmark index 1", 187 "verifyCmd": "$TC actions get action connmark index 1",
188 "matchPattern": "action order [0-9]+: connmark zone 100 pipe.*index 1 ref", 188 "matchPattern": "action order [0-9]+: connmark zone 100 pipe.*index 1 ref",
189 "matchCount": "1", 189 "matchCount": "1",
190 "teardown": [ 190 "teardown": [
191 "$TC actions flush action connmark" 191 "$TC actions flush action connmark"
@@ -209,7 +209,7 @@
209 "cmdUnderTest": "$TC actions add action connmark zone 65536 reclassify index 21", 209 "cmdUnderTest": "$TC actions add action connmark zone 65536 reclassify index 21",
210 "expExitCode": "255", 210 "expExitCode": "255",
211 "verifyCmd": "$TC actions get action connmark index 1", 211 "verifyCmd": "$TC actions get action connmark index 1",
212 "matchPattern": "action order [0-9]+: connmark zone 65536 reclassify.*index 21 ref", 212 "matchPattern": "action order [0-9]+: connmark zone 65536 reclassify.*index 21 ref",
213 "matchCount": "0", 213 "matchCount": "0",
214 "teardown": [ 214 "teardown": [
215 "$TC actions flush action connmark" 215 "$TC actions flush action connmark"
@@ -233,7 +233,7 @@
233 "cmdUnderTest": "$TC actions add action connmark zone 655 unsupp_arg pass index 2", 233 "cmdUnderTest": "$TC actions add action connmark zone 655 unsupp_arg pass index 2",
234 "expExitCode": "255", 234 "expExitCode": "255",
235 "verifyCmd": "$TC actions get action connmark index 2", 235 "verifyCmd": "$TC actions get action connmark index 2",
236 "matchPattern": "action order [0-9]+: connmark zone 655 unsupp_arg pass.*index 2 ref", 236 "matchPattern": "action order [0-9]+: connmark zone 655 unsupp_arg pass.*index 2 ref",
237 "matchCount": "0", 237 "matchCount": "0",
238 "teardown": [ 238 "teardown": [
239 "$TC actions flush action connmark" 239 "$TC actions flush action connmark"
@@ -258,7 +258,7 @@
258 "cmdUnderTest": "$TC actions replace action connmark zone 555 reclassify index 555", 258 "cmdUnderTest": "$TC actions replace action connmark zone 555 reclassify index 555",
259 "expExitCode": "0", 259 "expExitCode": "0",
260 "verifyCmd": "$TC actions get action connmark index 555", 260 "verifyCmd": "$TC actions get action connmark index 555",
261 "matchPattern": "action order [0-9]+: connmark zone 555 reclassify.*index 555 ref", 261 "matchPattern": "action order [0-9]+: connmark zone 555 reclassify.*index 555 ref",
262 "matchCount": "1", 262 "matchCount": "1",
263 "teardown": [ 263 "teardown": [
264 "$TC actions flush action connmark" 264 "$TC actions flush action connmark"
@@ -282,7 +282,7 @@
282 "cmdUnderTest": "$TC actions add action connmark zone 555 pipe index 5 cookie aabbccddeeff112233445566778800a1", 282 "cmdUnderTest": "$TC actions add action connmark zone 555 pipe index 5 cookie aabbccddeeff112233445566778800a1",
283 "expExitCode": "0", 283 "expExitCode": "0",
284 "verifyCmd": "$TC actions get action connmark index 5", 284 "verifyCmd": "$TC actions get action connmark index 5",
285 "matchPattern": "action order [0-9]+: connmark zone 555 pipe.*index 5 ref.*cookie aabbccddeeff112233445566778800a1", 285 "matchPattern": "action order [0-9]+: connmark zone 555 pipe.*index 5 ref.*cookie aabbccddeeff112233445566778800a1",
286 "matchCount": "1", 286 "matchCount": "1",
287 "teardown": [ 287 "teardown": [
288 "$TC actions flush action connmark" 288 "$TC actions flush action connmark"
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/csum.json b/tools/testing/selftests/tc-testing/tc-tests/actions/csum.json
index 3a2f51fc7fd4..a022792d392a 100644
--- a/tools/testing/selftests/tc-testing/tc-tests/actions/csum.json
+++ b/tools/testing/selftests/tc-testing/tc-tests/actions/csum.json
@@ -336,6 +336,30 @@
336 ] 336 ]
337 }, 337 },
338 { 338 {
339 "id": "b10b",
340 "name": "Add all 7 csum actions",
341 "category": [
342 "actions",
343 "csum"
344 ],
345 "setup": [
346 [
347 "$TC actions flush action csum",
348 0,
349 1,
350 255
351 ]
352 ],
353 "cmdUnderTest": "$TC actions add action csum icmp ip4h sctp igmp udplite udp tcp index 7",
354 "expExitCode": "0",
355 "verifyCmd": "$TC actions get action csum index 7",
356 "matchPattern": "action order [0-9]*: csum \\(iph, icmp, igmp, tcp, udp, udplite, sctp\\).*index 7 ref",
357 "matchCount": "1",
358 "teardown": [
359 "$TC actions flush action csum"
360 ]
361 },
362 {
339 "id": "ce92", 363 "id": "ce92",
340 "name": "Add csum udp action with cookie", 364 "name": "Add csum udp action with cookie",
341 "category": [ 365 "category": [
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/mirred.json b/tools/testing/selftests/tc-testing/tc-tests/actions/mirred.json
index 6e4edfae1799..db49fd0f8445 100644
--- a/tools/testing/selftests/tc-testing/tc-tests/actions/mirred.json
+++ b/tools/testing/selftests/tc-testing/tc-tests/actions/mirred.json
@@ -44,7 +44,8 @@
44 "matchPattern": "action order [0-9]*: mirred \\(Egress Redirect to device lo\\).*index 2 ref", 44 "matchPattern": "action order [0-9]*: mirred \\(Egress Redirect to device lo\\).*index 2 ref",
45 "matchCount": "1", 45 "matchCount": "1",
46 "teardown": [ 46 "teardown": [
47 "$TC actions flush action mirred" 47 "$TC actions flush action mirred",
48 "$TC actions flush action gact"
48 ] 49 ]
49 }, 50 },
50 { 51 {
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/nat.json b/tools/testing/selftests/tc-testing/tc-tests/actions/nat.json
new file mode 100644
index 000000000000..0080dc2fd41c
--- /dev/null
+++ b/tools/testing/selftests/tc-testing/tc-tests/actions/nat.json
@@ -0,0 +1,593 @@
1[
2 {
3 "id": "7565",
4 "name": "Add nat action on ingress with default control action",
5 "category": [
6 "actions",
7 "nat"
8 ],
9 "setup": [
10 [
11 "$TC actions flush action nat",
12 0,
13 1,
14 255
15 ]
16 ],
17 "cmdUnderTest": "$TC actions add action nat ingress 192.168.1.1 200.200.200.1",
18 "expExitCode": "0",
19 "verifyCmd": "$TC actions ls action nat",
20 "matchPattern": "action order [0-9]+: nat ingress 192.168.1.1/32 200.200.200.1 pass",
21 "matchCount": "1",
22 "teardown": [
23 "$TC actions flush action nat"
24 ]
25 },
26 {
27 "id": "fd79",
28 "name": "Add nat action on ingress with pipe control action",
29 "category": [
30 "actions",
31 "nat"
32 ],
33 "setup": [
34 [
35 "$TC actions flush action nat",
36 0,
37 1,
38 255
39 ]
40 ],
41 "cmdUnderTest": "$TC actions add action nat ingress 1.1.1.1 2.2.2.1 pipe index 77",
42 "expExitCode": "0",
43 "verifyCmd": "$TC actions get action nat index 77",
44 "matchPattern": "action order [0-9]+: nat ingress 1.1.1.1/32 2.2.2.1 pipe.*index 77 ref",
45 "matchCount": "1",
46 "teardown": [
47 "$TC actions flush action nat"
48 ]
49 },
50 {
51 "id": "eab9",
52 "name": "Add nat action on ingress with continue control action",
53 "category": [
54 "actions",
55 "nat"
56 ],
57 "setup": [
58 [
59 "$TC actions flush action nat",
60 0,
61 1,
62 255
63 ]
64 ],
65 "cmdUnderTest": "$TC actions add action nat ingress 192.168.10.10 192.168.20.20 continue index 1000",
66 "expExitCode": "0",
67 "verifyCmd": "$TC actions get action nat index 1000",
68 "matchPattern": "action order [0-9]+: nat ingress 192.168.10.10/32 192.168.20.20 continue.*index 1000 ref",
69 "matchCount": "1",
70 "teardown": [
71 "$TC actions flush action nat"
72 ]
73 },
74 {
75 "id": "c53a",
76 "name": "Add nat action on ingress with reclassify control action",
77 "category": [
78 "actions",
79 "nat"
80 ],
81 "setup": [
82 [
83 "$TC actions flush action nat",
84 0,
85 1,
86 255
87 ]
88 ],
89 "cmdUnderTest": "$TC actions add action nat ingress 192.168.10.10 192.168.20.20 reclassify index 1000",
90 "expExitCode": "0",
91 "verifyCmd": "$TC actions get action nat index 1000",
92 "matchPattern": "action order [0-9]+: nat ingress 192.168.10.10/32 192.168.20.20 reclassify.*index 1000 ref",
93 "matchCount": "1",
94 "teardown": [
95 "$TC actions flush action nat"
96 ]
97 },
98 {
99 "id": "76c9",
100 "name": "Add nat action on ingress with jump control action",
101 "category": [
102 "actions",
103 "nat"
104 ],
105 "setup": [
106 [
107 "$TC actions flush action nat",
108 0,
109 1,
110 255
111 ]
112 ],
113 "cmdUnderTest": "$TC actions add action nat ingress 12.18.10.10 12.18.20.20 jump 10 index 22",
114 "expExitCode": "0",
115 "verifyCmd": "$TC actions get action nat index 22",
116 "matchPattern": "action order [0-9]+: nat ingress 12.18.10.10/32 12.18.20.20 jump 10.*index 22 ref",
117 "matchCount": "1",
118 "teardown": [
119 "$TC actions flush action nat"
120 ]
121 },
122 {
123 "id": "24c6",
124 "name": "Add nat action on ingress with drop control action",
125 "category": [
126 "actions",
127 "nat"
128 ],
129 "setup": [
130 [
131 "$TC actions flush action nat",
132 0,
133 1,
134 255
135 ]
136 ],
137 "cmdUnderTest": "$TC actions add action nat ingress 1.18.1.1 1.18.2.2 drop index 722",
138 "expExitCode": "0",
139 "verifyCmd": "$TC actions get action nat index 722",
140 "matchPattern": "action order [0-9]+: nat ingress 1.18.1.1/32 1.18.2.2 drop.*index 722 ref",
141 "matchCount": "1",
142 "teardown": [
143 "$TC actions flush action nat"
144 ]
145 },
146 {
147 "id": "2120",
148 "name": "Add nat action on ingress with maximum index value",
149 "category": [
150 "actions",
151 "nat"
152 ],
153 "setup": [
154 [
155 "$TC actions flush action nat",
156 0,
157 1,
158 255
159 ]
160 ],
161 "cmdUnderTest": "$TC actions add action nat ingress 1.18.1.1 1.18.2.2 index 4294967295",
162 "expExitCode": "0",
163 "verifyCmd": "$TC actions get action nat index 4294967295",
164 "matchPattern": "action order [0-9]+: nat ingress 1.18.1.1/32 1.18.2.2 pass.*index 4294967295 ref",
165 "matchCount": "1",
166 "teardown": [
167 "$TC actions flush action nat"
168 ]
169 },
170 {
171 "id": "3e9d",
172 "name": "Add nat action on ingress with invalid index value",
173 "category": [
174 "actions",
175 "nat"
176 ],
177 "setup": [
178 [
179 "$TC actions flush action nat",
180 0,
181 1,
182 255
183 ]
184 ],
185 "cmdUnderTest": "$TC actions add action nat ingress 1.18.1.1 1.18.2.2 index 4294967295555",
186 "expExitCode": "255",
187 "verifyCmd": "$TC actions get action nat index 4294967295555",
188 "matchPattern": "action order [0-9]+: nat ingress 1.18.1.1/32 1.18.2.2 pass.*index 4294967295555 ref",
189 "matchCount": "0",
190 "teardown": [
191 [
192 "$TC actions flush action nat",
193 0,
194 1,
195 255
196 ]
197 ]
198 },
199 {
200 "id": "f6c9",
201 "name": "Add nat action on ingress with invalid IP address",
202 "category": [
203 "actions",
204 "nat"
205 ],
206 "setup": [
207 [
208 "$TC actions flush action nat",
209 0,
210 1,
211 255
212 ]
213 ],
214 "cmdUnderTest": "$TC actions add action nat ingress 1.1.1.1 1.1888.2.2 index 7",
215 "expExitCode": "255",
216 "verifyCmd": "$TC actions get action nat index 7",
217 "matchPattern": "action order [0-9]+: nat ingress 1.1.1.1/32 1.1888.2.2 pass.*index 7 ref",
218 "matchCount": "0",
219 "teardown": [
220 [
221 "$TC actions flush action nat",
222 0,
223 1,
224 255
225 ]
226 ]
227 },
228 {
229 "id": "be25",
230 "name": "Add nat action on ingress with invalid argument",
231 "category": [
232 "actions",
233 "nat"
234 ],
235 "setup": [
236 [
237 "$TC actions flush action nat",
238 0,
239 1,
240 255
241 ]
242 ],
243 "cmdUnderTest": "$TC actions add action nat ingress 1.1.1.1 1.18.2.2 another_arg index 12",
244 "expExitCode": "255",
245 "verifyCmd": "$TC actions get action nat index 12",
246 "matchPattern": "action order [0-9]+: nat ingress 1.1.1.1/32 1.18.2.2 pass.*another_arg.*index 12 ref",
247 "matchCount": "0",
248 "teardown": [
249 [
250 "$TC actions flush action nat",
251 0,
252 1,
253 255
254 ]
255 ]
256 },
257 {
258 "id": "a7bd",
259 "name": "Add nat action on ingress with DEFAULT IP address",
260 "category": [
261 "actions",
262 "nat"
263 ],
264 "setup": [
265 [
266 "$TC actions flush action nat",
267 0,
268 1,
269 255
270 ]
271 ],
272 "cmdUnderTest": "$TC actions add action nat ingress default 10.10.10.1 index 12",
273 "expExitCode": "0",
274 "verifyCmd": "$TC actions get action nat index 12",
275 "matchPattern": "action order [0-9]+: nat ingress 0.0.0.0/32 10.10.10.1 pass.*index 12 ref",
276 "matchCount": "1",
277 "teardown": [
278 "$TC actions flush action nat"
279 ]
280 },
281 {
282 "id": "ee1e",
283 "name": "Add nat action on ingress with ANY IP address",
284 "category": [
285 "actions",
286 "nat"
287 ],
288 "setup": [
289 [
290 "$TC actions flush action nat",
291 0,
292 1,
293 255
294 ]
295 ],
296 "cmdUnderTest": "$TC actions add action nat ingress any 10.10.10.1 index 12",
297 "expExitCode": "0",
298 "verifyCmd": "$TC actions get action nat index 12",
299 "matchPattern": "action order [0-9]+: nat ingress 0.0.0.0/32 10.10.10.1 pass.*index 12 ref",
300 "matchCount": "1",
301 "teardown": [
302 "$TC actions flush action nat"
303 ]
304 },
305 {
306 "id": "1de8",
307 "name": "Add nat action on ingress with ALL IP address",
308 "category": [
309 "actions",
310 "nat"
311 ],
312 "setup": [
313 [
314 "$TC actions flush action nat",
315 0,
316 1,
317 255
318 ]
319 ],
320 "cmdUnderTest": "$TC actions add action nat ingress all 10.10.10.1 index 12",
321 "expExitCode": "0",
322 "verifyCmd": "$TC actions get action nat index 12",
323 "matchPattern": "action order [0-9]+: nat ingress 0.0.0.0/32 10.10.10.1 pass.*index 12 ref",
324 "matchCount": "1",
325 "teardown": [
326 "$TC actions flush action nat"
327 ]
328 },
329 {
330 "id": "8dba",
331 "name": "Add nat action on egress with default control action",
332 "category": [
333 "actions",
334 "nat"
335 ],
336 "setup": [
337 [
338 "$TC actions flush action nat",
339 0,
340 1,
341 255
342 ]
343 ],
344 "cmdUnderTest": "$TC actions add action nat egress 10.10.10.1 20.20.20.1",
345 "expExitCode": "0",
346 "verifyCmd": "$TC actions ls action nat",
347 "matchPattern": "action order [0-9]+: nat egress 10.10.10.1/32 20.20.20.1 pass",
348 "matchCount": "1",
349 "teardown": [
350 "$TC actions flush action nat"
351 ]
352 },
353 {
354 "id": "19a7",
355 "name": "Add nat action on egress with pipe control action",
356 "category": [
357 "actions",
358 "nat"
359 ],
360 "setup": [
361 [
362 "$TC actions flush action nat",
363 0,
364 1,
365 255
366 ]
367 ],
368 "cmdUnderTest": "$TC actions add action nat egress 10.10.10.1 20.20.20.1 pipe",
369 "expExitCode": "0",
370 "verifyCmd": "$TC actions ls action nat",
371 "matchPattern": "action order [0-9]+: nat egress 10.10.10.1/32 20.20.20.1 pipe",
372 "matchCount": "1",
373 "teardown": [
374 "$TC actions flush action nat"
375 ]
376 },
377 {
378 "id": "f1d9",
379 "name": "Add nat action on egress with continue control action",
380 "category": [
381 "actions",
382 "nat"
383 ],
384 "setup": [
385 [
386 "$TC actions flush action nat",
387 0,
388 1,
389 255
390 ]
391 ],
392 "cmdUnderTest": "$TC actions add action nat egress 10.10.10.1 20.20.20.1 continue",
393 "expExitCode": "0",
394 "verifyCmd": "$TC actions ls action nat",
395 "matchPattern": "action order [0-9]+: nat egress 10.10.10.1/32 20.20.20.1 continue",
396 "matchCount": "1",
397 "teardown": [
398 "$TC actions flush action nat"
399 ]
400 },
401 {
402 "id": "6d4a",
403 "name": "Add nat action on egress with reclassify control action",
404 "category": [
405 "actions",
406 "nat"
407 ],
408 "setup": [
409 [
410 "$TC actions flush action nat",
411 0,
412 1,
413 255
414 ]
415 ],
416 "cmdUnderTest": "$TC actions add action nat egress 10.10.10.1 20.20.20.1 reclassify",
417 "expExitCode": "0",
418 "verifyCmd": "$TC actions ls action nat",
419 "matchPattern": "action order [0-9]+: nat egress 10.10.10.1/32 20.20.20.1 reclassify",
420 "matchCount": "1",
421 "teardown": [
422 "$TC actions flush action nat"
423 ]
424 },
425 {
426 "id": "b313",
427 "name": "Add nat action on egress with jump control action",
428 "category": [
429 "actions",
430 "nat"
431 ],
432 "setup": [
433 [
434 "$TC actions flush action nat",
435 0,
436 1,
437 255
438 ]
439 ],
440 "cmdUnderTest": "$TC actions add action nat egress 10.10.10.1 20.20.20.1 jump 777",
441 "expExitCode": "0",
442 "verifyCmd": "$TC actions ls action nat",
443 "matchPattern": "action order [0-9]+: nat egress 10.10.10.1/32 20.20.20.1 jump 777",
444 "matchCount": "1",
445 "teardown": [
446 "$TC actions flush action nat"
447 ]
448 },
449 {
450 "id": "d9fc",
451 "name": "Add nat action on egress with drop control action",
452 "category": [
453 "actions",
454 "nat"
455 ],
456 "setup": [
457 [
458 "$TC actions flush action nat",
459 0,
460 1,
461 255
462 ]
463 ],
464 "cmdUnderTest": "$TC actions add action nat egress 10.10.10.1 20.20.20.1 drop",
465 "expExitCode": "0",
466 "verifyCmd": "$TC actions ls action nat",
467 "matchPattern": "action order [0-9]+: nat egress 10.10.10.1/32 20.20.20.1 drop",
468 "matchCount": "1",
469 "teardown": [
470 "$TC actions flush action nat"
471 ]
472 },
473 {
474 "id": "a895",
475 "name": "Add nat action on egress with DEFAULT IP address",
476 "category": [
477 "actions",
478 "nat"
479 ],
480 "setup": [
481 [
482 "$TC actions flush action nat",
483 0,
484 1,
485 255
486 ]
487 ],
488 "cmdUnderTest": "$TC actions add action nat egress default 20.20.20.1 pipe index 10",
489 "expExitCode": "0",
490 "verifyCmd": "$TC actions get action nat index 10",
491 "matchPattern": "action order [0-9]+: nat egress 0.0.0.0/32 20.20.20.1 pipe.*index 10 ref",
492 "matchCount": "1",
493 "teardown": [
494 "$TC actions flush action nat"
495 ]
496 },
497 {
498 "id": "2572",
499 "name": "Add nat action on egress with ANY IP address",
500 "category": [
501 "actions",
502 "nat"
503 ],
504 "setup": [
505 [
506 "$TC actions flush action nat",
507 0,
508 1,
509 255
510 ]
511 ],
512 "cmdUnderTest": "$TC actions add action nat egress any 20.20.20.1 pipe index 10",
513 "expExitCode": "0",
514 "verifyCmd": "$TC actions get action nat index 10",
515 "matchPattern": "action order [0-9]+: nat egress 0.0.0.0/32 20.20.20.1 pipe.*index 10 ref",
516 "matchCount": "1",
517 "teardown": [
518 "$TC actions flush action nat"
519 ]
520 },
521 {
522 "id": "37f3",
523 "name": "Add nat action on egress with ALL IP address",
524 "category": [
525 "actions",
526 "nat"
527 ],
528 "setup": [
529 [
530 "$TC actions flush action nat",
531 0,
532 1,
533 255
534 ]
535 ],
536 "cmdUnderTest": "$TC actions add action nat egress all 20.20.20.1 pipe index 10",
537 "expExitCode": "0",
538 "verifyCmd": "$TC actions get action nat index 10",
539 "matchPattern": "action order [0-9]+: nat egress 0.0.0.0/32 20.20.20.1 pipe.*index 10 ref",
540 "matchCount": "1",
541 "teardown": [
542 "$TC actions flush action nat"
543 ]
544 },
545 {
546 "id": "6054",
547 "name": "Add nat action on egress with cookie",
548 "category": [
549 "actions",
550 "nat"
551 ],
552 "setup": [
553 [
554 "$TC actions flush action nat",
555 0,
556 1,
557 255
558 ]
559 ],
560 "cmdUnderTest": "$TC actions add action nat egress all 20.20.20.1 pipe index 10 cookie aa1bc2d3eeff112233445566778800a1",
561 "expExitCode": "0",
562 "verifyCmd": "$TC actions get action nat index 10",
563 "matchPattern": "action order [0-9]+: nat egress 0.0.0.0/32 20.20.20.1 pipe.*index 10 ref.*cookie aa1bc2d3eeff112233445566778800a1",
564 "matchCount": "1",
565 "teardown": [
566 "$TC actions flush action nat"
567 ]
568 },
569 {
570 "id": "79d6",
571 "name": "Add nat action on ingress with cookie",
572 "category": [
573 "actions",
574 "nat"
575 ],
576 "setup": [
577 [
578 "$TC actions flush action nat",
579 0,
580 1,
581 255
582 ]
583 ],
584 "cmdUnderTest": "$TC actions add action nat ingress 192.168.1.1 10.10.10.1 reclassify index 1 cookie 112233445566778899aabbccddeeff11",
585 "expExitCode": "0",
586 "verifyCmd": "$TC actions get action nat index 1",
587 "matchPattern": "action order [0-9]+: nat ingress 192.168.1.1/32 10.10.10.1 reclassify.*index 1 ref.*cookie 112233445566778899aabbccddeeff11",
588 "matchCount": "1",
589 "teardown": [
590 "$TC actions flush action nat"
591 ]
592 }
593]
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json b/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json
index 37ecc2716fee..5aaf593b914a 100644
--- a/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json
+++ b/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json
@@ -17,7 +17,7 @@
17 "cmdUnderTest": "$TC actions add action skbedit mark 1", 17 "cmdUnderTest": "$TC actions add action skbedit mark 1",
18 "expExitCode": "0", 18 "expExitCode": "0",
19 "verifyCmd": "$TC actions list action skbedit", 19 "verifyCmd": "$TC actions list action skbedit",
20 "matchPattern": "action order [0-9]*: skbedit mark 1", 20 "matchPattern": "action order [0-9]*: skbedit mark 1",
21 "matchCount": "1", 21 "matchCount": "1",
22 "teardown": [ 22 "teardown": [
23 "$TC actions flush action skbedit" 23 "$TC actions flush action skbedit"
@@ -65,7 +65,7 @@
65 "cmdUnderTest": "$TC actions add action skbedit prio 99", 65 "cmdUnderTest": "$TC actions add action skbedit prio 99",
66 "expExitCode": "0", 66 "expExitCode": "0",
67 "verifyCmd": "$TC actions list action skbedit", 67 "verifyCmd": "$TC actions list action skbedit",
68 "matchPattern": "action order [0-9]*: skbedit priority :99", 68 "matchPattern": "action order [0-9]*: skbedit priority :99",
69 "matchCount": "1", 69 "matchCount": "1",
70 "teardown": [ 70 "teardown": [
71 "$TC actions flush action skbedit" 71 "$TC actions flush action skbedit"
@@ -113,7 +113,7 @@
113 "cmdUnderTest": "$TC actions add action skbedit queue_mapping 909", 113 "cmdUnderTest": "$TC actions add action skbedit queue_mapping 909",
114 "expExitCode": "0", 114 "expExitCode": "0",
115 "verifyCmd": "$TC actions list action skbedit", 115 "verifyCmd": "$TC actions list action skbedit",
116 "matchPattern": "action order [0-9]*: skbedit queue_mapping 909", 116 "matchPattern": "action order [0-9]*: skbedit queue_mapping 909",
117 "matchCount": "1", 117 "matchCount": "1",
118 "teardown": [ 118 "teardown": [
119 "$TC actions flush action skbedit" 119 "$TC actions flush action skbedit"
@@ -161,7 +161,7 @@
161 "cmdUnderTest": "$TC actions add action skbedit ptype host", 161 "cmdUnderTest": "$TC actions add action skbedit ptype host",
162 "expExitCode": "0", 162 "expExitCode": "0",
163 "verifyCmd": "$TC actions list action skbedit", 163 "verifyCmd": "$TC actions list action skbedit",
164 "matchPattern": "action order [0-9]*: skbedit ptype host", 164 "matchPattern": "action order [0-9]*: skbedit ptype host",
165 "matchCount": "1", 165 "matchCount": "1",
166 "teardown": [ 166 "teardown": [
167 "$TC actions flush action skbedit" 167 "$TC actions flush action skbedit"
@@ -185,7 +185,7 @@
185 "cmdUnderTest": "$TC actions add action skbedit ptype otherhost", 185 "cmdUnderTest": "$TC actions add action skbedit ptype otherhost",
186 "expExitCode": "0", 186 "expExitCode": "0",
187 "verifyCmd": "$TC actions list action skbedit", 187 "verifyCmd": "$TC actions list action skbedit",
188 "matchPattern": "action order [0-9]*: skbedit ptype otherhost", 188 "matchPattern": "action order [0-9]*: skbedit ptype otherhost",
189 "matchCount": "1", 189 "matchCount": "1",
190 "teardown": [ 190 "teardown": [
191 "$TC actions flush action skbedit" 191 "$TC actions flush action skbedit"
@@ -233,7 +233,7 @@
233 "cmdUnderTest": "$TC actions add action skbedit ptype host pipe index 11", 233 "cmdUnderTest": "$TC actions add action skbedit ptype host pipe index 11",
234 "expExitCode": "0", 234 "expExitCode": "0",
235 "verifyCmd": "$TC actions get action skbedit index 11", 235 "verifyCmd": "$TC actions get action skbedit index 11",
236 "matchPattern": "action order [0-9]*: skbedit ptype host pipe.*index 11 ref", 236 "matchPattern": "action order [0-9]*: skbedit ptype host pipe.*index 11 ref",
237 "matchCount": "1", 237 "matchCount": "1",
238 "teardown": [ 238 "teardown": [
239 "$TC actions flush action skbedit" 239 "$TC actions flush action skbedit"
@@ -257,7 +257,7 @@
257 "cmdUnderTest": "$TC actions add action skbedit mark 56789 reclassify index 90", 257 "cmdUnderTest": "$TC actions add action skbedit mark 56789 reclassify index 90",
258 "expExitCode": "0", 258 "expExitCode": "0",
259 "verifyCmd": "$TC actions get action skbedit index 90", 259 "verifyCmd": "$TC actions get action skbedit index 90",
260 "matchPattern": "action order [0-9]*: skbedit mark 56789 reclassify.*index 90 ref", 260 "matchPattern": "action order [0-9]*: skbedit mark 56789 reclassify.*index 90 ref",
261 "matchCount": "1", 261 "matchCount": "1",
262 "teardown": [ 262 "teardown": [
263 "$TC actions flush action skbedit" 263 "$TC actions flush action skbedit"
@@ -281,7 +281,7 @@
281 "cmdUnderTest": "$TC actions add action skbedit queue_mapping 3 pass index 271", 281 "cmdUnderTest": "$TC actions add action skbedit queue_mapping 3 pass index 271",
282 "expExitCode": "0", 282 "expExitCode": "0",
283 "verifyCmd": "$TC actions get action skbedit index 271", 283 "verifyCmd": "$TC actions get action skbedit index 271",
284 "matchPattern": "action order [0-9]*: skbedit queue_mapping 3 pass.*index 271 ref", 284 "matchPattern": "action order [0-9]*: skbedit queue_mapping 3 pass.*index 271 ref",
285 "matchCount": "1", 285 "matchCount": "1",
286 "teardown": [ 286 "teardown": [
287 "$TC actions flush action skbedit" 287 "$TC actions flush action skbedit"
@@ -305,7 +305,7 @@
305 "cmdUnderTest": "$TC actions add action skbedit queue_mapping 3 drop index 271", 305 "cmdUnderTest": "$TC actions add action skbedit queue_mapping 3 drop index 271",
306 "expExitCode": "0", 306 "expExitCode": "0",
307 "verifyCmd": "$TC actions get action skbedit index 271", 307 "verifyCmd": "$TC actions get action skbedit index 271",
308 "matchPattern": "action order [0-9]*: skbedit queue_mapping 3 drop.*index 271 ref", 308 "matchPattern": "action order [0-9]*: skbedit queue_mapping 3 drop.*index 271 ref",
309 "matchCount": "1", 309 "matchCount": "1",
310 "teardown": [ 310 "teardown": [
311 "$TC actions flush action skbedit" 311 "$TC actions flush action skbedit"
@@ -329,7 +329,7 @@
329 "cmdUnderTest": "$TC actions add action skbedit priority 8 jump 9 index 2", 329 "cmdUnderTest": "$TC actions add action skbedit priority 8 jump 9 index 2",
330 "expExitCode": "0", 330 "expExitCode": "0",
331 "verifyCmd": "$TC actions get action skbedit index 2", 331 "verifyCmd": "$TC actions get action skbedit index 2",
332 "matchPattern": "action order [0-9]*: skbedit priority :8 jump 9.*index 2 ref", 332 "matchPattern": "action order [0-9]*: skbedit priority :8 jump 9.*index 2 ref",
333 "matchCount": "1", 333 "matchCount": "1",
334 "teardown": [ 334 "teardown": [
335 "$TC actions flush action skbedit" 335 "$TC actions flush action skbedit"
@@ -353,7 +353,7 @@
353 "cmdUnderTest": "$TC actions add action skbedit priority 16 continue index 32", 353 "cmdUnderTest": "$TC actions add action skbedit priority 16 continue index 32",
354 "expExitCode": "0", 354 "expExitCode": "0",
355 "verifyCmd": "$TC actions get action skbedit index 32", 355 "verifyCmd": "$TC actions get action skbedit index 32",
356 "matchPattern": "action order [0-9]*: skbedit priority :16 continue.*index 32 ref", 356 "matchPattern": "action order [0-9]*: skbedit priority :16 continue.*index 32 ref",
357 "matchCount": "1", 357 "matchCount": "1",
358 "teardown": [ 358 "teardown": [
359 "$TC actions flush action skbedit" 359 "$TC actions flush action skbedit"
@@ -377,7 +377,7 @@
377 "cmdUnderTest": "$TC actions add action skbedit priority 16 continue index 32 cookie deadbeef", 377 "cmdUnderTest": "$TC actions add action skbedit priority 16 continue index 32 cookie deadbeef",
378 "expExitCode": "0", 378 "expExitCode": "0",
379 "verifyCmd": "$TC actions get action skbedit index 32", 379 "verifyCmd": "$TC actions get action skbedit index 32",
380 "matchPattern": "action order [0-9]*: skbedit priority :16 continue.*index 32 ref.*cookie deadbeef", 380 "matchPattern": "action order [0-9]*: skbedit priority :16 continue.*index 32 ref.*cookie deadbeef",
381 "matchCount": "1", 381 "matchCount": "1",
382 "teardown": [ 382 "teardown": [
383 "$TC actions flush action skbedit" 383 "$TC actions flush action skbedit"
@@ -405,7 +405,7 @@
405 "cmdUnderTest": "$TC actions list action skbedit", 405 "cmdUnderTest": "$TC actions list action skbedit",
406 "expExitCode": "0", 406 "expExitCode": "0",
407 "verifyCmd": "$TC actions list action skbedit", 407 "verifyCmd": "$TC actions list action skbedit",
408 "matchPattern": "action order [0-9]*: skbedit", 408 "matchPattern": "action order [0-9]*: skbedit",
409 "matchCount": "4", 409 "matchCount": "4",
410 "teardown": [ 410 "teardown": [
411 "$TC actions flush action skbedit" 411 "$TC actions flush action skbedit"
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/tunnel_key.json b/tools/testing/selftests/tc-testing/tc-tests/actions/tunnel_key.json
new file mode 100644
index 000000000000..10b2d894e436
--- /dev/null
+++ b/tools/testing/selftests/tc-testing/tc-tests/actions/tunnel_key.json
@@ -0,0 +1,917 @@
1[
2 {
3 "id": "2b11",
4 "name": "Add tunnel_key set action with mandatory parameters",
5 "category": [
6 "actions",
7 "tunnel_key"
8 ],
9 "setup": [
10 [
11 "$TC actions flush action tunnel_key",
12 0,
13 1,
14 255
15 ]
16 ],
17 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 10.10.10.1 dst_ip 20.20.20.2 id 1",
18 "expExitCode": "0",
19 "verifyCmd": "$TC actions list action tunnel_key",
20 "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 10.10.10.1.*dst_ip 20.20.20.2.*key_id 1",
21 "matchCount": "1",
22 "teardown": [
23 "$TC actions flush action tunnel_key"
24 ]
25 },
26 {
27 "id": "dc6b",
28 "name": "Add tunnel_key set action with missing mandatory src_ip parameter",
29 "category": [
30 "actions",
31 "tunnel_key"
32 ],
33 "setup": [
34 [
35 "$TC actions flush action tunnel_key",
36 0,
37 1,
38 255
39 ]
40 ],
41 "cmdUnderTest": "$TC actions add action tunnel_key set dst_ip 20.20.20.2 id 100",
42 "expExitCode": "255",
43 "verifyCmd": "$TC actions list action tunnel_key",
44 "matchPattern": "action order [0-9]+: tunnel_key set.*dst_ip 20.20.20.2.*key_id 100",
45 "matchCount": "0",
46 "teardown": [
47 [
48 "$TC actions flush action tunnel_key",
49 0,
50 1,
51 255
52 ]
53 ]
54 },
55 {
56 "id": "7f25",
57 "name": "Add tunnel_key set action with missing mandatory dst_ip parameter",
58 "category": [
59 "actions",
60 "tunnel_key"
61 ],
62 "setup": [
63 [
64 "$TC actions flush action tunnel_key",
65 0,
66 1,
67 255
68 ]
69 ],
70 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 10.10.10.1 id 100",
71 "expExitCode": "255",
72 "verifyCmd": "$TC actions list action tunnel_key",
73 "matchPattern": "action order [0-9]+: tunnel_key set.*src_ip 10.10.10.1.*key_id 100",
74 "matchCount": "0",
75 "teardown": [
76 [
77 "$TC actions flush action tunnel_key",
78 0,
79 1,
80 255
81 ]
82 ]
83 },
84 {
85 "id": "ba4e",
86 "name": "Add tunnel_key set action with missing mandatory id parameter",
87 "category": [
88 "actions",
89 "tunnel_key"
90 ],
91 "setup": [
92 [
93 "$TC actions flush action tunnel_key",
94 0,
95 1,
96 255
97 ]
98 ],
99 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 10.10.10.1 dst_ip 20.20.20.2",
100 "expExitCode": "255",
101 "verifyCmd": "$TC actions list action tunnel_key",
102 "matchPattern": "action order [0-9]+: tunnel_key set.*src_ip 10.10.10.1.*dst_ip 20.20.20.2",
103 "matchCount": "0",
104 "teardown": [
105 [
106 "$TC actions flush action tunnel_key",
107 0,
108 1,
109 255
110 ]
111 ]
112 },
113 {
114 "id": "a5e0",
115 "name": "Add tunnel_key set action with invalid src_ip parameter",
116 "category": [
117 "actions",
118 "tunnel_key"
119 ],
120 "setup": [
121 [
122 "$TC actions flush action tunnel_key",
123 0,
124 1,
125 255
126 ]
127 ],
128 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 300.168.100.1 dst_ip 192.168.200.1 id 7 index 1",
129 "expExitCode": "1",
130 "verifyCmd": "$TC actions get action tunnel_key index 1",
131 "matchPattern": "action order [0-9]+: tunnel_key set.*src_ip 300.168.100.1.*dst_ip 192.168.200.1.*key_id 7.*index 1 ref",
132 "matchCount": "0",
133 "teardown": [
134 [
135 "$TC actions flush action tunnel_key",
136 0,
137 1,
138 255
139 ]
140 ]
141 },
142 {
143 "id": "eaa8",
144 "name": "Add tunnel_key set action with invalid dst_ip parameter",
145 "category": [
146 "actions",
147 "tunnel_key"
148 ],
149 "setup": [
150 [
151 "$TC actions flush action tunnel_key",
152 0,
153 1,
154 255
155 ]
156 ],
157 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 192.168.100.1 dst_ip 192.168.800.1 id 10 index 11",
158 "expExitCode": "1",
159 "verifyCmd": "$TC actions get action tunnel_key index 11",
160 "matchPattern": "action order [0-9]+: tunnel_key set.*src_ip 192.168.100.1.*dst_ip 192.168.800.1.*key_id 10.*index 11 ref",
161 "matchCount": "0",
162 "teardown": [
163 [
164 "$TC actions flush action tunnel_key",
165 0,
166 1,
167 255
168 ]
169 ]
170 },
171 {
172 "id": "3b09",
173 "name": "Add tunnel_key set action with invalid id parameter",
174 "category": [
175 "actions",
176 "tunnel_key"
177 ],
178 "setup": [
179 [
180 "$TC actions flush action tunnel_key",
181 0,
182 1,
183 255
184 ]
185 ],
186 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 112233445566778899 index 1",
187 "expExitCode": "255",
188 "verifyCmd": "$TC actions get action tunnel_key index 1",
189 "matchPattern": "action order [0-9]+: tunnel_key set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 112233445566778899.*index 1 ref",
190 "matchCount": "0",
191 "teardown": [
192 [
193 "$TC actions flush action tunnel_key",
194 0,
195 1,
196 255
197 ]
198 ]
199 },
200 {
201 "id": "9625",
202 "name": "Add tunnel_key set action with invalid dst_port parameter",
203 "category": [
204 "actions",
205 "tunnel_key"
206 ],
207 "setup": [
208 [
209 "$TC actions flush action tunnel_key",
210 0,
211 1,
212 255
213 ]
214 ],
215 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 11 dst_port 998877 index 1",
216 "expExitCode": "255",
217 "verifyCmd": "$TC actions get action tunnel_key index 1",
218 "matchPattern": "action order [0-9]+: tunnel_key set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 11.*dst_port 998877.*index 1 ref",
219 "matchCount": "0",
220 "teardown": [
221 [
222 "$TC actions flush action tunnel_key",
223 0,
224 1,
225 255
226 ]
227 ]
228 },
229 {
230 "id": "05af",
231 "name": "Add tunnel_key set action with optional dst_port parameter",
232 "category": [
233 "actions",
234 "tunnel_key"
235 ],
236 "setup": [
237 [
238 "$TC actions flush action tunnel_key",
239 0,
240 1,
241 255
242 ]
243 ],
244 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 192.168.100.1 dst_ip 192.168.200.1 id 789 dst_port 4000 index 10",
245 "expExitCode": "0",
246 "verifyCmd": "$TC actions get action tunnel_key index 10",
247 "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 192.168.100.1.*dst_ip 192.168.200.1.*key_id 789.*dst_port 4000.*index 10 ref",
248 "matchCount": "1",
249 "teardown": [
250 "$TC actions flush action tunnel_key"
251 ]
252 },
253 {
254 "id": "da80",
255 "name": "Add tunnel_key set action with index at 32-bit maximum",
256 "category": [
257 "actions",
258 "tunnel_key"
259 ],
260 "setup": [
261 [
262 "$TC actions flush action tunnel_key",
263 0,
264 1,
265 255
266 ]
267 ],
268 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 11 index 4294967295",
269 "expExitCode": "0",
270 "verifyCmd": "$TC actions get action tunnel_key index 4294967295",
271 "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*id 11.*index 4294967295 ref",
272 "matchCount": "1",
273 "teardown": [
274 "$TC actions flush action tunnel_key"
275 ]
276 },
277 {
278 "id": "d407",
279 "name": "Add tunnel_key set action with index exceeding 32-bit maximum",
280 "category": [
281 "actions",
282 "tunnel_key"
283 ],
284 "setup": [
285 [
286 "$TC actions flush action tunnel_key",
287 0,
288 1,
289 255
290 ]
291 ],
292 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 11 index 4294967295678",
293 "expExitCode": "255",
294 "verifyCmd": "$TC actions get action tunnel_key index 4294967295678",
295 "matchPattern": "action order [0-9]+: tunnel_key set.*index 4294967295678 ref",
296 "matchCount": "0",
297 "teardown": [
298 [
299 "$TC actions flush action tunnel_key",
300 0,
301 1,
302 255
303 ]
304 ]
305 },
306 {
307 "id": "5cba",
308 "name": "Add tunnel_key set action with id value at 32-bit maximum",
309 "category": [
310 "actions",
311 "tunnel_key"
312 ],
313 "setup": [
314 [
315 "$TC actions flush action tunnel_key",
316 0,
317 1,
318 255
319 ]
320 ],
321 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 4294967295 index 1",
322 "expExitCode": "0",
323 "verifyCmd": "$TC actions get action tunnel_key index 1",
324 "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 4294967295.*index 1",
325 "matchCount": "1",
326 "teardown": [
327 "$TC actions flush action tunnel_key"
328 ]
329 },
330 {
331 "id": "e84a",
332 "name": "Add tunnel_key set action with id value exceeding 32-bit maximum",
333 "category": [
334 "actions",
335 "tunnel_key"
336 ],
337 "setup": [
338 [
339 "$TC actions flush action tunnel_key",
340 0,
341 1,
342 255
343 ]
344 ],
345 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 42949672955 index 1",
346 "expExitCode": "255",
347 "verifyCmd": "$TC actions get action tunnel_key index 4294967295",
348 "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 42949672955.*index 1",
349 "matchCount": "0",
350 "teardown": [
351 [
352 "$TC actions flush action tunnel_key",
353 0,
354 1,
355 255
356 ]
357 ]
358 },
359 {
360 "id": "9c19",
361 "name": "Add tunnel_key set action with dst_port value at 16-bit maximum",
362 "category": [
363 "actions",
364 "tunnel_key"
365 ],
366 "setup": [
367 [
368 "$TC actions flush action tunnel_key",
369 0,
370 1,
371 255
372 ]
373 ],
374 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 429 dst_port 65535 index 1",
375 "expExitCode": "0",
376 "verifyCmd": "$TC actions get action tunnel_key index 1",
377 "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 429.*dst_port 65535.*index 1",
378 "matchCount": "1",
379 "teardown": [
380 "$TC actions flush action tunnel_key"
381 ]
382 },
383 {
384 "id": "3bd9",
385 "name": "Add tunnel_key set action with dst_port value exceeding 16-bit maximum",
386 "category": [
387 "actions",
388 "tunnel_key"
389 ],
390 "setup": [
391 [
392 "$TC actions flush action tunnel_key",
393 0,
394 1,
395 255
396 ]
397 ],
398 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 429 dst_port 65535789 index 1",
399 "expExitCode": "255",
400 "verifyCmd": "$TC actions get action tunnel_key index 1",
401 "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 429.*dst_port 65535789.*index 1",
402 "matchCount": "0",
403 "teardown": [
404 [
405 "$TC actions flush action tunnel_key",
406 0,
407 1,
408 255
409 ]
410 ]
411 },
412 {
413 "id": "68e2",
414 "name": "Add tunnel_key unset action",
415 "category": [
416 "actions",
417 "tunnel_key"
418 ],
419 "setup": [
420 [
421 "$TC actions flush action tunnel_key",
422 0,
423 1,
424 255
425 ]
426 ],
427 "cmdUnderTest": "$TC actions add action tunnel_key unset index 1",
428 "expExitCode": "0",
429 "verifyCmd": "$TC actions get action tunnel_key index 1",
430 "matchPattern": "action order [0-9]+: tunnel_key.*unset.*index 1 ref",
431 "matchCount": "1",
432 "teardown": [
433 "$TC actions flush action tunnel_key"
434 ]
435 },
436 {
437 "id": "6192",
438 "name": "Add tunnel_key unset continue action",
439 "category": [
440 "actions",
441 "tunnel_key"
442 ],
443 "setup": [
444 [
445 "$TC actions flush action tunnel_key",
446 0,
447 1,
448 255
449 ]
450 ],
451 "cmdUnderTest": "$TC actions add action tunnel_key unset continue index 1",
452 "expExitCode": "0",
453 "verifyCmd": "$TC actions get action tunnel_key index 1",
454 "matchPattern": "action order [0-9]+: tunnel_key.*unset continue.*index 1 ref",
455 "matchCount": "1",
456 "teardown": [
457 "$TC actions flush action tunnel_key"
458 ]
459 },
460 {
461 "id": "061d",
462 "name": "Add tunnel_key set continue action with cookie",
463 "category": [
464 "actions",
465 "tunnel_key"
466 ],
467 "setup": [
468 [
469 "$TC actions flush action tunnel_key",
470 0,
471 1,
472 255
473 ]
474 ],
475 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 192.168.10.1 dst_ip 192.168.20.2 id 123 continue index 1 cookie aa11bb22cc33dd44ee55ff66aa11b1b2",
476 "expExitCode": "0",
477 "verifyCmd": "$TC actions get action tunnel_key index 1",
478 "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 192.168.10.1.*dst_ip 192.168.20.2.*key_id 123.*csum continue.*index 1.*cookie aa11bb22cc33dd44ee55ff66aa11b1b2",
479 "matchCount": "1",
480 "teardown": [
481 "$TC actions flush action tunnel_key"
482 ]
483 },
484 {
485 "id": "8acb",
486 "name": "Add tunnel_key set continue action with invalid cookie",
487 "category": [
488 "actions",
489 "tunnel_key"
490 ],
491 "setup": [
492 [
493 "$TC actions flush action tunnel_key",
494 0,
495 1,
496 255
497 ]
498 ],
499 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 192.168.10.1 dst_ip 192.168.20.2 id 123 continue index 1 cookie aa11bb22cc33dd44ee55ff66aa11b1b2777888",
500 "expExitCode": "255",
501 "verifyCmd": "$TC actions get action tunnel_key index 1",
502 "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 192.168.10.1.*dst_ip 192.168.20.2.*key_id 123.*csum continue.*index 1.*cookie aa11bb22cc33dd44ee55ff66aa11b1b2777888",
503 "matchCount": "0",
504 "teardown": [
505 [
506 "$TC actions flush action tunnel_key",
507 0,
508 1,
509 255
510 ]
511 ]
512 },
513 {
514 "id": "a07e",
515 "name": "Add tunnel_key action with no set/unset command specified",
516 "category": [
517 "actions",
518 "tunnel_key"
519 ],
520 "setup": [
521 [
522 "$TC actions flush action tunnel_key",
523 0,
524 1,
525 255
526 ]
527 ],
528 "cmdUnderTest": "$TC actions add action tunnel_key src_ip 10.10.10.1 dst_ip 20.20.20.2 id 1",
529 "expExitCode": "255",
530 "verifyCmd": "$TC actions get action tunnel_key index 1",
531 "matchPattern": "action order [0-9]+: tunnel_key.*src_ip 10.10.10.1.*dst_ip 20.20.20.2.*key_id 1",
532 "matchCount": "0",
533 "teardown": [
534 [
535 "$TC actions flush action tunnel_key",
536 0,
537 1,
538 255
539 ]
540 ]
541 },
542 {
543 "id": "b227",
544 "name": "Add tunnel_key action with csum option",
545 "category": [
546 "actions",
547 "tunnel_key"
548 ],
549 "setup": [
550 [
551 "$TC actions flush action tunnel_key",
552 0,
553 1,
554 255
555 ]
556 ],
557 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 10.10.10.1 dst_ip 20.20.20.2 id 1 csum index 99",
558 "expExitCode": "0",
559 "verifyCmd": "$TC actions get action tunnel_key index 99",
560 "matchPattern": "action order [0-9]+: tunnel_key.*src_ip 10.10.10.1.*dst_ip 20.20.20.2.*key_id 1.*csum pipe.*index 99",
561 "matchCount": "1",
562 "teardown": [
563 "$TC actions flush action tunnel_key"
564 ]
565 },
566 {
567 "id": "58a7",
568 "name": "Add tunnel_key action with nocsum option",
569 "category": [
570 "actions",
571 "tunnel_key"
572 ],
573 "setup": [
574 [
575 "$TC actions flush action tunnel_key",
576 0,
577 1,
578 255
579 ]
580 ],
581 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 10.10.10.1 dst_ip 10.10.10.2 id 7823 nocsum index 234",
582 "expExitCode": "0",
583 "verifyCmd": "$TC actions get action tunnel_key index 234",
584 "matchPattern": "action order [0-9]+: tunnel_key.*src_ip 10.10.10.1.*dst_ip 10.10.10.2.*key_id 7823.*nocsum pipe.*index 234",
585 "matchCount": "1",
586 "teardown": [
587 "$TC actions flush action tunnel_key"
588 ]
589 },
590 {
591 "id": "2575",
592 "name": "Add tunnel_key action with not-supported parameter",
593 "category": [
594 "actions",
595 "tunnel_key"
596 ],
597 "setup": [
598 [
599 "$TC actions flush action tunnel_key",
600 0,
601 1,
602 255
603 ]
604 ],
605 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 10.10.10.1 dst_ip 10.10.10.2 id 7 foobar 999 index 4",
606 "expExitCode": "255",
607 "verifyCmd": "$TC actions get action tunnel_key index 4",
608 "matchPattern": "action order [0-9]+: tunnel_key.*src_ip 10.10.10.1.*dst_ip 10.10.10.2.*key_id 7.*foobar 999.*index 4",
609 "matchCount": "0",
610 "teardown": [
611 [
612 "$TC actions flush action tunnel_key",
613 0,
614 1,
615 255
616 ]
617 ]
618 },
619 {
620 "id": "7a88",
621 "name": "Add tunnel_key action with cookie parameter",
622 "category": [
623 "actions",
624 "tunnel_key"
625 ],
626 "setup": [
627 [
628 "$TC actions flush action tunnel_key",
629 0,
630 1,
631 255
632 ]
633 ],
634 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 10.10.10.1 dst_ip 10.10.10.2 id 7 index 4 cookie aa11bb22cc33dd44ee55ff66aa11b1b2",
635 "expExitCode": "0",
636 "verifyCmd": "$TC actions get action tunnel_key index 4",
637 "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 10.10.10.1.*dst_ip 10.10.10.2.*key_id 7.*dst_port 0.*csum pipe.*index 4 ref.*cookie aa11bb22cc33dd44ee55ff66aa11b1b2",
638 "matchCount": "1",
639 "teardown": [
640 "$TC actions flush action tunnel_key"
641 ]
642 },
643 {
644 "id": "4f20",
645 "name": "Add tunnel_key action with a single geneve option parameter",
646 "category": [
647 "actions",
648 "tunnel_key"
649 ],
650 "setup": [
651 [
652 "$TC actions flush action tunnel_key",
653 0,
654 1,
655 255
656 ]
657 ],
658 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 42 dst_port 6081 geneve_opts 0102:80:00880022 index 1",
659 "expExitCode": "0",
660 "verifyCmd": "$TC actions get action tunnel_key index 1",
661 "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 42.*dst_port 6081.*geneve_opt 0102:80:00880022.*index 1",
662 "matchCount": "1",
663 "teardown": [
664 "$TC actions flush action tunnel_key"
665 ]
666 },
667 {
668 "id": "e33d",
669 "name": "Add tunnel_key action with multiple geneve options parameter",
670 "category": [
671 "actions",
672 "tunnel_key"
673 ],
674 "setup": [
675 [
676 "$TC actions flush action tunnel_key",
677 0,
678 1,
679 255
680 ]
681 ],
682 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 42 dst_port 6081 geneve_opts 0102:80:00880022,0408:42:0040007611223344,0111:02:1020304011223344 index 1",
683 "expExitCode": "0",
684 "verifyCmd": "$TC actions get action tunnel_key index 1",
685 "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 42.*dst_port 6081.*geneve_opt 0102:80:00880022,0408:42:0040007611223344,0111:02:1020304011223344.*index 1",
686 "matchCount": "1",
687 "teardown": [
688 "$TC actions flush action tunnel_key"
689 ]
690 },
691 {
692 "id": "0778",
693 "name": "Add tunnel_key action with invalid class geneve option parameter",
694 "category": [
695 "actions",
696 "tunnel_key"
697 ],
698 "setup": [
699 [
700 "$TC actions flush action tunnel_key",
701 0,
702 1,
703 255
704 ]
705 ],
706 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 42 dst_port 6081 geneve_opts 824212:80:00880022 index 1",
707 "expExitCode": "255",
708 "verifyCmd": "$TC actions get action tunnel_key index 1",
709 "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 42.*dst_port 6081.*geneve_opt 824212:80:00880022.*index 1",
710 "matchCount": "0",
711 "teardown": [
712 "$TC actions flush action tunnel_key"
713 ]
714 },
715 {
716 "id": "4ae8",
717 "name": "Add tunnel_key action with invalid type geneve option parameter",
718 "category": [
719 "actions",
720 "tunnel_key"
721 ],
722 "setup": [
723 [
724 "$TC actions flush action tunnel_key",
725 0,
726 1,
727 255
728 ]
729 ],
730 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 42 dst_port 6081 geneve_opts 0102:4224:00880022 index 1",
731 "expExitCode": "255",
732 "verifyCmd": "$TC actions get action tunnel_key index 1",
733 "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 42.*dst_port 6081.*geneve_opt 0102:4224:00880022.*index 1",
734 "matchCount": "0",
735 "teardown": [
736 "$TC actions flush action tunnel_key"
737 ]
738 },
739 {
740 "id": "4039",
741 "name": "Add tunnel_key action with short data length geneve option parameter",
742 "category": [
743 "actions",
744 "tunnel_key"
745 ],
746 "setup": [
747 [
748 "$TC actions flush action tunnel_key",
749 0,
750 1,
751 255
752 ]
753 ],
754 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 42 dst_port 6081 geneve_opts 0102:80:4288 index 1",
755 "expExitCode": "255",
756 "verifyCmd": "$TC actions get action tunnel_key index 1",
757 "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 42.*dst_port 6081.*geneve_opt 0102:80:4288.*index 1",
758 "matchCount": "0",
759 "teardown": [
760 "$TC actions flush action tunnel_key"
761 ]
762 },
763 {
764 "id": "26a6",
765 "name": "Add tunnel_key action with non-multiple of 4 data length geneve option parameter",
766 "category": [
767 "actions",
768 "tunnel_key"
769 ],
770 "setup": [
771 [
772 "$TC actions flush action tunnel_key",
773 0,
774 1,
775 255
776 ]
777 ],
778 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 42 dst_port 6081 geneve_opts 0102:80:4288428822 index 1",
779 "expExitCode": "255",
780 "verifyCmd": "$TC actions get action tunnel_key index 1",
781 "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 42.*dst_port 6081.*geneve_opt 0102:80:4288428822.*index 1",
782 "matchCount": "0",
783 "teardown": [
784 "$TC actions flush action tunnel_key"
785 ]
786 },
787 {
788 "id": "f44d",
789 "name": "Add tunnel_key action with incomplete geneve options parameter",
790 "category": [
791 "actions",
792 "tunnel_key"
793 ],
794 "setup": [
795 [
796 "$TC actions flush action tunnel_key",
797 0,
798 1,
799 255
800 ]
801 ],
802 "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 42 dst_port 6081 geneve_opts 0102:80:00880022,0408:42: index 1",
803 "expExitCode": "255",
804 "verifyCmd": "$TC actions get action tunnel_key index 1",
805 "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 42.*dst_port 6081.*geneve_opt 0102:80:00880022,0408:42:.*index 1",
806 "matchCount": "0",
807 "teardown": [
808 "$TC actions flush action tunnel_key"
809 ]
810 },
811 {
812 "id": "7afc",
813 "name": "Replace tunnel_key set action with all parameters",
814 "category": [
815 "actions",
816 "tunnel_key"
817 ],
818 "setup": [
819 [
820 "$TC actions flush action tunnel_key",
821 0,
822 1,
823 255
824 ],
825 "$TC actions add action tunnel_key set src_ip 10.10.10.1 dst_ip 20.20.20.2 dst_port 3128 csum id 1 index 1"
826 ],
827 "cmdUnderTest": "$TC actions replace action tunnel_key set src_ip 11.11.11.1 dst_ip 21.21.21.2 dst_port 3129 nocsum id 11 index 1",
828 "expExitCode": "0",
829 "verifyCmd": "$TC actions get action tunnel_key index 1",
830 "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 11.11.11.1.*dst_ip 21.21.21.2.*key_id 11.*dst_port 3129.*nocsum pipe.*index 1",
831 "matchCount": "1",
832 "teardown": [
833 "$TC actions flush action tunnel_key"
834 ]
835 },
836 {
837 "id": "364d",
838 "name": "Replace tunnel_key set action with all parameters and cookie",
839 "category": [
840 "actions",
841 "tunnel_key"
842 ],
843 "setup": [
844 [
845 "$TC actions flush action tunnel_key",
846 0,
847 1,
848 255
849 ],
850 "$TC actions add action tunnel_key set src_ip 10.10.10.1 dst_ip 20.20.20.2 dst_port 3128 nocsum id 1 index 1 cookie aabbccddeeff112233445566778800a"
851 ],
852 "cmdUnderTest": "$TC actions replace action tunnel_key set src_ip 11.11.11.1 dst_ip 21.21.21.2 dst_port 3129 id 11 csum reclassify index 1 cookie a1b1c1d1",
853 "expExitCode": "0",
854 "verifyCmd": "$TC actions get action tunnel_key index 1",
855 "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 11.11.11.1.*dst_ip 21.21.21.2.*key_id 11.*dst_port 3129.*csum reclassify.*index 1.*cookie a1b1c1d1",
856 "matchCount": "1",
857 "teardown": [
858 "$TC actions flush action tunnel_key"
859 ]
860 },
861 {
862 "id": "937c",
863 "name": "Fetch all existing tunnel_key actions",
864 "category": [
865 "actions",
866 "tunnel_key"
867 ],
868 "setup": [
869 [
870 "$TC actions flush action tunnel_key",
871 0,
872 1,
873 255
874 ],
875 "$TC actions add action tunnel_key set src_ip 10.10.10.1 dst_ip 20.20.20.2 dst_port 3128 nocsum id 1 pipe index 1",
876 "$TC actions add action tunnel_key set src_ip 11.10.10.1 dst_ip 21.20.20.2 dst_port 3129 csum id 2 jump 10 index 2",
877 "$TC actions add action tunnel_key set src_ip 12.10.10.1 dst_ip 22.20.20.2 dst_port 3130 csum id 3 pass index 3",
878 "$TC actions add action tunnel_key set src_ip 13.10.10.1 dst_ip 23.20.20.2 dst_port 3131 nocsum id 4 continue index 4"
879 ],
880 "cmdUnderTest": "$TC actions list action tunnel_key",
881 "expExitCode": "0",
882 "verifyCmd": "$TC actions list action tunnel_key",
883 "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 10.10.10.1.*dst_ip 20.20.20.2.*key_id 1.*dst_port 3128.*nocsum pipe.*index 1.*set.*src_ip 11.10.10.1.*dst_ip 21.20.20.2.*key_id 2.*dst_port 3129.*csum jump 10.*index 2.*set.*src_ip 12.10.10.1.*dst_ip 22.20.20.2.*key_id 3.*dst_port 3130.*csum pass.*index 3.*set.*src_ip 13.10.10.1.*dst_ip 23.20.20.2.*key_id 4.*dst_port 3131.*nocsum continue.*index 4",
884 "matchCount": "1",
885 "teardown": [
886 "$TC actions flush action tunnel_key"
887 ]
888 },
889 {
890 "id": "6783",
891 "name": "Flush all existing tunnel_key actions",
892 "category": [
893 "actions",
894 "tunnel_key"
895 ],
896 "setup": [
897 [
898 "$TC actions flush action tunnel_key",
899 0,
900 1,
901 255
902 ],
903 "$TC actions add action tunnel_key set src_ip 10.10.10.1 dst_ip 20.20.20.2 dst_port 3128 nocsum id 1 pipe index 1",
904 "$TC actions add action tunnel_key set src_ip 11.10.10.1 dst_ip 21.20.20.2 dst_port 3129 csum id 2 reclassify index 2",
905 "$TC actions add action tunnel_key set src_ip 12.10.10.1 dst_ip 22.20.20.2 dst_port 3130 csum id 3 pass index 3",
906 "$TC actions add action tunnel_key set src_ip 13.10.10.1 dst_ip 23.20.20.2 dst_port 3131 nocsum id 4 continue index 4"
907 ],
908 "cmdUnderTest": "$TC actions flush action tunnel_key",
909 "expExitCode": "0",
910 "verifyCmd": "$TC actions list action tunnel_key",
911 "matchPattern": "action order [0-9]+:.*",
912 "matchCount": "0",
913 "teardown": [
914 "$TC actions flush action tunnel_key"
915 ]
916 }
917]
diff --git a/tools/testing/selftests/tc-testing/tc-tests/filters/fw.json b/tools/testing/selftests/tc-testing/tc-tests/filters/fw.json
new file mode 100644
index 000000000000..3b97cfd7e0f8
--- /dev/null
+++ b/tools/testing/selftests/tc-testing/tc-tests/filters/fw.json
@@ -0,0 +1,1049 @@
1[
2 {
3 "id": "901f",
4 "name": "Add fw filter with prio at 32-bit maxixum",
5 "category": [
6 "filter",
7 "fw"
8 ],
9 "setup": [
10 "$TC qdisc add dev $DEV1 ingress"
11 ],
12 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 65535 fw action ok",
13 "expExitCode": "0",
14 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 65535 protocol all fw",
15 "matchPattern": "pref 65535 fw.*handle 0x1.*gact action pass",
16 "matchCount": "1",
17 "teardown": [
18 "$TC qdisc del dev $DEV1 ingress"
19 ]
20 },
21 {
22 "id": "51e2",
23 "name": "Add fw filter with prio exceeding 32-bit maxixum",
24 "category": [
25 "filter",
26 "fw"
27 ],
28 "setup": [
29 "$TC qdisc add dev $DEV1 ingress"
30 ],
31 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 65536 fw action ok",
32 "expExitCode": "255",
33 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 65536 protocol all fw",
34 "matchPattern": "pref 65536 fw.*handle 0x1.*gact action pass",
35 "matchCount": "0",
36 "teardown": [
37 "$TC qdisc del dev $DEV1 ingress"
38 ]
39 },
40 {
41 "id": "d987",
42 "name": "Add fw filter with action ok",
43 "category": [
44 "filter",
45 "fw"
46 ],
47 "setup": [
48 "$TC qdisc add dev $DEV1 ingress"
49 ],
50 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw action ok",
51 "expExitCode": "0",
52 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw",
53 "matchPattern": "handle 0x1.*gact action pass",
54 "matchCount": "1",
55 "teardown": [
56 "$TC qdisc del dev $DEV1 ingress"
57 ]
58 },
59 {
60 "id": "affe",
61 "name": "Add fw filter with action continue",
62 "category": [
63 "filter",
64 "fw"
65 ],
66 "setup": [
67 "$TC qdisc add dev $DEV1 ingress"
68 ],
69 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw action continue",
70 "expExitCode": "0",
71 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw",
72 "matchPattern": "handle 0x1.*gact action continue",
73 "matchCount": "1",
74 "teardown": [
75 "$TC qdisc del dev $DEV1 ingress"
76 ]
77 },
78 {
79 "id": "28bc",
80 "name": "Add fw filter with action pipe",
81 "category": [
82 "filter",
83 "fw"
84 ],
85 "setup": [
86 "$TC qdisc add dev $DEV1 ingress"
87 ],
88 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw action pipe",
89 "expExitCode": "0",
90 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw",
91 "matchPattern": "handle 0x1.*gact action pipe",
92 "matchCount": "1",
93 "teardown": [
94 "$TC qdisc del dev $DEV1 ingress"
95 ]
96 },
97 {
98 "id": "8da2",
99 "name": "Add fw filter with action drop",
100 "category": [
101 "filter",
102 "fw"
103 ],
104 "setup": [
105 "$TC qdisc add dev $DEV1 ingress"
106 ],
107 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw action drop",
108 "expExitCode": "0",
109 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 protocol all prio 1 fw",
110 "matchPattern": "handle 0x1.*gact action drop",
111 "matchCount": "1",
112 "teardown": [
113 "$TC qdisc del dev $DEV1 ingress"
114 ]
115 },
116 {
117 "id": "9436",
118 "name": "Add fw filter with action reclassify",
119 "category": [
120 "filter",
121 "fw"
122 ],
123 "setup": [
124 "$TC qdisc add dev $DEV1 ingress"
125 ],
126 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw action reclassify",
127 "expExitCode": "0",
128 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw",
129 "matchPattern": "handle 0x1.*gact action reclassify",
130 "matchCount": "1",
131 "teardown": [
132 "$TC qdisc del dev $DEV1 ingress"
133 ]
134 },
135 {
136 "id": "95bb",
137 "name": "Add fw filter with action jump 10",
138 "category": [
139 "filter",
140 "fw"
141 ],
142 "setup": [
143 "$TC qdisc add dev $DEV1 ingress"
144 ],
145 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw action jump 10",
146 "expExitCode": "0",
147 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw",
148 "matchPattern": "handle 0x1.*gact action jump 10",
149 "matchCount": "1",
150 "teardown": [
151 "$TC qdisc del dev $DEV1 ingress"
152 ]
153 },
154 {
155 "id": "3d74",
156 "name": "Add fw filter with action goto chain 5",
157 "category": [
158 "filter",
159 "fw"
160 ],
161 "setup": [
162 "$TC qdisc add dev $DEV1 ingress"
163 ],
164 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw action goto chain 5",
165 "expExitCode": "0",
166 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw",
167 "matchPattern": "handle 0x1.*gact action goto chain 5",
168 "matchCount": "1",
169 "teardown": [
170 "$TC qdisc del dev $DEV1 ingress"
171 ]
172 },
173 {
174 "id": "eb8f",
175 "name": "Add fw filter with invalid action",
176 "category": [
177 "filter",
178 "fw"
179 ],
180 "setup": [
181 "$TC qdisc add dev $DEV1 ingress"
182 ],
183 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw action pump",
184 "expExitCode": "255",
185 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw",
186 "matchPattern": "handle 0x1.*gact action pump",
187 "matchCount": "0",
188 "teardown": [
189 "$TC qdisc del dev $DEV1 ingress"
190 ]
191 },
192 {
193 "id": "6a79",
194 "name": "Add fw filter with missing mandatory action",
195 "category": [
196 "filter",
197 "fw"
198 ],
199 "setup": [
200 "$TC qdisc add dev $DEV1 ingress"
201 ],
202 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw",
203 "expExitCode": "2",
204 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw",
205 "matchPattern": "filter protocol all pref [0-9]+ fw.*handle 0x1",
206 "matchCount": "0",
207 "teardown": [
208 "$TC qdisc del dev $DEV1 ingress"
209 ]
210 },
211 {
212 "id": "8298",
213 "name": "Add fw filter with cookie",
214 "category": [
215 "filter",
216 "fw"
217 ],
218 "setup": [
219 "$TC qdisc add dev $DEV1 ingress"
220 ],
221 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 2 fw action pipe cookie aa11bb22cc33dd44ee55ff66aa11b1b2",
222 "expExitCode": "0",
223 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 2 protocol all fw",
224 "matchPattern": "pref 2 fw.*handle 0x1.*gact action pipe.*cookie aa11bb22cc33dd44ee55ff66aa11b1b2",
225 "matchCount": "1",
226 "teardown": [
227 "$TC qdisc del dev $DEV1 ingress"
228 ]
229 },
230 {
231 "id": "a88c",
232 "name": "Add fw filter with invalid cookie",
233 "category": [
234 "filter",
235 "fw"
236 ],
237 "setup": [
238 "$TC qdisc add dev $DEV1 ingress"
239 ],
240 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 2 fw action continue cookie aa11bb22cc33dd44ee55ff66aa11b1b2777888",
241 "expExitCode": "255",
242 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 2 protocol all fw",
243 "matchPattern": "pref 2 fw.*handle 0x1.*gact action continue.*cookie aa11bb22cc33dd44ee55ff66aa11b1b2777888",
244 "matchCount": "0",
245 "teardown": [
246 "$TC qdisc del dev $DEV1 ingress"
247 ]
248 },
249 {
250 "id": "10f6",
251 "name": "Add fw filter with handle in hex",
252 "category": [
253 "filter",
254 "fw"
255 ],
256 "setup": [
257 "$TC qdisc add dev $DEV1 ingress"
258 ],
259 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 0xa1b2ff prio 1 fw action ok",
260 "expExitCode": "0",
261 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 0xa1b2ff prio 1 protocol all fw",
262 "matchPattern": "fw.*handle 0xa1b2ff.*gact action pass",
263 "matchCount": "1",
264 "teardown": [
265 "$TC qdisc del dev $DEV1 ingress"
266 ]
267 },
268 {
269 "id": "9d51",
270 "name": "Add fw filter with handle at 32-bit maximum",
271 "category": [
272 "filter",
273 "fw"
274 ],
275 "setup": [
276 "$TC qdisc add dev $DEV1 ingress"
277 ],
278 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 4294967295 prio 1 fw action ok",
279 "expExitCode": "0",
280 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 4294967295 prio 1 protocol all fw",
281 "matchPattern": "fw.*handle 0xffffffff.*gact action pass",
282 "matchCount": "1",
283 "teardown": [
284 "$TC qdisc del dev $DEV1 ingress"
285 ]
286 },
287 {
288 "id": "d939",
289 "name": "Add fw filter with handle exceeding 32-bit maximum",
290 "category": [
291 "filter",
292 "fw"
293 ],
294 "setup": [
295 "$TC qdisc add dev $DEV1 ingress"
296 ],
297 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 4294967296 prio 1 fw action ok",
298 "expExitCode": "1",
299 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 4294967296 prio 1 protocol all fw",
300 "matchPattern": "fw.*handle 0x.*gact action pass",
301 "matchCount": "0",
302 "teardown": [
303 "$TC qdisc del dev $DEV1 ingress"
304 ]
305 },
306 {
307 "id": "658c",
308 "name": "Add fw filter with mask in hex",
309 "category": [
310 "filter",
311 "fw"
312 ],
313 "setup": [
314 "$TC qdisc add dev $DEV1 ingress"
315 ],
316 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 10/0xa1b2f prio 1 fw action ok",
317 "expExitCode": "0",
318 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 10 prio 1 protocol all fw",
319 "matchPattern": "fw.*handle 0xa/0xa1b2f",
320 "matchCount": "1",
321 "teardown": [
322 "$TC qdisc del dev $DEV1 ingress"
323 ]
324 },
325 {
326 "id": "86be",
327 "name": "Add fw filter with mask at 32-bit maximum",
328 "category": [
329 "filter",
330 "fw"
331 ],
332 "setup": [
333 "$TC qdisc add dev $DEV1 ingress"
334 ],
335 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 10/4294967295 prio 1 fw action ok",
336 "expExitCode": "0",
337 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 10 prio 1 protocol all fw",
338 "matchPattern": "fw.*handle 0xa[^/]",
339 "matchCount": "1",
340 "teardown": [
341 "$TC qdisc del dev $DEV1 ingress"
342 ]
343 },
344 {
345 "id": "e635",
346 "name": "Add fw filter with mask exceeding 32-bit maximum",
347 "category": [
348 "filter",
349 "fw"
350 ],
351 "setup": [
352 "$TC qdisc add dev $DEV1 ingress"
353 ],
354 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 10/4294967296 prio 1 fw action ok",
355 "expExitCode": "1",
356 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 10 prio 1 protocol all fw",
357 "matchPattern": "fw.*handle 0xa",
358 "matchCount": "0",
359 "teardown": [
360 "$TC qdisc del dev $DEV1 ingress"
361 ]
362 },
363 {
364 "id": "6cab",
365 "name": "Add fw filter with handle/mask in hex",
366 "category": [
367 "filter",
368 "fw"
369 ],
370 "setup": [
371 "$TC qdisc add dev $DEV1 ingress"
372 ],
373 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 0xa1b2cdff/0x1a2bffdc prio 1 fw action ok",
374 "expExitCode": "0",
375 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 0xa1b2cdff prio 1 protocol all fw",
376 "matchPattern": "fw.*handle 0xa1b2cdff/0x1a2bffdc",
377 "matchCount": "1",
378 "teardown": [
379 "$TC qdisc del dev $DEV1 ingress"
380 ]
381 },
382 {
383 "id": "8700",
384 "name": "Add fw filter with handle/mask at 32-bit maximum",
385 "category": [
386 "filter",
387 "fw"
388 ],
389 "setup": [
390 "$TC qdisc add dev $DEV1 ingress"
391 ],
392 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 4294967295/4294967295 prio 1 fw action ok",
393 "expExitCode": "0",
394 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 0xffffffff prio 1 protocol all fw",
395 "matchPattern": "fw.*handle 0xffffffff[^/]",
396 "matchCount": "1",
397 "teardown": [
398 "$TC qdisc del dev $DEV1 ingress"
399 ]
400 },
401 {
402 "id": "7d62",
403 "name": "Add fw filter with handle/mask exceeding 32-bit maximum",
404 "category": [
405 "filter",
406 "fw"
407 ],
408 "setup": [
409 "$TC qdisc add dev $DEV1 ingress"
410 ],
411 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 4294967296/4294967296 prio 1 fw action ok",
412 "expExitCode": "1",
413 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 10 prio 1 protocol all fw",
414 "matchPattern": "fw.*handle",
415 "matchCount": "0",
416 "teardown": [
417 "$TC qdisc del dev $DEV1 ingress"
418 ]
419 },
420 {
421 "id": "7b69",
422 "name": "Add fw filter with missing mandatory handle",
423 "category": [
424 "filter",
425 "fw"
426 ],
427 "setup": [
428 "$TC qdisc add dev $DEV1 ingress"
429 ],
430 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: prio 1 fw action ok",
431 "expExitCode": "2",
432 "verifyCmd": "$TC filter show dev $DEV1 parent ffff:",
433 "matchPattern": "filter protocol all.*fw.*handle.*gact action pass",
434 "matchCount": "0",
435 "teardown": [
436 "$TC qdisc del dev $DEV1 ingress"
437 ]
438 },
439 {
440 "id": "d68b",
441 "name": "Add fw filter with invalid parent",
442 "category": [
443 "filter",
444 "fw"
445 ],
446 "setup": [
447 "$TC qdisc add dev $DEV1 ingress"
448 ],
449 "cmdUnderTest": "$TC filter add dev $DEV1 parent aa11b1b2: handle 1 prio 1 fw action ok",
450 "expExitCode": "255",
451 "verifyCmd": "$TC filter dev $DEV1 parent aa11b1b2: handle 1 prio 1 protocol all fw",
452 "matchPattern": "filter protocol all pref 1 fw.*handle 0x1.*gact action pass",
453 "matchCount": "0",
454 "teardown": [
455 "$TC qdisc del dev $DEV1 ingress"
456 ]
457 },
458 {
459 "id": "66e0",
460 "name": "Add fw filter with missing mandatory parent id",
461 "category": [
462 "filter",
463 "fw"
464 ],
465 "setup": [
466 "$TC qdisc add dev $DEV1 ingress"
467 ],
468 "cmdUnderTest": "$TC filter add dev $DEV1 handle 1 prio 1 fw action ok",
469 "expExitCode": "2",
470 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw",
471 "matchPattern": "pref [0-9]+ fw.*handle 0x1.*gact action pass",
472 "matchCount": "0",
473 "teardown": [
474 "$TC qdisc del dev $DEV1 ingress"
475 ]
476 },
477 {
478 "id": "0ff3",
479 "name": "Add fw filter with classid",
480 "category": [
481 "filter",
482 "fw"
483 ],
484 "setup": [
485 "$TC qdisc add dev $DEV1 ingress"
486 ],
487 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw classid 3 action ok",
488 "expExitCode": "0",
489 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw",
490 "matchPattern": "fw.*handle 0x1 classid :3.*gact action pass",
491 "matchCount": "1",
492 "teardown": [
493 "$TC qdisc del dev $DEV1 ingress"
494 ]
495 },
496 {
497 "id": "9849",
498 "name": "Add fw filter with classid at root",
499 "category": [
500 "filter",
501 "fw"
502 ],
503 "setup": [
504 "$TC qdisc add dev $DEV1 ingress"
505 ],
506 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw classid ffff:ffff action ok",
507 "expExitCode": "0",
508 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw",
509 "matchPattern": "pref 1 fw.*handle 0x1 classid root.*gact action pass",
510 "matchCount": "1",
511 "teardown": [
512 "$TC qdisc del dev $DEV1 ingress"
513 ]
514 },
515 {
516 "id": "b7ff",
517 "name": "Add fw filter with classid - keeps last 8 (hex) digits",
518 "category": [
519 "filter",
520 "fw"
521 ],
522 "setup": [
523 "$TC qdisc add dev $DEV1 ingress"
524 ],
525 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw classid 98765fedcb action ok",
526 "expExitCode": "0",
527 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw",
528 "matchPattern": "fw.*handle 0x1 classid 765f:edcb.*gact action pass",
529 "matchCount": "1",
530 "teardown": [
531 "$TC qdisc del dev $DEV1 ingress"
532 ]
533 },
534 {
535 "id": "2b18",
536 "name": "Add fw filter with invalid classid",
537 "category": [
538 "filter",
539 "fw"
540 ],
541 "setup": [
542 "$TC qdisc add dev $DEV1 ingress"
543 ],
544 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw classid 6789defg action ok",
545 "expExitCode": "1",
546 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw",
547 "matchPattern": "fw.*handle 0x1 classid 6789:defg.*gact action pass",
548 "matchCount": "0",
549 "teardown": [
550 "$TC qdisc del dev $DEV1 ingress"
551 ]
552 },
553 {
554 "id": "fade",
555 "name": "Add fw filter with flowid",
556 "category": [
557 "filter",
558 "fw"
559 ],
560 "setup": [
561 "$TC qdisc add dev $DEV1 ingress"
562 ],
563 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 10 prio 1 fw flowid 1:10 action ok",
564 "expExitCode": "0",
565 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 10 prio 1 protocol all fw",
566 "matchPattern": "filter parent ffff: protocol all pref 1 fw.*handle 0xa classid 1:10.*gact action pass",
567 "matchCount": "1",
568 "teardown": [
569 "$TC qdisc del dev $DEV1 ingress"
570 ]
571 },
572 {
573 "id": "33af",
574 "name": "Add fw filter with flowid then classid (same arg, takes second)",
575 "category": [
576 "filter",
577 "fw"
578 ],
579 "setup": [
580 "$TC qdisc add dev $DEV1 ingress"
581 ],
582 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 11 prio 1 fw flowid 10 classid 4 action ok",
583 "expExitCode": "0",
584 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 11 prio 1 protocol all fw",
585 "matchPattern": "filter parent ffff: protocol all pref 1 fw.*handle 0xb classid :4.*gact action pass",
586 "matchCount": "1",
587 "teardown": [
588 "$TC qdisc del dev $DEV1 ingress"
589 ]
590 },
591 {
592 "id": "8a8c",
593 "name": "Add fw filter with classid then flowid (same arg, takes second)",
594 "category": [
595 "filter",
596 "fw"
597 ],
598 "setup": [
599 "$TC qdisc add dev $DEV1 ingress"
600 ],
601 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 11 prio 1 fw classid 4 flowid 10 action ok",
602 "expExitCode": "0",
603 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 11 prio 1 protocol all fw",
604 "matchPattern": "filter parent ffff: protocol all pref 1 fw.*handle 0xb classid :10.*gact action pass",
605 "matchCount": "1",
606 "teardown": [
607 "$TC qdisc del dev $DEV1 ingress"
608 ]
609 },
610 {
611 "id": "b50d",
612 "name": "Add fw filter with handle val/mask and flowid 10:1000",
613 "category": [
614 "filter",
615 "fw"
616 ],
617 "setup": [
618 "$TC qdisc add dev $DEV1 ingress"
619 ],
620 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: prio 3 handle 10/0xff fw flowid 10:1000 action ok",
621 "expExitCode": "0",
622 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 10 prio 3 protocol all fw",
623 "matchPattern": "filter parent ffff: protocol all pref 3 fw.*handle 0xa/0xff classid 10:1000.*gact action pass",
624 "matchCount": "1",
625 "teardown": [
626 "$TC qdisc del dev $DEV1 ingress"
627 ]
628 },
629 {
630 "id": "7207",
631 "name": "Add fw filter with protocol ip",
632 "category": [
633 "filter",
634 "fw"
635 ],
636 "setup": [
637 "$TC qdisc add dev $DEV1 ingress"
638 ],
639 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol ip prio 1 handle 3 fw action ok",
640 "expExitCode": "0",
641 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 3 prio 1 protocol ip fw",
642 "matchPattern": "filter parent ffff: protocol ip pref 1 fw.*handle 0x3.*gact action pass.*index [0-9]+ ref [0-9]+ bind [0-9]+",
643 "matchCount": "1",
644 "teardown": [
645 "$TC qdisc del dev $DEV1 ingress"
646 ]
647 },
648 {
649 "id": "306d",
650 "name": "Add fw filter with protocol ipv6",
651 "category": [
652 "filter",
653 "fw"
654 ],
655 "setup": [
656 "$TC qdisc add dev $DEV1 ingress"
657 ],
658 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol ipv6 prio 2 handle 4 fw action ok",
659 "expExitCode": "0",
660 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 4 prio 2 protocol ipv6 fw",
661 "matchPattern": "filter parent ffff: protocol ipv6 pref 2 fw.*handle 0x4.*gact action pass.*index [0-9]+ ref [0-9]+ bind [0-9]+",
662 "matchCount": "1",
663 "teardown": [
664 "$TC qdisc del dev $DEV1 ingress"
665 ]
666 },
667 {
668 "id": "9a78",
669 "name": "Add fw filter with protocol arp",
670 "category": [
671 "filter",
672 "fw"
673 ],
674 "setup": [
675 "$TC qdisc add dev $DEV1 ingress"
676 ],
677 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol arp prio 5 handle 7 fw action drop",
678 "expExitCode": "0",
679 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 7 prio 5 protocol arp fw",
680 "matchPattern": "filter parent ffff: protocol arp pref 5 fw.*handle 0x7.*gact action drop.*index [0-9]+ ref [0-9]+ bind [0-9]+",
681 "matchCount": "1",
682 "teardown": [
683 "$TC qdisc del dev $DEV1 ingress"
684 ]
685 },
686 {
687 "id": "1821",
688 "name": "Add fw filter with protocol 802_3",
689 "category": [
690 "filter",
691 "fw"
692 ],
693 "setup": [
694 "$TC qdisc add dev $DEV1 ingress"
695 ],
696 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol 802_3 handle 1 prio 1 fw action ok",
697 "expExitCode": "0",
698 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol 802_3 fw",
699 "matchPattern": "filter parent ffff: protocol 802_3 pref 1 fw.*handle 0x1.*gact action pass",
700 "matchCount": "1",
701 "teardown": [
702 "$TC qdisc del dev $DEV1 ingress"
703 ]
704 },
705 {
706 "id": "2260",
707 "name": "Add fw filter with invalid protocol",
708 "category": [
709 "filter",
710 "fw"
711 ],
712 "setup": [
713 "$TC qdisc add dev $DEV1 ingress"
714 ],
715 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol igmp handle 1 prio 1 fw action ok",
716 "expExitCode": "255",
717 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol igmp fw",
718 "matchPattern": "filter parent ffff: protocol igmp pref 1 fw.*handle 0x1.*gact action pass",
719 "matchCount": "0",
720 "teardown": [
721 "$TC qdisc del dev $DEV1 ingress"
722 ]
723 },
724 {
725 "id": "09d7",
726 "name": "Add fw filters protocol 802_3 and ip with conflicting priorities",
727 "category": [
728 "filter",
729 "fw"
730 ],
731 "setup": [
732 "$TC qdisc add dev $DEV1 ingress",
733 "$TC filter add dev $DEV1 parent ffff: protocol 802_3 prio 3 handle 7 fw action ok"
734 ],
735 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol ip prio 3 handle 8 fw action ok",
736 "expExitCode": "2",
737 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 8 prio 3 protocol ip fw",
738 "matchPattern": "filter parent ffff: protocol ip pref 3 fw.*handle 0x8",
739 "matchCount": "0",
740 "teardown": [
741 "$TC qdisc del dev $DEV1 ingress"
742 ]
743 },
744 {
745 "id": "6973",
746 "name": "Add fw filters with same index, same action",
747 "category": [
748 "filter",
749 "fw"
750 ],
751 "setup": [
752 "$TC qdisc add dev $DEV1 ingress",
753 "$TC filter add dev $DEV1 parent ffff: prio 6 handle 2 fw action continue index 5"
754 ],
755 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: prio 8 handle 4 fw action continue index 5",
756 "expExitCode": "0",
757 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 4 prio 8 protocol all fw",
758 "matchPattern": "filter parent ffff: protocol all pref 8 fw.*handle 0x4.*gact action continue.*index 5 ref 2 bind 2",
759 "matchCount": "1",
760 "teardown": [
761 "$TC qdisc del dev $DEV1 ingress"
762 ]
763 },
764 {
765 "id": "fc06",
766 "name": "Add fw filters with action police",
767 "category": [
768 "filter",
769 "fw"
770 ],
771 "setup": [
772 "$TC qdisc add dev $DEV1 ingress"
773 ],
774 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: prio 3 handle 4 fw action police rate 1kbit burst 10k index 5",
775 "expExitCode": "0",
776 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 4 prio 3 protocol all fw",
777 "matchPattern": "filter parent ffff: protocol all pref 3 fw.*handle 0x4.*police 0x5 rate 1Kbit burst 10Kb mtu 2Kb action reclassify overhead 0b.*ref 1 bind 1",
778 "matchCount": "1",
779 "teardown": [
780 "$TC qdisc del dev $DEV1 ingress"
781 ]
782 },
783 {
784 "id": "aac7",
785 "name": "Add fw filters with action police linklayer atm",
786 "category": [
787 "filter",
788 "fw"
789 ],
790 "setup": [
791 "$TC qdisc add dev $DEV1 ingress"
792 ],
793 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: prio 3 handle 4 fw action police rate 2mbit burst 200k linklayer atm index 8",
794 "expExitCode": "0",
795 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 4 prio 3 protocol all fw",
796 "matchPattern": "filter parent ffff: protocol all pref 3 fw.*handle 0x4.*police 0x8 rate 2Mbit burst 200Kb mtu 2Kb action reclassify overhead 0b linklayer atm.*ref 1 bind 1",
797 "matchCount": "1",
798 "teardown": [
799 "$TC qdisc del dev $DEV1 ingress"
800 ]
801 },
802 {
803 "id": "5339",
804 "name": "Del entire fw filter",
805 "category": [
806 "filter",
807 "fw"
808 ],
809 "setup": [
810 "$TC qdisc add dev $DEV1 ingress",
811 "$TC filter add dev $DEV1 parent ffff: handle 5 prio 7 fw action pass",
812 "$TC filter add dev $DEV1 parent ffff: handle 3 prio 9 fw action pass"
813 ],
814 "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff:",
815 "expExitCode": "0",
816 "verifyCmd": "$TC filter show dev $DEV1 parent ffff:",
817 "matchPattern": "protocol all pref.*handle.*gact action pass",
818 "matchCount": "0",
819 "teardown": [
820 "$TC qdisc del dev $DEV1 ingress"
821 ]
822 },
823 {
824 "id": "0e99",
825 "name": "Del single fw filter x1",
826 "__comment__": "First of two tests to check that one filter is there and the other isn't",
827 "category": [
828 "filter",
829 "fw"
830 ],
831 "setup": [
832 "$TC qdisc add dev $DEV1 ingress",
833 "$TC filter add dev $DEV1 parent ffff: handle 5 prio 7 fw action pass",
834 "$TC filter add dev $DEV1 parent ffff: handle 3 prio 9 fw action pass"
835 ],
836 "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: handle 3 prio 9 fw action pass",
837 "expExitCode": "0",
838 "verifyCmd": "$TC filter show dev $DEV1 parent ffff:",
839 "matchPattern": "protocol all pref 7.*handle 0x5.*gact action pass",
840 "matchCount": "1",
841 "teardown": [
842 "$TC qdisc del dev $DEV1 ingress"
843 ]
844 },
845 {
846 "id": "f54c",
847 "name": "Del single fw filter x2",
848 "__comment__": "Second of two tests to check that one filter is there and the other isn't",
849 "category": [
850 "filter",
851 "fw"
852 ],
853 "setup": [
854 "$TC qdisc add dev $DEV1 ingress",
855 "$TC filter add dev $DEV1 parent ffff: handle 5 prio 7 fw action pass",
856 "$TC filter add dev $DEV1 parent ffff: handle 3 prio 9 fw action pass"
857 ],
858 "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: handle 3 prio 9 fw action pass",
859 "expExitCode": "0",
860 "verifyCmd": "$TC filter show dev $DEV1 parent ffff:",
861 "matchPattern": "protocol all pref 9.*handle 0x3.*gact action pass",
862 "matchCount": "0",
863 "teardown": [
864 "$TC qdisc del dev $DEV1 ingress"
865 ]
866 },
867 {
868 "id": "ba94",
869 "name": "Del fw filter by prio",
870 "category": [
871 "filter",
872 "fw"
873 ],
874 "setup": [
875 "$TC qdisc add dev $DEV1 ingress",
876 "$TC filter add dev $DEV1 parent ffff: handle 1 prio 4 fw action ok",
877 "$TC filter add dev $DEV1 parent ffff: handle 2 prio 4 fw action ok"
878 ],
879 "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: prio 4",
880 "expExitCode": "0",
881 "verifyCmd": "$TC filter show dev $DEV1 parent ffff:",
882 "matchPattern": "pref 4 fw.*gact action pass",
883 "matchCount": "0",
884 "teardown": [
885 "$TC qdisc del dev $DEV1 ingress"
886 ]
887 },
888 {
889 "id": "4acb",
890 "name": "Del fw filter by chain",
891 "category": [
892 "filter",
893 "fw"
894 ],
895 "setup": [
896 "$TC qdisc add dev $DEV1 ingress",
897 "$TC filter add dev $DEV1 parent ffff: handle 4 prio 2 chain 13 fw action pipe",
898 "$TC filter add dev $DEV1 parent ffff: handle 3 prio 5 chain 13 fw action pipe"
899 ],
900 "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: chain 13",
901 "expExitCode": "0",
902 "verifyCmd": "$TC filter show dev $DEV1 parent ffff:",
903 "matchPattern": "fw chain 13 handle.*gact action pipe",
904 "matchCount": "0",
905 "teardown": [
906 "$TC qdisc del dev $DEV1 ingress"
907 ]
908 },
909 {
910 "id": "3424",
911 "name": "Del fw filter by action (invalid)",
912 "category": [
913 "filter",
914 "fw"
915 ],
916 "setup": [
917 "$TC qdisc add dev $DEV1 ingress",
918 "$TC filter add dev $DEV1 parent ffff: handle 2 prio 4 fw action drop"
919 ],
920 "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: fw action drop",
921 "expExitCode": "2",
922 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 2 prio 4 protocol all fw",
923 "matchPattern": "handle 0x2.*gact action drop",
924 "matchCount": "1",
925 "teardown": [
926 "$TC qdisc del dev $DEV1 ingress"
927 ]
928 },
929 {
930 "id": "da89",
931 "name": "Del fw filter by handle (invalid)",
932 "category": [
933 "filter",
934 "fw"
935 ],
936 "setup": [
937 "$TC qdisc add dev $DEV1 ingress",
938 "$TC filter add dev $DEV1 parent ffff: handle 3 prio 4 fw action continue"
939 ],
940 "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: handle 3 fw",
941 "expExitCode": "2",
942 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 3 prio 4 protocol all fw",
943 "matchPattern": "handle 0x3.*gact action continue",
944 "matchCount": "1",
945 "teardown": [
946 "$TC qdisc del dev $DEV1 ingress"
947 ]
948 },
949 {
950 "id": "4d95",
951 "name": "Del fw filter by protocol (invalid)",
952 "category": [
953 "filter",
954 "fw"
955 ],
956 "setup": [
957 "$TC qdisc add dev $DEV1 ingress",
958 "$TC filter add dev $DEV1 parent ffff: handle 4 prio 2 protocol arp fw action pipe"
959 ],
960 "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: protocol arp fw",
961 "expExitCode": "2",
962 "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 4 prio 2 protocol arp fw",
963 "matchPattern": "filter parent ffff: protocol arp.*handle 0x4.*gact action pipe",
964 "matchCount": "1",
965 "teardown": [
966 "$TC qdisc del dev $DEV1 ingress"
967 ]
968 },
969 {
970 "id": "4736",
971 "name": "Del fw filter by flowid (invalid)",
972 "category": [
973 "filter",
974 "fw"
975 ],
976 "setup": [
977 "$TC qdisc add dev $DEV1 ingress",
978 "$TC filter add dev $DEV1 parent ffff: handle 4 prio 2 fw action pipe flowid 45"
979 ],
980 "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: fw flowid 45",
981 "expExitCode": "2",
982 "verifyCmd": "$TC filter show dev $DEV1 parent ffff:",
983 "matchPattern": "handle 0x4.*gact action pipe",
984 "matchCount": "1",
985 "teardown": [
986 "$TC qdisc del dev $DEV1 ingress"
987 ]
988 },
989 {
990 "id": "3dcb",
991 "name": "Replace fw filter action",
992 "category": [
993 "filter",
994 "fw"
995 ],
996 "setup": [
997 "$TC qdisc add dev $DEV1 ingress",
998 "$TC filter add dev $DEV1 parent ffff: handle 1 prio 2 fw action ok"
999 ],
1000 "cmdUnderTest": "$TC filter replace dev $DEV1 parent ffff: handle 1 prio 2 fw action pipe",
1001 "expExitCode": "0",
1002 "verifyCmd": "$TC filter show dev $DEV1 parent ffff:",
1003 "matchPattern": "pref 2 fw.*handle 0x1.*gact action pipe",
1004 "matchCount": "1",
1005 "teardown": [
1006 "$TC qdisc del dev $DEV1 ingress"
1007 ]
1008 },
1009 {
1010 "id": "eb4d",
1011 "name": "Replace fw filter classid",
1012 "category": [
1013 "filter",
1014 "fw"
1015 ],
1016 "setup": [
1017 "$TC qdisc add dev $DEV1 ingress",
1018 "$TC filter add dev $DEV1 parent ffff: handle 1 prio 2 fw action ok"
1019 ],
1020 "cmdUnderTest": "$TC filter replace dev $DEV1 parent ffff: handle 1 prio 2 fw action pipe classid 2",
1021 "expExitCode": "0",
1022 "verifyCmd": "$TC filter show dev $DEV1 parent ffff:",
1023 "matchPattern": "pref 2 fw.*handle 0x1 classid :2.*gact action pipe",
1024 "matchCount": "1",
1025 "teardown": [
1026 "$TC qdisc del dev $DEV1 ingress"
1027 ]
1028 },
1029 {
1030 "id": "67ec",
1031 "name": "Replace fw filter index",
1032 "category": [
1033 "filter",
1034 "fw"
1035 ],
1036 "setup": [
1037 "$TC qdisc add dev $DEV1 ingress",
1038 "$TC filter add dev $DEV1 parent ffff: handle 1 prio 2 fw action ok index 3"
1039 ],
1040 "cmdUnderTest": "$TC filter replace dev $DEV1 parent ffff: handle 1 prio 2 fw action ok index 16",
1041 "expExitCode": "0",
1042 "verifyCmd": "$TC filter show dev $DEV1 parent ffff:",
1043 "matchPattern": "pref 2 fw.*handle 0x1.*gact action pass.*index 16",
1044 "matchCount": "1",
1045 "teardown": [
1046 "$TC qdisc del dev $DEV1 ingress"
1047 ]
1048 }
1049]
diff --git a/tools/testing/selftests/tc-testing/tc-tests/filters/tests.json b/tools/testing/selftests/tc-testing/tc-tests/filters/tests.json
index 5fa02d86b35f..99a5ffca1088 100644
--- a/tools/testing/selftests/tc-testing/tc-tests/filters/tests.json
+++ b/tools/testing/selftests/tc-testing/tc-tests/filters/tests.json
@@ -12,8 +12,8 @@
12 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol ip prio 1 u32 match ip src 127.0.0.1/32 flowid 1:1 action ok", 12 "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol ip prio 1 u32 match ip src 127.0.0.1/32 flowid 1:1 action ok",
13 "expExitCode": "0", 13 "expExitCode": "0",
14 "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", 14 "verifyCmd": "$TC filter show dev $DEV1 parent ffff:",
15 "matchPattern": "match 7f000002/ffffffff at 12", 15 "matchPattern": "match 7f000001/ffffffff at 12",
16 "matchCount": "0", 16 "matchCount": "1",
17 "teardown": [ 17 "teardown": [
18 "$TC qdisc del dev $DEV1 ingress" 18 "$TC qdisc del dev $DEV1 ingress"
19 ] 19 ]
diff --git a/tools/testing/selftests/timers/raw_skew.c b/tools/testing/selftests/timers/raw_skew.c
index ca6cd146aafe..dcf73c5dab6e 100644
--- a/tools/testing/selftests/timers/raw_skew.c
+++ b/tools/testing/selftests/timers/raw_skew.c
@@ -134,6 +134,11 @@ int main(int argv, char **argc)
134 printf(" %lld.%i(act)", ppm/1000, abs((int)(ppm%1000))); 134 printf(" %lld.%i(act)", ppm/1000, abs((int)(ppm%1000)));
135 135
136 if (llabs(eppm - ppm) > 1000) { 136 if (llabs(eppm - ppm) > 1000) {
137 if (tx1.offset || tx2.offset ||
138 tx1.freq != tx2.freq || tx1.tick != tx2.tick) {
139 printf(" [SKIP]\n");
140 return ksft_exit_skip("The clock was adjusted externally. Shutdown NTPd or other time sync daemons\n");
141 }
137 printf(" [FAILED]\n"); 142 printf(" [FAILED]\n");
138 return ksft_exit_fail(); 143 return ksft_exit_fail();
139 } 144 }