diff options
Diffstat (limited to 'tools')
91 files changed, 4813 insertions, 1126 deletions
diff --git a/tools/arch/x86/lib/x86-opcode-map.txt b/tools/arch/x86/lib/x86-opcode-map.txt index 0a0e9112f284..8908c58bd6cd 100644 --- a/tools/arch/x86/lib/x86-opcode-map.txt +++ b/tools/arch/x86/lib/x86-opcode-map.txt @@ -695,16 +695,28 @@ AVXcode: 2 4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev) 4e: vrsqrt14ps/d Vpd,Wpd (66),(ev) 4f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev) -# Skip 0x50-0x57 +50: vpdpbusd Vx,Hx,Wx (66),(ev) +51: vpdpbusds Vx,Hx,Wx (66),(ev) +52: vdpbf16ps Vx,Hx,Wx (F3),(ev) | vpdpwssd Vx,Hx,Wx (66),(ev) | vp4dpwssd Vdqq,Hdqq,Wdq (F2),(ev) +53: vpdpwssds Vx,Hx,Wx (66),(ev) | vp4dpwssds Vdqq,Hdqq,Wdq (F2),(ev) +54: vpopcntb/w Vx,Wx (66),(ev) +55: vpopcntd/q Vx,Wx (66),(ev) 58: vpbroadcastd Vx,Wx (66),(v) 59: vpbroadcastq Vx,Wx (66),(v) | vbroadcasti32x2 Vx,Wx (66),(evo) 5a: vbroadcasti128 Vqq,Mdq (66),(v) | vbroadcasti32x4/64x2 Vx,Wx (66),(evo) 5b: vbroadcasti32x8/64x4 Vqq,Mdq (66),(ev) -# Skip 0x5c-0x63 +# Skip 0x5c-0x61 +62: vpexpandb/w Vx,Wx (66),(ev) +63: vpcompressb/w Wx,Vx (66),(ev) 64: vpblendmd/q Vx,Hx,Wx (66),(ev) 65: vblendmps/d Vx,Hx,Wx (66),(ev) 66: vpblendmb/w Vx,Hx,Wx (66),(ev) -# Skip 0x67-0x74 +68: vp2intersectd/q Kx,Hx,Wx (F2),(ev) +# Skip 0x69-0x6f +70: vpshldvw Vx,Hx,Wx (66),(ev) +71: vpshldvd/q Vx,Hx,Wx (66),(ev) +72: vcvtne2ps2bf16 Vx,Hx,Wx (F2),(ev) | vcvtneps2bf16 Vx,Wx (F3),(ev) | vpshrdvw Vx,Hx,Wx (66),(ev) +73: vpshrdvd/q Vx,Hx,Wx (66),(ev) 75: vpermi2b/w Vx,Hx,Wx (66),(ev) 76: vpermi2d/q Vx,Hx,Wx (66),(ev) 77: vpermi2ps/d Vx,Hx,Wx (66),(ev) @@ -727,6 +739,7 @@ AVXcode: 2 8c: vpmaskmovd/q Vx,Hx,Mx (66),(v) 8d: vpermb/w Vx,Hx,Wx (66),(ev) 8e: vpmaskmovd/q Mx,Vx,Hx (66),(v) +8f: vpshufbitqmb Kx,Hx,Wx (66),(ev) # 0x0f 0x38 0x90-0xbf (FMA) 90: vgatherdd/q Vx,Hx,Wx (66),(v) | vpgatherdd/q Vx,Wx (66),(evo) 91: vgatherqd/q Vx,Hx,Wx (66),(v) | vpgatherqd/q Vx,Wx (66),(evo) @@ -738,8 +751,8 @@ AVXcode: 2 97: vfmsubadd132ps/d Vx,Hx,Wx (66),(v) 98: vfmadd132ps/d Vx,Hx,Wx (66),(v) 99: vfmadd132ss/d Vx,Hx,Wx (66),(v),(v1) -9a: vfmsub132ps/d Vx,Hx,Wx (66),(v) -9b: vfmsub132ss/d Vx,Hx,Wx (66),(v),(v1) +9a: vfmsub132ps/d Vx,Hx,Wx (66),(v) | v4fmaddps Vdqq,Hdqq,Wdq (F2),(ev) +9b: vfmsub132ss/d Vx,Hx,Wx (66),(v),(v1) | v4fmaddss Vdq,Hdq,Wdq (F2),(ev) 9c: vfnmadd132ps/d Vx,Hx,Wx (66),(v) 9d: vfnmadd132ss/d Vx,Hx,Wx (66),(v),(v1) 9e: vfnmsub132ps/d Vx,Hx,Wx (66),(v) @@ -752,8 +765,8 @@ a6: vfmaddsub213ps/d Vx,Hx,Wx (66),(v) a7: vfmsubadd213ps/d Vx,Hx,Wx (66),(v) a8: vfmadd213ps/d Vx,Hx,Wx (66),(v) a9: vfmadd213ss/d Vx,Hx,Wx (66),(v),(v1) -aa: vfmsub213ps/d Vx,Hx,Wx (66),(v) -ab: vfmsub213ss/d Vx,Hx,Wx (66),(v),(v1) +aa: vfmsub213ps/d Vx,Hx,Wx (66),(v) | v4fnmaddps Vdqq,Hdqq,Wdq (F2),(ev) +ab: vfmsub213ss/d Vx,Hx,Wx (66),(v),(v1) | v4fnmaddss Vdq,Hdq,Wdq (F2),(ev) ac: vfnmadd213ps/d Vx,Hx,Wx (66),(v) ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1) ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v) @@ -780,11 +793,12 @@ ca: sha1msg2 Vdq,Wdq | vrcp28ps/d Vx,Wx (66),(ev) cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev) cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev) cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev) +cf: vgf2p8mulb Vx,Wx (66) db: VAESIMC Vdq,Wdq (66),(v1) -dc: VAESENC Vdq,Hdq,Wdq (66),(v1) -dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1) -de: VAESDEC Vdq,Hdq,Wdq (66),(v1) -df: VAESDECLAST Vdq,Hdq,Wdq (66),(v1) +dc: vaesenc Vx,Hx,Wx (66) +dd: vaesenclast Vx,Hx,Wx (66) +de: vaesdec Vx,Hx,Wx (66) +df: vaesdeclast Vx,Hx,Wx (66) f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | CRC32 Gd,Eb (66&F2) f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | CRC32 Gd,Ew (66&F2) f2: ANDN Gy,By,Ey (v) @@ -848,7 +862,7 @@ AVXcode: 3 41: vdppd Vdq,Hdq,Wdq,Ib (66),(v1) 42: vmpsadbw Vx,Hx,Wx,Ib (66),(v1) | vdbpsadbw Vx,Hx,Wx,Ib (66),(evo) 43: vshufi32x4/64x2 Vx,Hx,Wx,Ib (66),(ev) -44: vpclmulqdq Vdq,Hdq,Wdq,Ib (66),(v1) +44: vpclmulqdq Vx,Hx,Wx,Ib (66) 46: vperm2i128 Vqq,Hqq,Wqq,Ib (66),(v) 4a: vblendvps Vx,Hx,Wx,Lx (66),(v) 4b: vblendvpd Vx,Hx,Wx,Lx (66),(v) @@ -865,7 +879,13 @@ AVXcode: 3 63: vpcmpistri Vdq,Wdq,Ib (66),(v1) 66: vfpclassps/d Vk,Wx,Ib (66),(ev) 67: vfpclassss/d Vk,Wx,Ib (66),(ev) +70: vpshldw Vx,Hx,Wx,Ib (66),(ev) +71: vpshldd/q Vx,Hx,Wx,Ib (66),(ev) +72: vpshrdw Vx,Hx,Wx,Ib (66),(ev) +73: vpshrdd/q Vx,Hx,Wx,Ib (66),(ev) cc: sha1rnds4 Vdq,Wdq,Ib +ce: vgf2p8affineqb Vx,Wx,Ib (66) +cf: vgf2p8affineinvqb Vx,Wx,Ib (66) df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1) f0: RORX Gy,Ey,Ib (F2),(v) EndTable diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature index 8a19753cc26a..574c2e0b9d20 100644 --- a/tools/build/Makefile.feature +++ b/tools/build/Makefile.feature @@ -96,7 +96,8 @@ FEATURE_TESTS_EXTRA := \ cxx \ llvm \ llvm-version \ - clang + clang \ + libbpf FEATURE_TESTS ?= $(FEATURE_TESTS_BASIC) diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile index 8499385365c0..f30a89046aa3 100644 --- a/tools/build/feature/Makefile +++ b/tools/build/feature/Makefile @@ -53,6 +53,7 @@ FILES= \ test-zlib.bin \ test-lzma.bin \ test-bpf.bin \ + test-libbpf.bin \ test-get_cpuid.bin \ test-sdt.bin \ test-cxx.bin \ @@ -270,6 +271,9 @@ $(OUTPUT)test-get_cpuid.bin: $(OUTPUT)test-bpf.bin: $(BUILD) +$(OUTPUT)test-libbpf.bin: + $(BUILD) -lbpf + $(OUTPUT)test-sdt.bin: $(BUILD) diff --git a/tools/build/feature/test-libbpf.c b/tools/build/feature/test-libbpf.c new file mode 100644 index 000000000000..a508756cf4cc --- /dev/null +++ b/tools/build/feature/test-libbpf.c @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <bpf/libbpf.h> + +int main(void) +{ + return bpf_object__open("test") ? 0 : -1; +} diff --git a/tools/hv/vmbus_testing b/tools/hv/vmbus_testing new file mode 100755 index 000000000000..e7212903dd1d --- /dev/null +++ b/tools/hv/vmbus_testing @@ -0,0 +1,376 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 +# +# Program to allow users to fuzz test Hyper-V drivers +# by interfacing with Hyper-V debugfs attributes. +# Current test methods available: +# 1. delay testing +# +# Current file/directory structure of hyper-V debugfs: +# /sys/kernel/debug/hyperv/UUID +# /sys/kernel/debug/hyperv/UUID/<test-state filename> +# /sys/kernel/debug/hyperv/UUID/<test-method sub-directory> +# +# author: Branden Bonaby <brandonbonaby94@gmail.com> + +import os +import cmd +import argparse +import glob +from argparse import RawDescriptionHelpFormatter +from argparse import RawTextHelpFormatter +from enum import Enum + +# Do not change unless, you change the debugfs attributes +# in /drivers/hv/debugfs.c. All fuzz testing +# attributes will start with "fuzz_test". + +# debugfs path for hyperv must exist before proceeding +debugfs_hyperv_path = "/sys/kernel/debug/hyperv" +if not os.path.isdir(debugfs_hyperv_path): + print("{} doesn't exist/check permissions".format(debugfs_hyperv_path)) + exit(-1) + +class dev_state(Enum): + off = 0 + on = 1 + +# File names, that correspond to the files created in +# /drivers/hv/debugfs.c +class f_names(Enum): + state_f = "fuzz_test_state" + buff_f = "fuzz_test_buffer_interrupt_delay" + mess_f = "fuzz_test_message_delay" + +# Both single_actions and all_actions are used +# for error checking and to allow for some subparser +# names to be abbreviated. Do not abbreviate the +# test method names, as it will become less intuitive +# as to what the user can do. If you do decide to +# abbreviate the test method name, make sure the main +# function reflects this change. + +all_actions = [ + "disable_all", + "D", + "enable_all", + "view_all", + "V" +] + +single_actions = [ + "disable_single", + "d", + "enable_single", + "view_single", + "v" +] + +def main(): + + file_map = recursive_file_lookup(debugfs_hyperv_path, dict()) + args = parse_args() + if (not args.action): + print ("Error, no options selected...exiting") + exit(-1) + arg_set = { k for (k,v) in vars(args).items() if v and k != "action" } + arg_set.add(args.action) + path = args.path if "path" in arg_set else None + if (path and path[-1] == "/"): + path = path[:-1] + validate_args_path(path, arg_set, file_map) + if (path and "enable_single" in arg_set): + state_path = locate_state(path, file_map) + set_test_state(state_path, dev_state.on.value, args.quiet) + + # Use subparsers as the key for different actions + if ("delay" in arg_set): + validate_delay_values(args.delay_time) + if (args.enable_all): + set_delay_all_devices(file_map, args.delay_time, + args.quiet) + else: + set_delay_values(path, file_map, args.delay_time, + args.quiet) + elif ("disable_all" in arg_set or "D" in arg_set): + disable_all_testing(file_map) + elif ("disable_single" in arg_set or "d" in arg_set): + disable_testing_single_device(path, file_map) + elif ("view_all" in arg_set or "V" in arg_set): + get_all_devices_test_status(file_map) + elif ("view_single" in arg_set or "v" in arg_set): + get_device_test_values(path, file_map) + +# Get the state location +def locate_state(device, file_map): + return file_map[device][f_names.state_f.value] + +# Validate delay values to make sure they are acceptable to +# enable delays on a device +def validate_delay_values(delay): + + if (delay[0] == -1 and delay[1] == -1): + print("\nError, At least 1 value must be greater than 0") + exit(-1) + for i in delay: + if (i < -1 or i == 0 or i > 1000): + print("\nError, Values must be equal to -1 " + "or be > 0 and <= 1000") + exit(-1) + +# Validate argument path +def validate_args_path(path, arg_set, file_map): + + if (not path and any(element in arg_set for element in single_actions)): + print("Error, path (-p) REQUIRED for the specified option. " + "Use (-h) to check usage.") + exit(-1) + elif (path and any(item in arg_set for item in all_actions)): + print("Error, path (-p) NOT REQUIRED for the specified option. " + "Use (-h) to check usage." ) + exit(-1) + elif (path not in file_map and any(item in arg_set + for item in single_actions)): + print("Error, path '{}' not a valid vmbus device".format(path)) + exit(-1) + +# display Testing status of single device +def get_device_test_values(path, file_map): + + for name in file_map[path]: + file_location = file_map[path][name] + print( name + " = " + str(read_test_files(file_location))) + +# Create a map of the vmbus devices and their associated files +# [key=device, value = [key = filename, value = file path]] +def recursive_file_lookup(path, file_map): + + for f_path in glob.iglob(path + '**/*'): + if (os.path.isfile(f_path)): + if (f_path.rsplit("/",2)[0] == debugfs_hyperv_path): + directory = f_path.rsplit("/",1)[0] + else: + directory = f_path.rsplit("/",2)[0] + f_name = f_path.split("/")[-1] + if (file_map.get(directory)): + file_map[directory].update({f_name:f_path}) + else: + file_map[directory] = {f_name:f_path} + elif (os.path.isdir(f_path)): + recursive_file_lookup(f_path,file_map) + return file_map + +# display Testing state of devices +def get_all_devices_test_status(file_map): + + for device in file_map: + if (get_test_state(locate_state(device, file_map)) is 1): + print("Testing = ON for: {}" + .format(device.split("/")[5])) + else: + print("Testing = OFF for: {}" + .format(device.split("/")[5])) + +# read the vmbus device files, path must be absolute path before calling +def read_test_files(path): + try: + with open(path,"r") as f: + file_value = f.readline().strip() + return int(file_value) + + except IOError as e: + errno, strerror = e.args + print("I/O error({0}): {1} on file {2}" + .format(errno, strerror, path)) + exit(-1) + except ValueError: + print ("Element to int conversion error in: \n{}".format(path)) + exit(-1) + +# writing to vmbus device files, path must be absolute path before calling +def write_test_files(path, value): + + try: + with open(path,"w") as f: + f.write("{}".format(value)) + except IOError as e: + errno, strerror = e.args + print("I/O error({0}): {1} on file {2}" + .format(errno, strerror, path)) + exit(-1) + +# set testing state of device +def set_test_state(state_path, state_value, quiet): + + write_test_files(state_path, state_value) + if (get_test_state(state_path) is 1): + if (not quiet): + print("Testing = ON for device: {}" + .format(state_path.split("/")[5])) + else: + if (not quiet): + print("Testing = OFF for device: {}" + .format(state_path.split("/")[5])) + +# get testing state of device +def get_test_state(state_path): + #state == 1 - test = ON + #state == 0 - test = OFF + return read_test_files(state_path) + +# write 1 - 1000 microseconds, into a single device using the +# fuzz_test_buffer_interrupt_delay and fuzz_test_message_delay +# debugfs attributes +def set_delay_values(device, file_map, delay_length, quiet): + + try: + interrupt = file_map[device][f_names.buff_f.value] + message = file_map[device][f_names.mess_f.value] + + # delay[0]- buffer interrupt delay, delay[1]- message delay + if (delay_length[0] >= 0 and delay_length[0] <= 1000): + write_test_files(interrupt, delay_length[0]) + if (delay_length[1] >= 0 and delay_length[1] <= 1000): + write_test_files(message, delay_length[1]) + if (not quiet): + print("Buffer delay testing = {} for: {}" + .format(read_test_files(interrupt), + interrupt.split("/")[5])) + print("Message delay testing = {} for: {}" + .format(read_test_files(message), + message.split("/")[5])) + except IOError as e: + errno, strerror = e.args + print("I/O error({0}): {1} on files {2}{3}" + .format(errno, strerror, interrupt, message)) + exit(-1) + +# enabling delay testing on all devices +def set_delay_all_devices(file_map, delay, quiet): + + for device in (file_map): + set_test_state(locate_state(device, file_map), + dev_state.on.value, + quiet) + set_delay_values(device, file_map, delay, quiet) + +# disable all testing on a SINGLE device. +def disable_testing_single_device(device, file_map): + + for name in file_map[device]: + file_location = file_map[device][name] + write_test_files(file_location, dev_state.off.value) + print("ALL testing now OFF for {}".format(device.split("/")[-1])) + +# disable all testing on ALL devices +def disable_all_testing(file_map): + + for device in file_map: + disable_testing_single_device(device, file_map) + +def parse_args(): + parser = argparse.ArgumentParser(prog = "vmbus_testing",usage ="\n" + "%(prog)s [delay] [-h] [-e|-E] -t [-p]\n" + "%(prog)s [view_all | V] [-h]\n" + "%(prog)s [disable_all | D] [-h]\n" + "%(prog)s [disable_single | d] [-h|-p]\n" + "%(prog)s [view_single | v] [-h|-p]\n" + "%(prog)s --version\n", + description = "\nUse lsvmbus to get vmbus device type " + "information.\n" "\nThe debugfs root path is " + "/sys/kernel/debug/hyperv", + formatter_class = RawDescriptionHelpFormatter) + subparsers = parser.add_subparsers(dest = "action") + parser.add_argument("--version", action = "version", + version = '%(prog)s 0.1.0') + parser.add_argument("-q","--quiet", action = "store_true", + help = "silence none important test messages." + " This will only work when enabling testing" + " on a device.") + # Use the path parser to hold the --path attribute so it can + # be shared between subparsers. Also do the same for the state + # parser, as all testing methods will use --enable_all and + # enable_single. + path_parser = argparse.ArgumentParser(add_help=False) + path_parser.add_argument("-p","--path", metavar = "", + help = "Debugfs path to a vmbus device. The path " + "must be the absolute path to the device.") + state_parser = argparse.ArgumentParser(add_help=False) + state_group = state_parser.add_mutually_exclusive_group(required = True) + state_group.add_argument("-E", "--enable_all", action = "store_const", + const = "enable_all", + help = "Enable the specified test type " + "on ALL vmbus devices.") + state_group.add_argument("-e", "--enable_single", + action = "store_const", + const = "enable_single", + help = "Enable the specified test type on a " + "SINGLE vmbus device.") + parser_delay = subparsers.add_parser("delay", + parents = [state_parser, path_parser], + help = "Delay the ring buffer interrupt or the " + "ring buffer message reads in microseconds.", + prog = "vmbus_testing", + usage = "%(prog)s [-h]\n" + "%(prog)s -E -t [value] [value]\n" + "%(prog)s -e -t [value] [value] -p", + description = "Delay the ring buffer interrupt for " + "vmbus devices, or delay the ring buffer message " + "reads for vmbus devices (both in microseconds). This " + "is only on the host to guest channel.") + parser_delay.add_argument("-t", "--delay_time", metavar = "", nargs = 2, + type = check_range, default =[0,0], required = (True), + help = "Set [buffer] & [message] delay time. " + "Value constraints: -1 == value " + "or 0 < value <= 1000.\n" + "Use -1 to keep the previous value for that delay " + "type, or a value > 0 <= 1000 to change the delay " + "time.") + parser_dis_all = subparsers.add_parser("disable_all", + aliases = ['D'], prog = "vmbus_testing", + usage = "%(prog)s [disable_all | D] -h\n" + "%(prog)s [disable_all | D]\n", + help = "Disable ALL testing on ALL vmbus devices.", + description = "Disable ALL testing on ALL vmbus " + "devices.") + parser_dis_single = subparsers.add_parser("disable_single", + aliases = ['d'], + parents = [path_parser], prog = "vmbus_testing", + usage = "%(prog)s [disable_single | d] -h\n" + "%(prog)s [disable_single | d] -p\n", + help = "Disable ALL testing on a SINGLE vmbus device.", + description = "Disable ALL testing on a SINGLE vmbus " + "device.") + parser_view_all = subparsers.add_parser("view_all", aliases = ['V'], + help = "View the test state for ALL vmbus devices.", + prog = "vmbus_testing", + usage = "%(prog)s [view_all | V] -h\n" + "%(prog)s [view_all | V]\n", + description = "This shows the test state for ALL the " + "vmbus devices.") + parser_view_single = subparsers.add_parser("view_single", + aliases = ['v'],parents = [path_parser], + help = "View the test values for a SINGLE vmbus " + "device.", + description = "This shows the test values for a SINGLE " + "vmbus device.", prog = "vmbus_testing", + usage = "%(prog)s [view_single | v] -h\n" + "%(prog)s [view_single | v] -p") + + return parser.parse_args() + +# value checking for range checking input in parser +def check_range(arg1): + + try: + val = int(arg1) + except ValueError as err: + raise argparse.ArgumentTypeError(str(err)) + if val < -1 or val > 1000: + message = ("\n\nvalue must be -1 or 0 < value <= 1000. " + "Value program received: {}\n").format(val) + raise argparse.ArgumentTypeError(message) + return val + +if __name__ == "__main__": + main() diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index 1783427da9b0..c90f4146e5a2 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -483,6 +483,16 @@ ifndef NO_LIBELF ifeq ($(feature-bpf), 1) CFLAGS += -DHAVE_LIBBPF_SUPPORT $(call detected,CONFIG_LIBBPF) + + # detecting libbpf without LIBBPF_DYNAMIC, so make VF=1 shows libbpf detection status + $(call feature_check,libbpf) + ifdef LIBBPF_DYNAMIC + ifeq ($(feature-libbpf), 1) + EXTLIBS += -lbpf + else + dummy := $(error Error: No libbpf devel library found, please install libbpf-devel); + endif + endif endif ifndef NO_DWARF diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 1cd294468a1f..eae5d5e95952 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -116,6 +116,8 @@ include ../scripts/utilities.mak # # Define TCMALLOC to enable tcmalloc heap profiling. # +# Define LIBBPF_DYNAMIC to enable libbpf dynamic linking. +# # As per kernel Makefile, avoid funny character set dependencies unexport LC_ALL @@ -360,7 +362,9 @@ export PERL_PATH PERFLIBS = $(LIBAPI) $(LIBTRACEEVENT) $(LIBSUBCMD) $(LIBPERF) ifndef NO_LIBBPF - PERFLIBS += $(LIBBPF) + ifndef LIBBPF_DYNAMIC + PERFLIBS += $(LIBBPF) + endif endif # We choose to avoid "if .. else if .. else .. endif endif" diff --git a/tools/perf/arch/arm/tests/dwarf-unwind.c b/tools/perf/arch/arm/tests/dwarf-unwind.c index 2c35e532bc9a..ccfa87055c4a 100644 --- a/tools/perf/arch/arm/tests/dwarf-unwind.c +++ b/tools/perf/arch/arm/tests/dwarf-unwind.c @@ -3,7 +3,7 @@ #include "perf_regs.h" #include "thread.h" #include "map.h" -#include "map_groups.h" +#include "maps.h" #include "event.h" #include "debug.h" #include "tests/tests.h" @@ -26,7 +26,7 @@ static int sample_ustack(struct perf_sample *sample, sp = (unsigned long) regs[PERF_REG_ARM_SP]; - map = map_groups__find(thread->mg, (u64)sp); + map = maps__find(thread->maps, (u64)sp); if (!map) { pr_debug("failed to get stack map\n"); free(buf); diff --git a/tools/perf/arch/arm64/tests/dwarf-unwind.c b/tools/perf/arch/arm64/tests/dwarf-unwind.c index a6a407fa1b8b..46147a483049 100644 --- a/tools/perf/arch/arm64/tests/dwarf-unwind.c +++ b/tools/perf/arch/arm64/tests/dwarf-unwind.c @@ -3,7 +3,7 @@ #include "perf_regs.h" #include "thread.h" #include "map.h" -#include "map_groups.h" +#include "maps.h" #include "event.h" #include "debug.h" #include "tests/tests.h" @@ -26,7 +26,7 @@ static int sample_ustack(struct perf_sample *sample, sp = (unsigned long) regs[PERF_REG_ARM64_SP]; - map = map_groups__find(thread->mg, (u64)sp); + map = maps__find(thread->maps, (u64)sp); if (!map) { pr_debug("failed to get stack map\n"); free(buf); diff --git a/tools/perf/arch/powerpc/tests/dwarf-unwind.c b/tools/perf/arch/powerpc/tests/dwarf-unwind.c index 5c178e4a1995..8efd9ed9e9db 100644 --- a/tools/perf/arch/powerpc/tests/dwarf-unwind.c +++ b/tools/perf/arch/powerpc/tests/dwarf-unwind.c @@ -3,7 +3,7 @@ #include "perf_regs.h" #include "thread.h" #include "map.h" -#include "map_groups.h" +#include "maps.h" #include "event.h" #include "debug.h" #include "tests/tests.h" @@ -27,7 +27,7 @@ static int sample_ustack(struct perf_sample *sample, sp = (unsigned long) regs[PERF_REG_POWERPC_R1]; - map = map_groups__find(thread->mg, (u64)sp); + map = maps__find(thread->maps, (u64)sp); if (!map) { pr_debug("failed to get stack map\n"); free(buf); diff --git a/tools/perf/arch/s390/annotate/instructions.c b/tools/perf/arch/s390/annotate/instructions.c index 2a6662e42f89..0e136630659e 100644 --- a/tools/perf/arch/s390/annotate/instructions.c +++ b/tools/perf/arch/s390/annotate/instructions.c @@ -38,7 +38,7 @@ static int s390_call__parse(struct arch *arch, struct ins_operands *ops, return -1; target.addr = map__objdump_2mem(map, ops->target.addr); - if (map_groups__find_ams(ms->mg, &target) == 0 && + if (maps__find_ams(ms->maps, &target) == 0 && map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr) ops->target.sym = target.ms.sym; diff --git a/tools/perf/arch/x86/tests/dwarf-unwind.c b/tools/perf/arch/x86/tests/dwarf-unwind.c index 6ad0a1cedb13..ef43be9b6ec2 100644 --- a/tools/perf/arch/x86/tests/dwarf-unwind.c +++ b/tools/perf/arch/x86/tests/dwarf-unwind.c @@ -3,7 +3,7 @@ #include "perf_regs.h" #include "thread.h" #include "map.h" -#include "map_groups.h" +#include "maps.h" #include "event.h" #include "debug.h" #include "tests/tests.h" @@ -27,7 +27,7 @@ static int sample_ustack(struct perf_sample *sample, sp = (unsigned long) regs[PERF_REG_X86_SP]; - map = map_groups__find(thread->mg, (u64)sp); + map = maps__find(thread->maps, (u64)sp); if (!map) { pr_debug("failed to get stack map\n"); free(buf); diff --git a/tools/perf/arch/x86/tests/insn-x86-dat-32.c b/tools/perf/arch/x86/tests/insn-x86-dat-32.c index 58f8f2a095c4..e6461abc9e7b 100644 --- a/tools/perf/arch/x86/tests/insn-x86-dat-32.c +++ b/tools/perf/arch/x86/tests/insn-x86-dat-32.c @@ -667,6 +667,86 @@ "62 f2 55 0f 4f f4 \tvrsqrt14ss %xmm4,%xmm5,%xmm6{%k7}",}, {{0x62, 0xf2, 0xd5, 0x0f, 0x4f, 0xf4, }, 6, 0, "", "", "62 f2 d5 0f 4f f4 \tvrsqrt14sd %xmm4,%xmm5,%xmm6{%k7}",}, +{{0x62, 0xf2, 0x6d, 0x08, 0x50, 0xd9, }, 6, 0, "", "", +"62 f2 6d 08 50 d9 \tvpdpbusd %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0x6d, 0x28, 0x50, 0xd9, }, 6, 0, "", "", +"62 f2 6d 28 50 d9 \tvpdpbusd %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x50, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 50 d9 \tvpdpbusd %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x50, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 50 9c c8 78 56 34 12 \tvpdpbusd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x08, 0x51, 0xd9, }, 6, 0, "", "", +"62 f2 6d 08 51 d9 \tvpdpbusds %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0x6d, 0x28, 0x51, 0xd9, }, 6, 0, "", "", +"62 f2 6d 28 51 d9 \tvpdpbusds %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x51, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 51 d9 \tvpdpbusds %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x51, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 51 9c c8 78 56 34 12 \tvpdpbusds 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6e, 0x08, 0x52, 0xd9, }, 6, 0, "", "", +"62 f2 6e 08 52 d9 \tvdpbf16ps %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0x6e, 0x28, 0x52, 0xd9, }, 6, 0, "", "", +"62 f2 6e 28 52 d9 \tvdpbf16ps %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6e, 0x48, 0x52, 0xd9, }, 6, 0, "", "", +"62 f2 6e 48 52 d9 \tvdpbf16ps %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6e, 0x48, 0x52, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6e 48 52 9c c8 78 56 34 12 \tvdpbf16ps 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x08, 0x52, 0xd9, }, 6, 0, "", "", +"62 f2 6d 08 52 d9 \tvpdpwssd %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0x6d, 0x28, 0x52, 0xd9, }, 6, 0, "", "", +"62 f2 6d 28 52 d9 \tvpdpwssd %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x52, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 52 d9 \tvpdpwssd %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x52, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 52 9c c8 78 56 34 12 \tvpdpwssd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x7f, 0x48, 0x52, 0x20, }, 6, 0, "", "", +"62 f2 7f 48 52 20 \tvp4dpwssd (%eax),%zmm0,%zmm4",}, +{{0x62, 0xf2, 0x7f, 0x48, 0x52, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 7f 48 52 a4 c8 78 56 34 12 \tvp4dpwssd 0x12345678(%eax,%ecx,8),%zmm0,%zmm4",}, +{{0x62, 0xf2, 0x6d, 0x08, 0x53, 0xd9, }, 6, 0, "", "", +"62 f2 6d 08 53 d9 \tvpdpwssds %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0x6d, 0x28, 0x53, 0xd9, }, 6, 0, "", "", +"62 f2 6d 28 53 d9 \tvpdpwssds %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x53, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 53 d9 \tvpdpwssds %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x53, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 53 9c c8 78 56 34 12 \tvpdpwssds 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x7f, 0x48, 0x53, 0x20, }, 6, 0, "", "", +"62 f2 7f 48 53 20 \tvp4dpwssds (%eax),%zmm0,%zmm4",}, +{{0x62, 0xf2, 0x7f, 0x48, 0x53, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 7f 48 53 a4 c8 78 56 34 12 \tvp4dpwssds 0x12345678(%eax,%ecx,8),%zmm0,%zmm4",}, +{{0x62, 0xf2, 0x7d, 0x08, 0x54, 0xd1, }, 6, 0, "", "", +"62 f2 7d 08 54 d1 \tvpopcntb %xmm1,%xmm2",}, +{{0x62, 0xf2, 0x7d, 0x28, 0x54, 0xd1, }, 6, 0, "", "", +"62 f2 7d 28 54 d1 \tvpopcntb %ymm1,%ymm2",}, +{{0x62, 0xf2, 0x7d, 0x48, 0x54, 0xd1, }, 6, 0, "", "", +"62 f2 7d 48 54 d1 \tvpopcntb %zmm1,%zmm2",}, +{{0x62, 0xf2, 0x7d, 0x48, 0x54, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 7d 48 54 94 c8 78 56 34 12 \tvpopcntb 0x12345678(%eax,%ecx,8),%zmm2",}, +{{0x62, 0xf2, 0xfd, 0x08, 0x54, 0xd1, }, 6, 0, "", "", +"62 f2 fd 08 54 d1 \tvpopcntw %xmm1,%xmm2",}, +{{0x62, 0xf2, 0xfd, 0x28, 0x54, 0xd1, }, 6, 0, "", "", +"62 f2 fd 28 54 d1 \tvpopcntw %ymm1,%ymm2",}, +{{0x62, 0xf2, 0xfd, 0x48, 0x54, 0xd1, }, 6, 0, "", "", +"62 f2 fd 48 54 d1 \tvpopcntw %zmm1,%zmm2",}, +{{0x62, 0xf2, 0xfd, 0x48, 0x54, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 fd 48 54 94 c8 78 56 34 12 \tvpopcntw 0x12345678(%eax,%ecx,8),%zmm2",}, +{{0x62, 0xf2, 0x7d, 0x08, 0x55, 0xd1, }, 6, 0, "", "", +"62 f2 7d 08 55 d1 \tvpopcntd %xmm1,%xmm2",}, +{{0x62, 0xf2, 0x7d, 0x28, 0x55, 0xd1, }, 6, 0, "", "", +"62 f2 7d 28 55 d1 \tvpopcntd %ymm1,%ymm2",}, +{{0x62, 0xf2, 0x7d, 0x48, 0x55, 0xd1, }, 6, 0, "", "", +"62 f2 7d 48 55 d1 \tvpopcntd %zmm1,%zmm2",}, +{{0x62, 0xf2, 0x7d, 0x48, 0x55, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 7d 48 55 94 c8 78 56 34 12 \tvpopcntd 0x12345678(%eax,%ecx,8),%zmm2",}, +{{0x62, 0xf2, 0xfd, 0x08, 0x55, 0xd1, }, 6, 0, "", "", +"62 f2 fd 08 55 d1 \tvpopcntq %xmm1,%xmm2",}, +{{0x62, 0xf2, 0xfd, 0x28, 0x55, 0xd1, }, 6, 0, "", "", +"62 f2 fd 28 55 d1 \tvpopcntq %ymm1,%ymm2",}, +{{0x62, 0xf2, 0xfd, 0x48, 0x55, 0xd1, }, 6, 0, "", "", +"62 f2 fd 48 55 d1 \tvpopcntq %zmm1,%zmm2",}, +{{0x62, 0xf2, 0xfd, 0x48, 0x55, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 fd 48 55 94 c8 78 56 34 12 \tvpopcntq 0x12345678(%eax,%ecx,8),%zmm2",}, {{0xc4, 0xe2, 0x79, 0x59, 0xf4, }, 5, 0, "", "", "c4 e2 79 59 f4 \tvpbroadcastq %xmm4,%xmm6",}, {{0x62, 0xf2, 0x7d, 0x48, 0x59, 0xf7, }, 6, 0, "", "", @@ -681,6 +761,38 @@ "62 f2 7d 48 5b 31 \tvbroadcasti32x8 (%ecx),%zmm6",}, {{0x62, 0xf2, 0xfd, 0x48, 0x5b, 0x31, }, 6, 0, "", "", "62 f2 fd 48 5b 31 \tvbroadcasti64x4 (%ecx),%zmm6",}, +{{0x62, 0xf2, 0x7d, 0x08, 0x62, 0xd1, }, 6, 0, "", "", +"62 f2 7d 08 62 d1 \tvpexpandb %xmm1,%xmm2",}, +{{0x62, 0xf2, 0x7d, 0x28, 0x62, 0xd1, }, 6, 0, "", "", +"62 f2 7d 28 62 d1 \tvpexpandb %ymm1,%ymm2",}, +{{0x62, 0xf2, 0x7d, 0x48, 0x62, 0xd1, }, 6, 0, "", "", +"62 f2 7d 48 62 d1 \tvpexpandb %zmm1,%zmm2",}, +{{0x62, 0xf2, 0x7d, 0x48, 0x62, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 7d 48 62 94 c8 78 56 34 12 \tvpexpandb 0x12345678(%eax,%ecx,8),%zmm2",}, +{{0x62, 0xf2, 0xfd, 0x08, 0x62, 0xd1, }, 6, 0, "", "", +"62 f2 fd 08 62 d1 \tvpexpandw %xmm1,%xmm2",}, +{{0x62, 0xf2, 0xfd, 0x28, 0x62, 0xd1, }, 6, 0, "", "", +"62 f2 fd 28 62 d1 \tvpexpandw %ymm1,%ymm2",}, +{{0x62, 0xf2, 0xfd, 0x48, 0x62, 0xd1, }, 6, 0, "", "", +"62 f2 fd 48 62 d1 \tvpexpandw %zmm1,%zmm2",}, +{{0x62, 0xf2, 0xfd, 0x48, 0x62, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 fd 48 62 94 c8 78 56 34 12 \tvpexpandw 0x12345678(%eax,%ecx,8),%zmm2",}, +{{0x62, 0xf2, 0x7d, 0x08, 0x63, 0xca, }, 6, 0, "", "", +"62 f2 7d 08 63 ca \tvpcompressb %xmm1,%xmm2",}, +{{0x62, 0xf2, 0x7d, 0x28, 0x63, 0xca, }, 6, 0, "", "", +"62 f2 7d 28 63 ca \tvpcompressb %ymm1,%ymm2",}, +{{0x62, 0xf2, 0x7d, 0x48, 0x63, 0xca, }, 6, 0, "", "", +"62 f2 7d 48 63 ca \tvpcompressb %zmm1,%zmm2",}, +{{0x62, 0xf2, 0x7d, 0x48, 0x63, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 7d 48 63 94 c8 78 56 34 12 \tvpcompressb %zmm2,0x12345678(%eax,%ecx,8)",}, +{{0x62, 0xf2, 0xfd, 0x08, 0x63, 0xca, }, 6, 0, "", "", +"62 f2 fd 08 63 ca \tvpcompressw %xmm1,%xmm2",}, +{{0x62, 0xf2, 0xfd, 0x28, 0x63, 0xca, }, 6, 0, "", "", +"62 f2 fd 28 63 ca \tvpcompressw %ymm1,%ymm2",}, +{{0x62, 0xf2, 0xfd, 0x48, 0x63, 0xca, }, 6, 0, "", "", +"62 f2 fd 48 63 ca \tvpcompressw %zmm1,%zmm2",}, +{{0x62, 0xf2, 0xfd, 0x48, 0x63, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 fd 48 63 94 c8 78 56 34 12 \tvpcompressw %zmm2,0x12345678(%eax,%ecx,8)",}, {{0x62, 0xf2, 0x55, 0x48, 0x64, 0xf4, }, 6, 0, "", "", "62 f2 55 48 64 f4 \tvpblendmd %zmm4,%zmm5,%zmm6",}, {{0x62, 0xf2, 0xd5, 0x48, 0x64, 0xf4, }, 6, 0, "", "", @@ -693,6 +805,86 @@ "62 f2 55 48 66 f4 \tvpblendmb %zmm4,%zmm5,%zmm6",}, {{0x62, 0xf2, 0xd5, 0x48, 0x66, 0xf4, }, 6, 0, "", "", "62 f2 d5 48 66 f4 \tvpblendmw %zmm4,%zmm5,%zmm6",}, +{{0x62, 0xf2, 0x6f, 0x08, 0x68, 0xd9, }, 6, 0, "", "", +"62 f2 6f 08 68 d9 \tvp2intersectd %xmm1,%xmm2,%k3",}, +{{0x62, 0xf2, 0x6f, 0x28, 0x68, 0xd9, }, 6, 0, "", "", +"62 f2 6f 28 68 d9 \tvp2intersectd %ymm1,%ymm2,%k3",}, +{{0x62, 0xf2, 0x6f, 0x48, 0x68, 0xd9, }, 6, 0, "", "", +"62 f2 6f 48 68 d9 \tvp2intersectd %zmm1,%zmm2,%k3",}, +{{0x62, 0xf2, 0x6f, 0x48, 0x68, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6f 48 68 9c c8 78 56 34 12 \tvp2intersectd 0x12345678(%eax,%ecx,8),%zmm2,%k3",}, +{{0x62, 0xf2, 0xef, 0x08, 0x68, 0xd9, }, 6, 0, "", "", +"62 f2 ef 08 68 d9 \tvp2intersectq %xmm1,%xmm2,%k3",}, +{{0x62, 0xf2, 0xef, 0x28, 0x68, 0xd9, }, 6, 0, "", "", +"62 f2 ef 28 68 d9 \tvp2intersectq %ymm1,%ymm2,%k3",}, +{{0x62, 0xf2, 0xef, 0x48, 0x68, 0xd9, }, 6, 0, "", "", +"62 f2 ef 48 68 d9 \tvp2intersectq %zmm1,%zmm2,%k3",}, +{{0x62, 0xf2, 0xef, 0x48, 0x68, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 ef 48 68 9c c8 78 56 34 12 \tvp2intersectq 0x12345678(%eax,%ecx,8),%zmm2,%k3",}, +{{0x62, 0xf2, 0xed, 0x08, 0x70, 0xd9, }, 6, 0, "", "", +"62 f2 ed 08 70 d9 \tvpshldvw %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0xed, 0x28, 0x70, 0xd9, }, 6, 0, "", "", +"62 f2 ed 28 70 d9 \tvpshldvw %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0x70, 0xd9, }, 6, 0, "", "", +"62 f2 ed 48 70 d9 \tvpshldvw %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0x70, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 ed 48 70 9c c8 78 56 34 12 \tvpshldvw 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x08, 0x71, 0xd9, }, 6, 0, "", "", +"62 f2 6d 08 71 d9 \tvpshldvd %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0x6d, 0x28, 0x71, 0xd9, }, 6, 0, "", "", +"62 f2 6d 28 71 d9 \tvpshldvd %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x71, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 71 d9 \tvpshldvd %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x71, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 71 9c c8 78 56 34 12 \tvpshldvd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0xed, 0x08, 0x71, 0xd9, }, 6, 0, "", "", +"62 f2 ed 08 71 d9 \tvpshldvq %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0xed, 0x28, 0x71, 0xd9, }, 6, 0, "", "", +"62 f2 ed 28 71 d9 \tvpshldvq %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0x71, 0xd9, }, 6, 0, "", "", +"62 f2 ed 48 71 d9 \tvpshldvq %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0x71, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 ed 48 71 9c c8 78 56 34 12 \tvpshldvq 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6f, 0x08, 0x72, 0xd9, }, 6, 0, "", "", +"62 f2 6f 08 72 d9 \tvcvtne2ps2bf16 %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0x6f, 0x28, 0x72, 0xd9, }, 6, 0, "", "", +"62 f2 6f 28 72 d9 \tvcvtne2ps2bf16 %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6f, 0x48, 0x72, 0xd9, }, 6, 0, "", "", +"62 f2 6f 48 72 d9 \tvcvtne2ps2bf16 %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6f, 0x48, 0x72, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6f 48 72 9c c8 78 56 34 12 \tvcvtne2ps2bf16 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x7e, 0x08, 0x72, 0xd1, }, 6, 0, "", "", +"62 f2 7e 08 72 d1 \tvcvtneps2bf16 %xmm1,%xmm2",}, +{{0x62, 0xf2, 0x7e, 0x28, 0x72, 0xd1, }, 6, 0, "", "", +"62 f2 7e 28 72 d1 \tvcvtneps2bf16 %ymm1,%xmm2",}, +{{0x62, 0xf2, 0x7e, 0x48, 0x72, 0xd1, }, 6, 0, "", "", +"62 f2 7e 48 72 d1 \tvcvtneps2bf16 %zmm1,%ymm2",}, +{{0x62, 0xf2, 0x7e, 0x48, 0x72, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 7e 48 72 94 c8 78 56 34 12 \tvcvtneps2bf16 0x12345678(%eax,%ecx,8),%ymm2",}, +{{0x62, 0xf2, 0xed, 0x08, 0x72, 0xd9, }, 6, 0, "", "", +"62 f2 ed 08 72 d9 \tvpshrdvw %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0xed, 0x28, 0x72, 0xd9, }, 6, 0, "", "", +"62 f2 ed 28 72 d9 \tvpshrdvw %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0x72, 0xd9, }, 6, 0, "", "", +"62 f2 ed 48 72 d9 \tvpshrdvw %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0x72, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 ed 48 72 9c c8 78 56 34 12 \tvpshrdvw 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x08, 0x73, 0xd9, }, 6, 0, "", "", +"62 f2 6d 08 73 d9 \tvpshrdvd %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0x6d, 0x28, 0x73, 0xd9, }, 6, 0, "", "", +"62 f2 6d 28 73 d9 \tvpshrdvd %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x73, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 73 d9 \tvpshrdvd %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x73, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 73 9c c8 78 56 34 12 \tvpshrdvd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0xed, 0x08, 0x73, 0xd9, }, 6, 0, "", "", +"62 f2 ed 08 73 d9 \tvpshrdvq %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0xed, 0x28, 0x73, 0xd9, }, 6, 0, "", "", +"62 f2 ed 28 73 d9 \tvpshrdvq %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0x73, 0xd9, }, 6, 0, "", "", +"62 f2 ed 48 73 d9 \tvpshrdvq %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0x73, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 ed 48 73 9c c8 78 56 34 12 \tvpshrdvq 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, {{0x62, 0xf2, 0x55, 0x48, 0x75, 0xf4, }, 6, 0, "", "", "62 f2 55 48 75 f4 \tvpermi2b %zmm4,%zmm5,%zmm6",}, {{0x62, 0xf2, 0xd5, 0x48, 0x75, 0xf4, }, 6, 0, "", "", @@ -745,6 +937,14 @@ "62 f2 55 48 8d f4 \tvpermb %zmm4,%zmm5,%zmm6",}, {{0x62, 0xf2, 0xd5, 0x48, 0x8d, 0xf4, }, 6, 0, "", "", "62 f2 d5 48 8d f4 \tvpermw %zmm4,%zmm5,%zmm6",}, +{{0x62, 0xf2, 0x6d, 0x08, 0x8f, 0xd9, }, 6, 0, "", "", +"62 f2 6d 08 8f d9 \tvpshufbitqmb %xmm1,%xmm2,%k3",}, +{{0x62, 0xf2, 0x6d, 0x28, 0x8f, 0xd9, }, 6, 0, "", "", +"62 f2 6d 28 8f d9 \tvpshufbitqmb %ymm1,%ymm2,%k3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x8f, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 8f d9 \tvpshufbitqmb %zmm1,%zmm2,%k3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x8f, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 8f 9c c8 78 56 34 12 \tvpshufbitqmb 0x12345678(%eax,%ecx,8),%zmm2,%k3",}, {{0xc4, 0xe2, 0x69, 0x90, 0x4c, 0x7d, 0x02, }, 7, 0, "", "", "c4 e2 69 90 4c 7d 02 \tvpgatherdd %xmm2,0x2(%ebp,%xmm7,2),%xmm1",}, {{0xc4, 0xe2, 0xe9, 0x90, 0x4c, 0x7d, 0x04, }, 7, 0, "", "", @@ -761,6 +961,38 @@ "62 f2 7d 49 91 b4 fd 7b 00 00 00 \tvpgatherqd 0x7b(%ebp,%zmm7,8),%ymm6{%k1}",}, {{0x62, 0xf2, 0xfd, 0x49, 0x91, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "", "62 f2 fd 49 91 b4 fd 7b 00 00 00 \tvpgatherqq 0x7b(%ebp,%zmm7,8),%zmm6{%k1}",}, +{{0xc4, 0xe2, 0x69, 0x9a, 0xd9, }, 5, 0, "", "", +"c4 e2 69 9a d9 \tvfmsub132ps %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x6d, 0x9a, 0xd9, }, 5, 0, "", "", +"c4 e2 6d 9a d9 \tvfmsub132ps %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x9a, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 9a d9 \tvfmsub132ps %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x9a, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 9a 9c c8 78 56 34 12 \tvfmsub132ps 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0xc4, 0xe2, 0xe9, 0x9a, 0xd9, }, 5, 0, "", "", +"c4 e2 e9 9a d9 \tvfmsub132pd %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0xed, 0x9a, 0xd9, }, 5, 0, "", "", +"c4 e2 ed 9a d9 \tvfmsub132pd %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0x9a, 0xd9, }, 6, 0, "", "", +"62 f2 ed 48 9a d9 \tvfmsub132pd %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0x9a, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 ed 48 9a 9c c8 78 56 34 12 \tvfmsub132pd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x7f, 0x48, 0x9a, 0x20, }, 6, 0, "", "", +"62 f2 7f 48 9a 20 \tv4fmaddps (%eax),%zmm0,%zmm4",}, +{{0x62, 0xf2, 0x7f, 0x48, 0x9a, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 7f 48 9a a4 c8 78 56 34 12 \tv4fmaddps 0x12345678(%eax,%ecx,8),%zmm0,%zmm4",}, +{{0xc4, 0xe2, 0x69, 0x9b, 0xd9, }, 5, 0, "", "", +"c4 e2 69 9b d9 \tvfmsub132ss %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x69, 0x9b, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "", +"c4 e2 69 9b 9c c8 78 56 34 12 \tvfmsub132ss 0x12345678(%eax,%ecx,8),%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0xe9, 0x9b, 0xd9, }, 5, 0, "", "", +"c4 e2 e9 9b d9 \tvfmsub132sd %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0xe9, 0x9b, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "", +"c4 e2 e9 9b 9c c8 78 56 34 12 \tvfmsub132sd 0x12345678(%eax,%ecx,8),%xmm2,%xmm3",}, +{{0x62, 0xf2, 0x7f, 0x08, 0x9b, 0x20, }, 6, 0, "", "", +"62 f2 7f 08 9b 20 \tv4fmaddss (%eax),%xmm0,%xmm4",}, +{{0x62, 0xf2, 0x7f, 0x08, 0x9b, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 7f 08 9b a4 c8 78 56 34 12 \tv4fmaddss 0x12345678(%eax,%ecx,8),%xmm0,%xmm4",}, {{0x62, 0xf2, 0x7d, 0x49, 0xa0, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "", "62 f2 7d 49 a0 b4 fd 7b 00 00 00 \tvpscatterdd %zmm6,0x7b(%ebp,%zmm7,8){%k1}",}, {{0x62, 0xf2, 0xfd, 0x49, 0xa0, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "", @@ -777,6 +1009,38 @@ "62 f2 7d 49 a3 b4 fd 7b 00 00 00 \tvscatterqps %ymm6,0x7b(%ebp,%zmm7,8){%k1}",}, {{0x62, 0xf2, 0xfd, 0x49, 0xa3, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "", "62 f2 fd 49 a3 b4 fd 7b 00 00 00 \tvscatterqpd %zmm6,0x7b(%ebp,%zmm7,8){%k1}",}, +{{0xc4, 0xe2, 0x69, 0xaa, 0xd9, }, 5, 0, "", "", +"c4 e2 69 aa d9 \tvfmsub213ps %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x6d, 0xaa, 0xd9, }, 5, 0, "", "", +"c4 e2 6d aa d9 \tvfmsub213ps %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xaa, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 aa d9 \tvfmsub213ps %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xaa, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 aa 9c c8 78 56 34 12 \tvfmsub213ps 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0xc4, 0xe2, 0xe9, 0xaa, 0xd9, }, 5, 0, "", "", +"c4 e2 e9 aa d9 \tvfmsub213pd %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0xed, 0xaa, 0xd9, }, 5, 0, "", "", +"c4 e2 ed aa d9 \tvfmsub213pd %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0xaa, 0xd9, }, 6, 0, "", "", +"62 f2 ed 48 aa d9 \tvfmsub213pd %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0xaa, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 ed 48 aa 9c c8 78 56 34 12 \tvfmsub213pd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x7f, 0x48, 0xaa, 0x20, }, 6, 0, "", "", +"62 f2 7f 48 aa 20 \tv4fnmaddps (%eax),%zmm0,%zmm4",}, +{{0x62, 0xf2, 0x7f, 0x48, 0xaa, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 7f 48 aa a4 c8 78 56 34 12 \tv4fnmaddps 0x12345678(%eax,%ecx,8),%zmm0,%zmm4",}, +{{0xc4, 0xe2, 0x69, 0xab, 0xd9, }, 5, 0, "", "", +"c4 e2 69 ab d9 \tvfmsub213ss %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x69, 0xab, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "", +"c4 e2 69 ab 9c c8 78 56 34 12 \tvfmsub213ss 0x12345678(%eax,%ecx,8),%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0xe9, 0xab, 0xd9, }, 5, 0, "", "", +"c4 e2 e9 ab d9 \tvfmsub213sd %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0xe9, 0xab, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "", +"c4 e2 e9 ab 9c c8 78 56 34 12 \tvfmsub213sd 0x12345678(%eax,%ecx,8),%xmm2,%xmm3",}, +{{0x62, 0xf2, 0x7f, 0x08, 0xab, 0x20, }, 6, 0, "", "", +"62 f2 7f 08 ab 20 \tv4fnmaddss (%eax),%xmm0,%xmm4",}, +{{0x62, 0xf2, 0x7f, 0x08, 0xab, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 7f 08 ab a4 c8 78 56 34 12 \tv4fnmaddss 0x12345678(%eax,%ecx,8),%xmm0,%xmm4",}, {{0x62, 0xf2, 0xd5, 0x48, 0xb4, 0xf4, }, 6, 0, "", "", "62 f2 d5 48 b4 f4 \tvpmadd52luq %zmm4,%zmm5,%zmm6",}, {{0x62, 0xf2, 0xd5, 0x48, 0xb5, 0xf4, }, 6, 0, "", "", @@ -805,6 +1069,50 @@ "62 f2 4d 0f cd fd \tvrsqrt28ss %xmm5,%xmm6,%xmm7{%k7}",}, {{0x62, 0xf2, 0xcd, 0x0f, 0xcd, 0xfd, }, 6, 0, "", "", "62 f2 cd 0f cd fd \tvrsqrt28sd %xmm5,%xmm6,%xmm7{%k7}",}, +{{0x66, 0x0f, 0x38, 0xcf, 0xd9, }, 5, 0, "", "", +"66 0f 38 cf d9 \tgf2p8mulb %xmm1,%xmm3",}, +{{0x66, 0x0f, 0x38, 0xcf, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "", +"66 0f 38 cf 9c c8 78 56 34 12 \tgf2p8mulb 0x12345678(%eax,%ecx,8),%xmm3",}, +{{0xc4, 0xe2, 0x69, 0xcf, 0xd9, }, 5, 0, "", "", +"c4 e2 69 cf d9 \tvgf2p8mulb %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x6d, 0xcf, 0xd9, }, 5, 0, "", "", +"c4 e2 6d cf d9 \tvgf2p8mulb %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xcf, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 cf d9 \tvgf2p8mulb %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xcf, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 cf 9c c8 78 56 34 12 \tvgf2p8mulb 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0xc4, 0xe2, 0x69, 0xdc, 0xd9, }, 5, 0, "", "", +"c4 e2 69 dc d9 \tvaesenc %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x6d, 0xdc, 0xd9, }, 5, 0, "", "", +"c4 e2 6d dc d9 \tvaesenc %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xdc, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 dc d9 \tvaesenc %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xdc, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 dc 9c c8 78 56 34 12 \tvaesenc 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0xc4, 0xe2, 0x69, 0xdd, 0xd9, }, 5, 0, "", "", +"c4 e2 69 dd d9 \tvaesenclast %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x6d, 0xdd, 0xd9, }, 5, 0, "", "", +"c4 e2 6d dd d9 \tvaesenclast %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xdd, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 dd d9 \tvaesenclast %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xdd, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 dd 9c c8 78 56 34 12 \tvaesenclast 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0xc4, 0xe2, 0x69, 0xde, 0xd9, }, 5, 0, "", "", +"c4 e2 69 de d9 \tvaesdec %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x6d, 0xde, 0xd9, }, 5, 0, "", "", +"c4 e2 6d de d9 \tvaesdec %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xde, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 de d9 \tvaesdec %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xde, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 de 9c c8 78 56 34 12 \tvaesdec 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0xc4, 0xe2, 0x69, 0xdf, 0xd9, }, 5, 0, "", "", +"c4 e2 69 df d9 \tvaesdeclast %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x6d, 0xdf, 0xd9, }, 5, 0, "", "", +"c4 e2 6d df d9 \tvaesdeclast %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xdf, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 df d9 \tvaesdeclast %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xdf, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 df 9c c8 78 56 34 12 \tvaesdeclast 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, {{0x62, 0xf3, 0x4d, 0x48, 0x03, 0xfd, 0x12, }, 7, 0, "", "", "62 f3 4d 48 03 fd 12 \tvalignd $0x12,%zmm5,%zmm6,%zmm7",}, {{0x62, 0xf3, 0xcd, 0x48, 0x03, 0xfd, 0x12, }, 7, 0, "", "", @@ -905,6 +1213,12 @@ "62 f3 4d 48 43 fd 12 \tvshufi32x4 $0x12,%zmm5,%zmm6,%zmm7",}, {{0x62, 0xf3, 0xcd, 0x48, 0x43, 0xfd, 0x12, }, 7, 0, "", "", "62 f3 cd 48 43 fd 12 \tvshufi64x2 $0x12,%zmm5,%zmm6,%zmm7",}, +{{0xc4, 0xe3, 0x69, 0x44, 0xd9, 0x12, }, 6, 0, "", "", +"c4 e3 69 44 d9 12 \tvpclmulqdq $0x12,%xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe3, 0x6d, 0x44, 0xd9, 0x12, }, 6, 0, "", "", +"c4 e3 6d 44 d9 12 \tvpclmulqdq $0x12,%ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf3, 0x6d, 0x48, 0x44, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 6d 48 44 d9 12 \tvpclmulqdq $0x12,%zmm1,%zmm2,%zmm3",}, {{0x62, 0xf3, 0x4d, 0x48, 0x50, 0xfd, 0x12, }, 7, 0, "", "", "62 f3 4d 48 50 fd 12 \tvrangeps $0x12,%zmm5,%zmm6,%zmm7",}, {{0x62, 0xf3, 0xcd, 0x48, 0x50, 0xfd, 0x12, }, 7, 0, "", "", @@ -937,6 +1251,58 @@ "62 f3 7d 08 67 ef 12 \tvfpclassss $0x12,%xmm7,%k5",}, {{0x62, 0xf3, 0xfd, 0x08, 0x67, 0xef, 0x12, }, 7, 0, "", "", "62 f3 fd 08 67 ef 12 \tvfpclasssd $0x12,%xmm7,%k5",}, +{{0x62, 0xf3, 0xed, 0x08, 0x70, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 08 70 d9 12 \tvpshldw $0x12,%xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf3, 0xed, 0x28, 0x70, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 28 70 d9 12 \tvpshldw $0x12,%ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf3, 0xed, 0x48, 0x70, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 48 70 d9 12 \tvpshldw $0x12,%zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf3, 0x6d, 0x08, 0x71, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 6d 08 71 d9 12 \tvpshldd $0x12,%xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf3, 0x6d, 0x28, 0x71, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 6d 28 71 d9 12 \tvpshldd $0x12,%ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf3, 0x6d, 0x48, 0x71, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 6d 48 71 d9 12 \tvpshldd $0x12,%zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf3, 0xed, 0x08, 0x71, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 08 71 d9 12 \tvpshldq $0x12,%xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf3, 0xed, 0x28, 0x71, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 28 71 d9 12 \tvpshldq $0x12,%ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf3, 0xed, 0x48, 0x71, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 48 71 d9 12 \tvpshldq $0x12,%zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf3, 0xed, 0x08, 0x72, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 08 72 d9 12 \tvpshrdw $0x12,%xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf3, 0xed, 0x28, 0x72, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 28 72 d9 12 \tvpshrdw $0x12,%ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf3, 0xed, 0x48, 0x72, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 48 72 d9 12 \tvpshrdw $0x12,%zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf3, 0x6d, 0x08, 0x73, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 6d 08 73 d9 12 \tvpshrdd $0x12,%xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf3, 0x6d, 0x28, 0x73, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 6d 28 73 d9 12 \tvpshrdd $0x12,%ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf3, 0x6d, 0x48, 0x73, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 6d 48 73 d9 12 \tvpshrdd $0x12,%zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf3, 0xed, 0x08, 0x73, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 08 73 d9 12 \tvpshrdq $0x12,%xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf3, 0xed, 0x28, 0x73, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 28 73 d9 12 \tvpshrdq $0x12,%ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf3, 0xed, 0x48, 0x73, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 48 73 d9 12 \tvpshrdq $0x12,%zmm1,%zmm2,%zmm3",}, +{{0x66, 0x0f, 0x3a, 0xce, 0xd9, 0x12, }, 6, 0, "", "", +"66 0f 3a ce d9 12 \tgf2p8affineqb $0x12,%xmm1,%xmm3",}, +{{0xc4, 0xe3, 0xe9, 0xce, 0xd9, 0x12, }, 6, 0, "", "", +"c4 e3 e9 ce d9 12 \tvgf2p8affineqb $0x12,%xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe3, 0xed, 0xce, 0xd9, 0x12, }, 6, 0, "", "", +"c4 e3 ed ce d9 12 \tvgf2p8affineqb $0x12,%ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf3, 0xed, 0x48, 0xce, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 48 ce d9 12 \tvgf2p8affineqb $0x12,%zmm1,%zmm2,%zmm3",}, +{{0x66, 0x0f, 0x3a, 0xcf, 0xd9, 0x12, }, 6, 0, "", "", +"66 0f 3a cf d9 12 \tgf2p8affineinvqb $0x12,%xmm1,%xmm3",}, +{{0xc4, 0xe3, 0xe9, 0xcf, 0xd9, 0x12, }, 6, 0, "", "", +"c4 e3 e9 cf d9 12 \tvgf2p8affineinvqb $0x12,%xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe3, 0xed, 0xcf, 0xd9, 0x12, }, 6, 0, "", "", +"c4 e3 ed cf d9 12 \tvgf2p8affineinvqb $0x12,%ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf3, 0xed, 0x48, 0xcf, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 48 cf d9 12 \tvgf2p8affineinvqb $0x12,%zmm1,%zmm2,%zmm3",}, {{0x62, 0xf1, 0x4d, 0x48, 0x72, 0xc5, 0x12, }, 7, 0, "", "", "62 f1 4d 48 72 c5 12 \tvprord $0x12,%zmm5,%zmm6",}, {{0x62, 0xf1, 0xcd, 0x48, 0x72, 0xc5, 0x12, }, 7, 0, "", "", diff --git a/tools/perf/arch/x86/tests/insn-x86-dat-64.c b/tools/perf/arch/x86/tests/insn-x86-dat-64.c index 656f8aed31de..567ecccfad7c 100644 --- a/tools/perf/arch/x86/tests/insn-x86-dat-64.c +++ b/tools/perf/arch/x86/tests/insn-x86-dat-64.c @@ -587,6 +587,112 @@ "62 02 35 07 4f d0 \tvrsqrt14ss %xmm24,%xmm25,%xmm26{%k7}",}, {{0x62, 0x02, 0xb5, 0x07, 0x4f, 0xd0, }, 6, 0, "", "", "62 02 b5 07 4f d0 \tvrsqrt14sd %xmm24,%xmm25,%xmm26{%k7}",}, +{{0x62, 0xf2, 0x6d, 0x08, 0x50, 0xd9, }, 6, 0, "", "", +"62 f2 6d 08 50 d9 \tvpdpbusd %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0x6d, 0x28, 0x50, 0xd9, }, 6, 0, "", "", +"62 f2 6d 28 50 d9 \tvpdpbusd %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x50, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 50 d9 \tvpdpbusd %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x50, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 50 9c c8 78 56 34 12 \tvpdpbusd 0x12345678(%rax,%rcx,8),%zmm2,%zmm3",}, +{{0x67, 0x62, 0xf2, 0x6d, 0x48, 0x50, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 6d 48 50 9c c8 78 56 34 12 \tvpdpbusd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x08, 0x51, 0xd9, }, 6, 0, "", "", +"62 f2 6d 08 51 d9 \tvpdpbusds %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0x6d, 0x28, 0x51, 0xd9, }, 6, 0, "", "", +"62 f2 6d 28 51 d9 \tvpdpbusds %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x51, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 51 d9 \tvpdpbusds %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x51, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 51 9c c8 78 56 34 12 \tvpdpbusds 0x12345678(%rax,%rcx,8),%zmm2,%zmm3",}, +{{0x67, 0x62, 0xf2, 0x6d, 0x48, 0x51, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 6d 48 51 9c c8 78 56 34 12 \tvpdpbusds 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6e, 0x08, 0x52, 0xd9, }, 6, 0, "", "", +"62 f2 6e 08 52 d9 \tvdpbf16ps %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0x6e, 0x28, 0x52, 0xd9, }, 6, 0, "", "", +"62 f2 6e 28 52 d9 \tvdpbf16ps %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6e, 0x48, 0x52, 0xd9, }, 6, 0, "", "", +"62 f2 6e 48 52 d9 \tvdpbf16ps %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6e, 0x48, 0x52, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6e 48 52 9c c8 78 56 34 12 \tvdpbf16ps 0x12345678(%rax,%rcx,8),%zmm2,%zmm3",}, +{{0x67, 0x62, 0xf2, 0x6e, 0x48, 0x52, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 6e 48 52 9c c8 78 56 34 12 \tvdpbf16ps 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x08, 0x52, 0xd9, }, 6, 0, "", "", +"62 f2 6d 08 52 d9 \tvpdpwssd %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0x6d, 0x28, 0x52, 0xd9, }, 6, 0, "", "", +"62 f2 6d 28 52 d9 \tvpdpwssd %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x52, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 52 d9 \tvpdpwssd %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x52, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 52 9c c8 78 56 34 12 \tvpdpwssd 0x12345678(%rax,%rcx,8),%zmm2,%zmm3",}, +{{0x67, 0x62, 0xf2, 0x6d, 0x48, 0x52, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 6d 48 52 9c c8 78 56 34 12 \tvpdpwssd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x7f, 0x48, 0x52, 0x20, }, 6, 0, "", "", +"62 f2 7f 48 52 20 \tvp4dpwssd (%rax),%zmm0,%zmm4",}, +{{0x67, 0x62, 0xf2, 0x7f, 0x48, 0x52, 0x20, }, 7, 0, "", "", +"67 62 f2 7f 48 52 20 \tvp4dpwssd (%eax),%zmm0,%zmm4",}, +{{0x62, 0xf2, 0x7f, 0x48, 0x52, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 7f 48 52 a4 c8 78 56 34 12 \tvp4dpwssd 0x12345678(%rax,%rcx,8),%zmm0,%zmm4",}, +{{0x67, 0x62, 0xf2, 0x7f, 0x48, 0x52, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 7f 48 52 a4 c8 78 56 34 12 \tvp4dpwssd 0x12345678(%eax,%ecx,8),%zmm0,%zmm4",}, +{{0x62, 0xf2, 0x6d, 0x08, 0x53, 0xd9, }, 6, 0, "", "", +"62 f2 6d 08 53 d9 \tvpdpwssds %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0x6d, 0x28, 0x53, 0xd9, }, 6, 0, "", "", +"62 f2 6d 28 53 d9 \tvpdpwssds %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x53, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 53 d9 \tvpdpwssds %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x53, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 53 9c c8 78 56 34 12 \tvpdpwssds 0x12345678(%rax,%rcx,8),%zmm2,%zmm3",}, +{{0x67, 0x62, 0xf2, 0x6d, 0x48, 0x53, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 6d 48 53 9c c8 78 56 34 12 \tvpdpwssds 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x7f, 0x48, 0x53, 0x20, }, 6, 0, "", "", +"62 f2 7f 48 53 20 \tvp4dpwssds (%rax),%zmm0,%zmm4",}, +{{0x67, 0x62, 0xf2, 0x7f, 0x48, 0x53, 0x20, }, 7, 0, "", "", +"67 62 f2 7f 48 53 20 \tvp4dpwssds (%eax),%zmm0,%zmm4",}, +{{0x62, 0xf2, 0x7f, 0x48, 0x53, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 7f 48 53 a4 c8 78 56 34 12 \tvp4dpwssds 0x12345678(%rax,%rcx,8),%zmm0,%zmm4",}, +{{0x67, 0x62, 0xf2, 0x7f, 0x48, 0x53, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 7f 48 53 a4 c8 78 56 34 12 \tvp4dpwssds 0x12345678(%eax,%ecx,8),%zmm0,%zmm4",}, +{{0x62, 0xf2, 0x7d, 0x08, 0x54, 0xd1, }, 6, 0, "", "", +"62 f2 7d 08 54 d1 \tvpopcntb %xmm1,%xmm2",}, +{{0x62, 0xf2, 0x7d, 0x28, 0x54, 0xd1, }, 6, 0, "", "", +"62 f2 7d 28 54 d1 \tvpopcntb %ymm1,%ymm2",}, +{{0x62, 0xf2, 0x7d, 0x48, 0x54, 0xd1, }, 6, 0, "", "", +"62 f2 7d 48 54 d1 \tvpopcntb %zmm1,%zmm2",}, +{{0x62, 0xf2, 0x7d, 0x48, 0x54, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 7d 48 54 94 c8 78 56 34 12 \tvpopcntb 0x12345678(%rax,%rcx,8),%zmm2",}, +{{0x67, 0x62, 0xf2, 0x7d, 0x48, 0x54, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 7d 48 54 94 c8 78 56 34 12 \tvpopcntb 0x12345678(%eax,%ecx,8),%zmm2",}, +{{0x62, 0xf2, 0xfd, 0x08, 0x54, 0xd1, }, 6, 0, "", "", +"62 f2 fd 08 54 d1 \tvpopcntw %xmm1,%xmm2",}, +{{0x62, 0xf2, 0xfd, 0x28, 0x54, 0xd1, }, 6, 0, "", "", +"62 f2 fd 28 54 d1 \tvpopcntw %ymm1,%ymm2",}, +{{0x62, 0xf2, 0xfd, 0x48, 0x54, 0xd1, }, 6, 0, "", "", +"62 f2 fd 48 54 d1 \tvpopcntw %zmm1,%zmm2",}, +{{0x62, 0xf2, 0xfd, 0x48, 0x54, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 fd 48 54 94 c8 78 56 34 12 \tvpopcntw 0x12345678(%rax,%rcx,8),%zmm2",}, +{{0x67, 0x62, 0xf2, 0xfd, 0x48, 0x54, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 fd 48 54 94 c8 78 56 34 12 \tvpopcntw 0x12345678(%eax,%ecx,8),%zmm2",}, +{{0x62, 0xf2, 0x7d, 0x08, 0x55, 0xd1, }, 6, 0, "", "", +"62 f2 7d 08 55 d1 \tvpopcntd %xmm1,%xmm2",}, +{{0x62, 0xf2, 0x7d, 0x28, 0x55, 0xd1, }, 6, 0, "", "", +"62 f2 7d 28 55 d1 \tvpopcntd %ymm1,%ymm2",}, +{{0x62, 0xf2, 0x7d, 0x48, 0x55, 0xd1, }, 6, 0, "", "", +"62 f2 7d 48 55 d1 \tvpopcntd %zmm1,%zmm2",}, +{{0x62, 0xf2, 0x7d, 0x48, 0x55, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 7d 48 55 94 c8 78 56 34 12 \tvpopcntd 0x12345678(%rax,%rcx,8),%zmm2",}, +{{0x67, 0x62, 0xf2, 0x7d, 0x48, 0x55, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 7d 48 55 94 c8 78 56 34 12 \tvpopcntd 0x12345678(%eax,%ecx,8),%zmm2",}, +{{0x62, 0xf2, 0xfd, 0x08, 0x55, 0xd1, }, 6, 0, "", "", +"62 f2 fd 08 55 d1 \tvpopcntq %xmm1,%xmm2",}, +{{0x62, 0xf2, 0xfd, 0x28, 0x55, 0xd1, }, 6, 0, "", "", +"62 f2 fd 28 55 d1 \tvpopcntq %ymm1,%ymm2",}, +{{0x62, 0xf2, 0xfd, 0x48, 0x55, 0xd1, }, 6, 0, "", "", +"62 f2 fd 48 55 d1 \tvpopcntq %zmm1,%zmm2",}, +{{0x62, 0xf2, 0xfd, 0x48, 0x55, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 fd 48 55 94 c8 78 56 34 12 \tvpopcntq 0x12345678(%rax,%rcx,8),%zmm2",}, +{{0x67, 0x62, 0xf2, 0xfd, 0x48, 0x55, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 fd 48 55 94 c8 78 56 34 12 \tvpopcntq 0x12345678(%eax,%ecx,8),%zmm2",}, {{0xc4, 0xe2, 0x79, 0x59, 0xf4, }, 5, 0, "", "", "c4 e2 79 59 f4 \tvpbroadcastq %xmm4,%xmm6",}, {{0x62, 0x02, 0x7d, 0x48, 0x59, 0xd3, }, 6, 0, "", "", @@ -601,6 +707,46 @@ "62 62 7d 48 5b 21 \tvbroadcasti32x8 (%rcx),%zmm28",}, {{0x62, 0x62, 0xfd, 0x48, 0x5b, 0x11, }, 6, 0, "", "", "62 62 fd 48 5b 11 \tvbroadcasti64x4 (%rcx),%zmm26",}, +{{0x62, 0xf2, 0x7d, 0x08, 0x62, 0xd1, }, 6, 0, "", "", +"62 f2 7d 08 62 d1 \tvpexpandb %xmm1,%xmm2",}, +{{0x62, 0xf2, 0x7d, 0x28, 0x62, 0xd1, }, 6, 0, "", "", +"62 f2 7d 28 62 d1 \tvpexpandb %ymm1,%ymm2",}, +{{0x62, 0xf2, 0x7d, 0x48, 0x62, 0xd1, }, 6, 0, "", "", +"62 f2 7d 48 62 d1 \tvpexpandb %zmm1,%zmm2",}, +{{0x62, 0xf2, 0x7d, 0x48, 0x62, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 7d 48 62 94 c8 78 56 34 12 \tvpexpandb 0x12345678(%rax,%rcx,8),%zmm2",}, +{{0x67, 0x62, 0xf2, 0x7d, 0x48, 0x62, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 7d 48 62 94 c8 78 56 34 12 \tvpexpandb 0x12345678(%eax,%ecx,8),%zmm2",}, +{{0x62, 0xf2, 0xfd, 0x08, 0x62, 0xd1, }, 6, 0, "", "", +"62 f2 fd 08 62 d1 \tvpexpandw %xmm1,%xmm2",}, +{{0x62, 0xf2, 0xfd, 0x28, 0x62, 0xd1, }, 6, 0, "", "", +"62 f2 fd 28 62 d1 \tvpexpandw %ymm1,%ymm2",}, +{{0x62, 0xf2, 0xfd, 0x48, 0x62, 0xd1, }, 6, 0, "", "", +"62 f2 fd 48 62 d1 \tvpexpandw %zmm1,%zmm2",}, +{{0x62, 0xf2, 0xfd, 0x48, 0x62, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 fd 48 62 94 c8 78 56 34 12 \tvpexpandw 0x12345678(%rax,%rcx,8),%zmm2",}, +{{0x67, 0x62, 0xf2, 0xfd, 0x48, 0x62, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 fd 48 62 94 c8 78 56 34 12 \tvpexpandw 0x12345678(%eax,%ecx,8),%zmm2",}, +{{0x62, 0xf2, 0x7d, 0x08, 0x63, 0xca, }, 6, 0, "", "", +"62 f2 7d 08 63 ca \tvpcompressb %xmm1,%xmm2",}, +{{0x62, 0xf2, 0x7d, 0x28, 0x63, 0xca, }, 6, 0, "", "", +"62 f2 7d 28 63 ca \tvpcompressb %ymm1,%ymm2",}, +{{0x62, 0xf2, 0x7d, 0x48, 0x63, 0xca, }, 6, 0, "", "", +"62 f2 7d 48 63 ca \tvpcompressb %zmm1,%zmm2",}, +{{0x62, 0xf2, 0x7d, 0x48, 0x63, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 7d 48 63 94 c8 78 56 34 12 \tvpcompressb %zmm2,0x12345678(%rax,%rcx,8)",}, +{{0x67, 0x62, 0xf2, 0x7d, 0x48, 0x63, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 7d 48 63 94 c8 78 56 34 12 \tvpcompressb %zmm2,0x12345678(%eax,%ecx,8)",}, +{{0x62, 0xf2, 0xfd, 0x08, 0x63, 0xca, }, 6, 0, "", "", +"62 f2 fd 08 63 ca \tvpcompressw %xmm1,%xmm2",}, +{{0x62, 0xf2, 0xfd, 0x28, 0x63, 0xca, }, 6, 0, "", "", +"62 f2 fd 28 63 ca \tvpcompressw %ymm1,%ymm2",}, +{{0x62, 0xf2, 0xfd, 0x48, 0x63, 0xca, }, 6, 0, "", "", +"62 f2 fd 48 63 ca \tvpcompressw %zmm1,%zmm2",}, +{{0x62, 0xf2, 0xfd, 0x48, 0x63, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 fd 48 63 94 c8 78 56 34 12 \tvpcompressw %zmm2,0x12345678(%rax,%rcx,8)",}, +{{0x67, 0x62, 0xf2, 0xfd, 0x48, 0x63, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 fd 48 63 94 c8 78 56 34 12 \tvpcompressw %zmm2,0x12345678(%eax,%ecx,8)",}, {{0x62, 0x02, 0x25, 0x40, 0x64, 0xe2, }, 6, 0, "", "", "62 02 25 40 64 e2 \tvpblendmd %zmm26,%zmm27,%zmm28",}, {{0x62, 0x02, 0xa5, 0x40, 0x64, 0xe2, }, 6, 0, "", "", @@ -613,6 +759,106 @@ "62 02 25 40 66 e2 \tvpblendmb %zmm26,%zmm27,%zmm28",}, {{0x62, 0x02, 0xa5, 0x40, 0x66, 0xe2, }, 6, 0, "", "", "62 02 a5 40 66 e2 \tvpblendmw %zmm26,%zmm27,%zmm28",}, +{{0x62, 0xf2, 0x6f, 0x08, 0x68, 0xd9, }, 6, 0, "", "", +"62 f2 6f 08 68 d9 \tvp2intersectd %xmm1,%xmm2,%k3",}, +{{0x62, 0xf2, 0x6f, 0x28, 0x68, 0xd9, }, 6, 0, "", "", +"62 f2 6f 28 68 d9 \tvp2intersectd %ymm1,%ymm2,%k3",}, +{{0x62, 0xf2, 0x6f, 0x48, 0x68, 0xd9, }, 6, 0, "", "", +"62 f2 6f 48 68 d9 \tvp2intersectd %zmm1,%zmm2,%k3",}, +{{0x62, 0xf2, 0x6f, 0x48, 0x68, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6f 48 68 9c c8 78 56 34 12 \tvp2intersectd 0x12345678(%rax,%rcx,8),%zmm2,%k3",}, +{{0x67, 0x62, 0xf2, 0x6f, 0x48, 0x68, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 6f 48 68 9c c8 78 56 34 12 \tvp2intersectd 0x12345678(%eax,%ecx,8),%zmm2,%k3",}, +{{0x62, 0xf2, 0xef, 0x08, 0x68, 0xd9, }, 6, 0, "", "", +"62 f2 ef 08 68 d9 \tvp2intersectq %xmm1,%xmm2,%k3",}, +{{0x62, 0xf2, 0xef, 0x28, 0x68, 0xd9, }, 6, 0, "", "", +"62 f2 ef 28 68 d9 \tvp2intersectq %ymm1,%ymm2,%k3",}, +{{0x62, 0xf2, 0xef, 0x48, 0x68, 0xd9, }, 6, 0, "", "", +"62 f2 ef 48 68 d9 \tvp2intersectq %zmm1,%zmm2,%k3",}, +{{0x62, 0xf2, 0xef, 0x48, 0x68, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 ef 48 68 9c c8 78 56 34 12 \tvp2intersectq 0x12345678(%rax,%rcx,8),%zmm2,%k3",}, +{{0x67, 0x62, 0xf2, 0xef, 0x48, 0x68, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 ef 48 68 9c c8 78 56 34 12 \tvp2intersectq 0x12345678(%eax,%ecx,8),%zmm2,%k3",}, +{{0x62, 0xf2, 0xed, 0x08, 0x70, 0xd9, }, 6, 0, "", "", +"62 f2 ed 08 70 d9 \tvpshldvw %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0xed, 0x28, 0x70, 0xd9, }, 6, 0, "", "", +"62 f2 ed 28 70 d9 \tvpshldvw %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0x70, 0xd9, }, 6, 0, "", "", +"62 f2 ed 48 70 d9 \tvpshldvw %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0x70, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 ed 48 70 9c c8 78 56 34 12 \tvpshldvw 0x12345678(%rax,%rcx,8),%zmm2,%zmm3",}, +{{0x67, 0x62, 0xf2, 0xed, 0x48, 0x70, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 ed 48 70 9c c8 78 56 34 12 \tvpshldvw 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x08, 0x71, 0xd9, }, 6, 0, "", "", +"62 f2 6d 08 71 d9 \tvpshldvd %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0x6d, 0x28, 0x71, 0xd9, }, 6, 0, "", "", +"62 f2 6d 28 71 d9 \tvpshldvd %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x71, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 71 d9 \tvpshldvd %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x71, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 71 9c c8 78 56 34 12 \tvpshldvd 0x12345678(%rax,%rcx,8),%zmm2,%zmm3",}, +{{0x67, 0x62, 0xf2, 0x6d, 0x48, 0x71, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 6d 48 71 9c c8 78 56 34 12 \tvpshldvd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0xed, 0x08, 0x71, 0xd9, }, 6, 0, "", "", +"62 f2 ed 08 71 d9 \tvpshldvq %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0xed, 0x28, 0x71, 0xd9, }, 6, 0, "", "", +"62 f2 ed 28 71 d9 \tvpshldvq %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0x71, 0xd9, }, 6, 0, "", "", +"62 f2 ed 48 71 d9 \tvpshldvq %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0x71, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 ed 48 71 9c c8 78 56 34 12 \tvpshldvq 0x12345678(%rax,%rcx,8),%zmm2,%zmm3",}, +{{0x67, 0x62, 0xf2, 0xed, 0x48, 0x71, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 ed 48 71 9c c8 78 56 34 12 \tvpshldvq 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6f, 0x08, 0x72, 0xd9, }, 6, 0, "", "", +"62 f2 6f 08 72 d9 \tvcvtne2ps2bf16 %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0x6f, 0x28, 0x72, 0xd9, }, 6, 0, "", "", +"62 f2 6f 28 72 d9 \tvcvtne2ps2bf16 %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6f, 0x48, 0x72, 0xd9, }, 6, 0, "", "", +"62 f2 6f 48 72 d9 \tvcvtne2ps2bf16 %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6f, 0x48, 0x72, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6f 48 72 9c c8 78 56 34 12 \tvcvtne2ps2bf16 0x12345678(%rax,%rcx,8),%zmm2,%zmm3",}, +{{0x67, 0x62, 0xf2, 0x6f, 0x48, 0x72, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 6f 48 72 9c c8 78 56 34 12 \tvcvtne2ps2bf16 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x7e, 0x08, 0x72, 0xd1, }, 6, 0, "", "", +"62 f2 7e 08 72 d1 \tvcvtneps2bf16 %xmm1,%xmm2",}, +{{0x62, 0xf2, 0x7e, 0x28, 0x72, 0xd1, }, 6, 0, "", "", +"62 f2 7e 28 72 d1 \tvcvtneps2bf16 %ymm1,%xmm2",}, +{{0x62, 0xf2, 0x7e, 0x48, 0x72, 0xd1, }, 6, 0, "", "", +"62 f2 7e 48 72 d1 \tvcvtneps2bf16 %zmm1,%ymm2",}, +{{0x62, 0xf2, 0x7e, 0x48, 0x72, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 7e 48 72 94 c8 78 56 34 12 \tvcvtneps2bf16 0x12345678(%rax,%rcx,8),%ymm2",}, +{{0x67, 0x62, 0xf2, 0x7e, 0x48, 0x72, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 7e 48 72 94 c8 78 56 34 12 \tvcvtneps2bf16 0x12345678(%eax,%ecx,8),%ymm2",}, +{{0x62, 0xf2, 0xed, 0x08, 0x72, 0xd9, }, 6, 0, "", "", +"62 f2 ed 08 72 d9 \tvpshrdvw %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0xed, 0x28, 0x72, 0xd9, }, 6, 0, "", "", +"62 f2 ed 28 72 d9 \tvpshrdvw %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0x72, 0xd9, }, 6, 0, "", "", +"62 f2 ed 48 72 d9 \tvpshrdvw %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0x72, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 ed 48 72 9c c8 78 56 34 12 \tvpshrdvw 0x12345678(%rax,%rcx,8),%zmm2,%zmm3",}, +{{0x67, 0x62, 0xf2, 0xed, 0x48, 0x72, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 ed 48 72 9c c8 78 56 34 12 \tvpshrdvw 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x08, 0x73, 0xd9, }, 6, 0, "", "", +"62 f2 6d 08 73 d9 \tvpshrdvd %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0x6d, 0x28, 0x73, 0xd9, }, 6, 0, "", "", +"62 f2 6d 28 73 d9 \tvpshrdvd %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x73, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 73 d9 \tvpshrdvd %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x73, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 73 9c c8 78 56 34 12 \tvpshrdvd 0x12345678(%rax,%rcx,8),%zmm2,%zmm3",}, +{{0x67, 0x62, 0xf2, 0x6d, 0x48, 0x73, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 6d 48 73 9c c8 78 56 34 12 \tvpshrdvd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0xed, 0x08, 0x73, 0xd9, }, 6, 0, "", "", +"62 f2 ed 08 73 d9 \tvpshrdvq %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0xed, 0x28, 0x73, 0xd9, }, 6, 0, "", "", +"62 f2 ed 28 73 d9 \tvpshrdvq %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0x73, 0xd9, }, 6, 0, "", "", +"62 f2 ed 48 73 d9 \tvpshrdvq %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0x73, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 ed 48 73 9c c8 78 56 34 12 \tvpshrdvq 0x12345678(%rax,%rcx,8),%zmm2,%zmm3",}, +{{0x67, 0x62, 0xf2, 0xed, 0x48, 0x73, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 ed 48 73 9c c8 78 56 34 12 \tvpshrdvq 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, {{0x62, 0x02, 0x35, 0x40, 0x75, 0xd0, }, 6, 0, "", "", "62 02 35 40 75 d0 \tvpermi2b %zmm24,%zmm25,%zmm26",}, {{0x62, 0x02, 0xa5, 0x40, 0x75, 0xe2, }, 6, 0, "", "", @@ -667,6 +913,16 @@ "62 02 25 40 8d e2 \tvpermb %zmm26,%zmm27,%zmm28",}, {{0x62, 0x02, 0xa5, 0x40, 0x8d, 0xe2, }, 6, 0, "", "", "62 02 a5 40 8d e2 \tvpermw %zmm26,%zmm27,%zmm28",}, +{{0x62, 0xf2, 0x6d, 0x08, 0x8f, 0xd9, }, 6, 0, "", "", +"62 f2 6d 08 8f d9 \tvpshufbitqmb %xmm1,%xmm2,%k3",}, +{{0x62, 0xf2, 0x6d, 0x28, 0x8f, 0xd9, }, 6, 0, "", "", +"62 f2 6d 28 8f d9 \tvpshufbitqmb %ymm1,%ymm2,%k3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x8f, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 8f d9 \tvpshufbitqmb %zmm1,%zmm2,%k3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x8f, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 8f 9c c8 78 56 34 12 \tvpshufbitqmb 0x12345678(%rax,%rcx,8),%zmm2,%k3",}, +{{0x67, 0x62, 0xf2, 0x6d, 0x48, 0x8f, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 6d 48 8f 9c c8 78 56 34 12 \tvpshufbitqmb 0x12345678(%eax,%ecx,8),%zmm2,%k3",}, {{0xc4, 0xe2, 0x69, 0x90, 0x4c, 0x7d, 0x02, }, 7, 0, "", "", "c4 e2 69 90 4c 7d 02 \tvpgatherdd %xmm2,0x2(%rbp,%xmm7,2),%xmm1",}, {{0xc4, 0xe2, 0xe9, 0x90, 0x4c, 0x7d, 0x04, }, 7, 0, "", "", @@ -683,6 +939,54 @@ "62 22 7d 41 91 94 dd 7b 00 00 00 \tvpgatherqd 0x7b(%rbp,%zmm27,8),%ymm26{%k1}",}, {{0x62, 0x22, 0xfd, 0x41, 0x91, 0x94, 0xdd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "", "62 22 fd 41 91 94 dd 7b 00 00 00 \tvpgatherqq 0x7b(%rbp,%zmm27,8),%zmm26{%k1}",}, +{{0xc4, 0xe2, 0x69, 0x9a, 0xd9, }, 5, 0, "", "", +"c4 e2 69 9a d9 \tvfmsub132ps %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x6d, 0x9a, 0xd9, }, 5, 0, "", "", +"c4 e2 6d 9a d9 \tvfmsub132ps %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x9a, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 9a d9 \tvfmsub132ps %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0x9a, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 9a 9c c8 78 56 34 12 \tvfmsub132ps 0x12345678(%rax,%rcx,8),%zmm2,%zmm3",}, +{{0x67, 0x62, 0xf2, 0x6d, 0x48, 0x9a, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 6d 48 9a 9c c8 78 56 34 12 \tvfmsub132ps 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0xc4, 0xe2, 0xe9, 0x9a, 0xd9, }, 5, 0, "", "", +"c4 e2 e9 9a d9 \tvfmsub132pd %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0xed, 0x9a, 0xd9, }, 5, 0, "", "", +"c4 e2 ed 9a d9 \tvfmsub132pd %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0x9a, 0xd9, }, 6, 0, "", "", +"62 f2 ed 48 9a d9 \tvfmsub132pd %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0x9a, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 ed 48 9a 9c c8 78 56 34 12 \tvfmsub132pd 0x12345678(%rax,%rcx,8),%zmm2,%zmm3",}, +{{0x67, 0x62, 0xf2, 0xed, 0x48, 0x9a, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 ed 48 9a 9c c8 78 56 34 12 \tvfmsub132pd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x7f, 0x48, 0x9a, 0x20, }, 6, 0, "", "", +"62 f2 7f 48 9a 20 \tv4fmaddps (%rax),%zmm0,%zmm4",}, +{{0x67, 0x62, 0xf2, 0x7f, 0x48, 0x9a, 0x20, }, 7, 0, "", "", +"67 62 f2 7f 48 9a 20 \tv4fmaddps (%eax),%zmm0,%zmm4",}, +{{0x62, 0xf2, 0x7f, 0x48, 0x9a, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 7f 48 9a a4 c8 78 56 34 12 \tv4fmaddps 0x12345678(%rax,%rcx,8),%zmm0,%zmm4",}, +{{0x67, 0x62, 0xf2, 0x7f, 0x48, 0x9a, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 7f 48 9a a4 c8 78 56 34 12 \tv4fmaddps 0x12345678(%eax,%ecx,8),%zmm0,%zmm4",}, +{{0xc4, 0xe2, 0x69, 0x9b, 0xd9, }, 5, 0, "", "", +"c4 e2 69 9b d9 \tvfmsub132ss %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x69, 0x9b, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "", +"c4 e2 69 9b 9c c8 78 56 34 12 \tvfmsub132ss 0x12345678(%rax,%rcx,8),%xmm2,%xmm3",}, +{{0x67, 0xc4, 0xe2, 0x69, 0x9b, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"67 c4 e2 69 9b 9c c8 78 56 34 12 \tvfmsub132ss 0x12345678(%eax,%ecx,8),%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0xe9, 0x9b, 0xd9, }, 5, 0, "", "", +"c4 e2 e9 9b d9 \tvfmsub132sd %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0xe9, 0x9b, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "", +"c4 e2 e9 9b 9c c8 78 56 34 12 \tvfmsub132sd 0x12345678(%rax,%rcx,8),%xmm2,%xmm3",}, +{{0x67, 0xc4, 0xe2, 0xe9, 0x9b, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"67 c4 e2 e9 9b 9c c8 78 56 34 12 \tvfmsub132sd 0x12345678(%eax,%ecx,8),%xmm2,%xmm3",}, +{{0x62, 0xf2, 0x7f, 0x08, 0x9b, 0x20, }, 6, 0, "", "", +"62 f2 7f 08 9b 20 \tv4fmaddss (%rax),%xmm0,%xmm4",}, +{{0x67, 0x62, 0xf2, 0x7f, 0x08, 0x9b, 0x20, }, 7, 0, "", "", +"67 62 f2 7f 08 9b 20 \tv4fmaddss (%eax),%xmm0,%xmm4",}, +{{0x62, 0xf2, 0x7f, 0x08, 0x9b, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 7f 08 9b a4 c8 78 56 34 12 \tv4fmaddss 0x12345678(%rax,%rcx,8),%xmm0,%xmm4",}, +{{0x67, 0x62, 0xf2, 0x7f, 0x08, 0x9b, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 7f 08 9b a4 c8 78 56 34 12 \tv4fmaddss 0x12345678(%eax,%ecx,8),%xmm0,%xmm4",}, {{0x62, 0x22, 0x7d, 0x41, 0xa0, 0xa4, 0xed, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "", "62 22 7d 41 a0 a4 ed 7b 00 00 00 \tvpscatterdd %zmm28,0x7b(%rbp,%zmm29,8){%k1}",}, {{0x62, 0x22, 0xfd, 0x41, 0xa0, 0x94, 0xdd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "", @@ -699,6 +1003,54 @@ "62 b2 7d 41 a3 b4 ed 7b 00 00 00 \tvscatterqps %ymm6,0x7b(%rbp,%zmm29,8){%k1}",}, {{0x62, 0x22, 0xfd, 0x41, 0xa3, 0xa4, 0xed, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "", "62 22 fd 41 a3 a4 ed 7b 00 00 00 \tvscatterqpd %zmm28,0x7b(%rbp,%zmm29,8){%k1}",}, +{{0xc4, 0xe2, 0x69, 0xaa, 0xd9, }, 5, 0, "", "", +"c4 e2 69 aa d9 \tvfmsub213ps %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x6d, 0xaa, 0xd9, }, 5, 0, "", "", +"c4 e2 6d aa d9 \tvfmsub213ps %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xaa, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 aa d9 \tvfmsub213ps %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xaa, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 aa 9c c8 78 56 34 12 \tvfmsub213ps 0x12345678(%rax,%rcx,8),%zmm2,%zmm3",}, +{{0x67, 0x62, 0xf2, 0x6d, 0x48, 0xaa, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 6d 48 aa 9c c8 78 56 34 12 \tvfmsub213ps 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0xc4, 0xe2, 0xe9, 0xaa, 0xd9, }, 5, 0, "", "", +"c4 e2 e9 aa d9 \tvfmsub213pd %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0xed, 0xaa, 0xd9, }, 5, 0, "", "", +"c4 e2 ed aa d9 \tvfmsub213pd %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0xaa, 0xd9, }, 6, 0, "", "", +"62 f2 ed 48 aa d9 \tvfmsub213pd %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0xed, 0x48, 0xaa, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 ed 48 aa 9c c8 78 56 34 12 \tvfmsub213pd 0x12345678(%rax,%rcx,8),%zmm2,%zmm3",}, +{{0x67, 0x62, 0xf2, 0xed, 0x48, 0xaa, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 ed 48 aa 9c c8 78 56 34 12 \tvfmsub213pd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x7f, 0x48, 0xaa, 0x20, }, 6, 0, "", "", +"62 f2 7f 48 aa 20 \tv4fnmaddps (%rax),%zmm0,%zmm4",}, +{{0x67, 0x62, 0xf2, 0x7f, 0x48, 0xaa, 0x20, }, 7, 0, "", "", +"67 62 f2 7f 48 aa 20 \tv4fnmaddps (%eax),%zmm0,%zmm4",}, +{{0x62, 0xf2, 0x7f, 0x48, 0xaa, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 7f 48 aa a4 c8 78 56 34 12 \tv4fnmaddps 0x12345678(%rax,%rcx,8),%zmm0,%zmm4",}, +{{0x67, 0x62, 0xf2, 0x7f, 0x48, 0xaa, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 7f 48 aa a4 c8 78 56 34 12 \tv4fnmaddps 0x12345678(%eax,%ecx,8),%zmm0,%zmm4",}, +{{0xc4, 0xe2, 0x69, 0xab, 0xd9, }, 5, 0, "", "", +"c4 e2 69 ab d9 \tvfmsub213ss %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x69, 0xab, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "", +"c4 e2 69 ab 9c c8 78 56 34 12 \tvfmsub213ss 0x12345678(%rax,%rcx,8),%xmm2,%xmm3",}, +{{0x67, 0xc4, 0xe2, 0x69, 0xab, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"67 c4 e2 69 ab 9c c8 78 56 34 12 \tvfmsub213ss 0x12345678(%eax,%ecx,8),%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0xe9, 0xab, 0xd9, }, 5, 0, "", "", +"c4 e2 e9 ab d9 \tvfmsub213sd %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0xe9, 0xab, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "", +"c4 e2 e9 ab 9c c8 78 56 34 12 \tvfmsub213sd 0x12345678(%rax,%rcx,8),%xmm2,%xmm3",}, +{{0x67, 0xc4, 0xe2, 0xe9, 0xab, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"67 c4 e2 e9 ab 9c c8 78 56 34 12 \tvfmsub213sd 0x12345678(%eax,%ecx,8),%xmm2,%xmm3",}, +{{0x62, 0xf2, 0x7f, 0x08, 0xab, 0x20, }, 6, 0, "", "", +"62 f2 7f 08 ab 20 \tv4fnmaddss (%rax),%xmm0,%xmm4",}, +{{0x67, 0x62, 0xf2, 0x7f, 0x08, 0xab, 0x20, }, 7, 0, "", "", +"67 62 f2 7f 08 ab 20 \tv4fnmaddss (%eax),%xmm0,%xmm4",}, +{{0x62, 0xf2, 0x7f, 0x08, 0xab, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 7f 08 ab a4 c8 78 56 34 12 \tv4fnmaddss 0x12345678(%rax,%rcx,8),%xmm0,%xmm4",}, +{{0x67, 0x62, 0xf2, 0x7f, 0x08, 0xab, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 7f 08 ab a4 c8 78 56 34 12 \tv4fnmaddss 0x12345678(%eax,%ecx,8),%xmm0,%xmm4",}, {{0x62, 0x02, 0xa5, 0x40, 0xb4, 0xe2, }, 6, 0, "", "", "62 02 a5 40 b4 e2 \tvpmadd52luq %zmm26,%zmm27,%zmm28",}, {{0x62, 0x02, 0xa5, 0x40, 0xb5, 0xe2, }, 6, 0, "", "", @@ -727,6 +1079,62 @@ "62 02 15 07 cd f4 \tvrsqrt28ss %xmm28,%xmm29,%xmm30{%k7}",}, {{0x62, 0x02, 0xad, 0x07, 0xcd, 0xd9, }, 6, 0, "", "", "62 02 ad 07 cd d9 \tvrsqrt28sd %xmm25,%xmm26,%xmm27{%k7}",}, +{{0x66, 0x0f, 0x38, 0xcf, 0xd9, }, 5, 0, "", "", +"66 0f 38 cf d9 \tgf2p8mulb %xmm1,%xmm3",}, +{{0x66, 0x0f, 0x38, 0xcf, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "", +"66 0f 38 cf 9c c8 78 56 34 12 \tgf2p8mulb 0x12345678(%rax,%rcx,8),%xmm3",}, +{{0x67, 0x66, 0x0f, 0x38, 0xcf, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"67 66 0f 38 cf 9c c8 78 56 34 12 \tgf2p8mulb 0x12345678(%eax,%ecx,8),%xmm3",}, +{{0xc4, 0xe2, 0x69, 0xcf, 0xd9, }, 5, 0, "", "", +"c4 e2 69 cf d9 \tvgf2p8mulb %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x6d, 0xcf, 0xd9, }, 5, 0, "", "", +"c4 e2 6d cf d9 \tvgf2p8mulb %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xcf, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 cf d9 \tvgf2p8mulb %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xcf, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 cf 9c c8 78 56 34 12 \tvgf2p8mulb 0x12345678(%rax,%rcx,8),%zmm2,%zmm3",}, +{{0x67, 0x62, 0xf2, 0x6d, 0x48, 0xcf, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 6d 48 cf 9c c8 78 56 34 12 \tvgf2p8mulb 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0xc4, 0xe2, 0x69, 0xdc, 0xd9, }, 5, 0, "", "", +"c4 e2 69 dc d9 \tvaesenc %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x6d, 0xdc, 0xd9, }, 5, 0, "", "", +"c4 e2 6d dc d9 \tvaesenc %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xdc, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 dc d9 \tvaesenc %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xdc, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 dc 9c c8 78 56 34 12 \tvaesenc 0x12345678(%rax,%rcx,8),%zmm2,%zmm3",}, +{{0x67, 0x62, 0xf2, 0x6d, 0x48, 0xdc, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 6d 48 dc 9c c8 78 56 34 12 \tvaesenc 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0xc4, 0xe2, 0x69, 0xdd, 0xd9, }, 5, 0, "", "", +"c4 e2 69 dd d9 \tvaesenclast %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x6d, 0xdd, 0xd9, }, 5, 0, "", "", +"c4 e2 6d dd d9 \tvaesenclast %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xdd, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 dd d9 \tvaesenclast %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xdd, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 dd 9c c8 78 56 34 12 \tvaesenclast 0x12345678(%rax,%rcx,8),%zmm2,%zmm3",}, +{{0x67, 0x62, 0xf2, 0x6d, 0x48, 0xdd, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 6d 48 dd 9c c8 78 56 34 12 \tvaesenclast 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0xc4, 0xe2, 0x69, 0xde, 0xd9, }, 5, 0, "", "", +"c4 e2 69 de d9 \tvaesdec %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x6d, 0xde, 0xd9, }, 5, 0, "", "", +"c4 e2 6d de d9 \tvaesdec %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xde, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 de d9 \tvaesdec %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xde, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 de 9c c8 78 56 34 12 \tvaesdec 0x12345678(%rax,%rcx,8),%zmm2,%zmm3",}, +{{0x67, 0x62, 0xf2, 0x6d, 0x48, 0xde, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 6d 48 de 9c c8 78 56 34 12 \tvaesdec 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, +{{0xc4, 0xe2, 0x69, 0xdf, 0xd9, }, 5, 0, "", "", +"c4 e2 69 df d9 \tvaesdeclast %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x6d, 0xdf, 0xd9, }, 5, 0, "", "", +"c4 e2 6d df d9 \tvaesdeclast %ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xdf, 0xd9, }, 6, 0, "", "", +"62 f2 6d 48 df d9 \tvaesdeclast %zmm1,%zmm2,%zmm3",}, +{{0x62, 0xf2, 0x6d, 0x48, 0xdf, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", +"62 f2 6d 48 df 9c c8 78 56 34 12 \tvaesdeclast 0x12345678(%rax,%rcx,8),%zmm2,%zmm3",}, +{{0x67, 0x62, 0xf2, 0x6d, 0x48, 0xdf, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "", +"67 62 f2 6d 48 df 9c c8 78 56 34 12 \tvaesdeclast 0x12345678(%eax,%ecx,8),%zmm2,%zmm3",}, {{0x62, 0x03, 0x15, 0x40, 0x03, 0xf4, 0x12, }, 7, 0, "", "", "62 03 15 40 03 f4 12 \tvalignd $0x12,%zmm28,%zmm29,%zmm30",}, {{0x62, 0x03, 0xad, 0x40, 0x03, 0xd9, 0x12, }, 7, 0, "", "", @@ -827,6 +1235,14 @@ "62 03 2d 40 43 d9 12 \tvshufi32x4 $0x12,%zmm25,%zmm26,%zmm27",}, {{0x62, 0x03, 0x95, 0x40, 0x43, 0xf4, 0x12, }, 7, 0, "", "", "62 03 95 40 43 f4 12 \tvshufi64x2 $0x12,%zmm28,%zmm29,%zmm30",}, +{{0xc4, 0xe3, 0x69, 0x44, 0xd9, 0x12, }, 6, 0, "", "", +"c4 e3 69 44 d9 12 \tvpclmulqdq $0x12,%xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe3, 0x6d, 0x44, 0xd9, 0x12, }, 6, 0, "", "", +"c4 e3 6d 44 d9 12 \tvpclmulqdq $0x12,%ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf3, 0x6d, 0x48, 0x44, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 6d 48 44 d9 12 \tvpclmulqdq $0x12,%zmm1,%zmm2,%zmm3",}, +{{0x62, 0x03, 0x2d, 0x40, 0x44, 0xd9, 0x12, }, 7, 0, "", "", +"62 03 2d 40 44 d9 12 \tvpclmulqdq $0x12,%zmm25,%zmm26,%zmm27",}, {{0x62, 0x03, 0x2d, 0x40, 0x50, 0xd9, 0x12, }, 7, 0, "", "", "62 03 2d 40 50 d9 12 \tvrangeps $0x12,%zmm25,%zmm26,%zmm27",}, {{0x62, 0x03, 0x95, 0x40, 0x50, 0xf4, 0x12, }, 7, 0, "", "", @@ -859,6 +1275,74 @@ "62 93 7d 08 67 eb 12 \tvfpclassss $0x12,%xmm27,%k5",}, {{0x62, 0x93, 0xfd, 0x08, 0x67, 0xee, 0x12, }, 7, 0, "", "", "62 93 fd 08 67 ee 12 \tvfpclasssd $0x12,%xmm30,%k5",}, +{{0x62, 0xf3, 0xed, 0x08, 0x70, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 08 70 d9 12 \tvpshldw $0x12,%xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf3, 0xed, 0x28, 0x70, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 28 70 d9 12 \tvpshldw $0x12,%ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf3, 0xed, 0x48, 0x70, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 48 70 d9 12 \tvpshldw $0x12,%zmm1,%zmm2,%zmm3",}, +{{0x62, 0x03, 0xad, 0x40, 0x70, 0xd9, 0x12, }, 7, 0, "", "", +"62 03 ad 40 70 d9 12 \tvpshldw $0x12,%zmm25,%zmm26,%zmm27",}, +{{0x62, 0xf3, 0x6d, 0x08, 0x71, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 6d 08 71 d9 12 \tvpshldd $0x12,%xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf3, 0x6d, 0x28, 0x71, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 6d 28 71 d9 12 \tvpshldd $0x12,%ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf3, 0x6d, 0x48, 0x71, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 6d 48 71 d9 12 \tvpshldd $0x12,%zmm1,%zmm2,%zmm3",}, +{{0x62, 0x03, 0x2d, 0x40, 0x71, 0xd9, 0x12, }, 7, 0, "", "", +"62 03 2d 40 71 d9 12 \tvpshldd $0x12,%zmm25,%zmm26,%zmm27",}, +{{0x62, 0xf3, 0xed, 0x08, 0x71, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 08 71 d9 12 \tvpshldq $0x12,%xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf3, 0xed, 0x28, 0x71, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 28 71 d9 12 \tvpshldq $0x12,%ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf3, 0xed, 0x48, 0x71, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 48 71 d9 12 \tvpshldq $0x12,%zmm1,%zmm2,%zmm3",}, +{{0x62, 0x03, 0xad, 0x40, 0x71, 0xd9, 0x12, }, 7, 0, "", "", +"62 03 ad 40 71 d9 12 \tvpshldq $0x12,%zmm25,%zmm26,%zmm27",}, +{{0x62, 0xf3, 0xed, 0x08, 0x72, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 08 72 d9 12 \tvpshrdw $0x12,%xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf3, 0xed, 0x28, 0x72, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 28 72 d9 12 \tvpshrdw $0x12,%ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf3, 0xed, 0x48, 0x72, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 48 72 d9 12 \tvpshrdw $0x12,%zmm1,%zmm2,%zmm3",}, +{{0x62, 0x03, 0xad, 0x40, 0x72, 0xd9, 0x12, }, 7, 0, "", "", +"62 03 ad 40 72 d9 12 \tvpshrdw $0x12,%zmm25,%zmm26,%zmm27",}, +{{0x62, 0xf3, 0x6d, 0x08, 0x73, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 6d 08 73 d9 12 \tvpshrdd $0x12,%xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf3, 0x6d, 0x28, 0x73, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 6d 28 73 d9 12 \tvpshrdd $0x12,%ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf3, 0x6d, 0x48, 0x73, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 6d 48 73 d9 12 \tvpshrdd $0x12,%zmm1,%zmm2,%zmm3",}, +{{0x62, 0x03, 0x2d, 0x40, 0x73, 0xd9, 0x12, }, 7, 0, "", "", +"62 03 2d 40 73 d9 12 \tvpshrdd $0x12,%zmm25,%zmm26,%zmm27",}, +{{0x62, 0xf3, 0xed, 0x08, 0x73, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 08 73 d9 12 \tvpshrdq $0x12,%xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf3, 0xed, 0x28, 0x73, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 28 73 d9 12 \tvpshrdq $0x12,%ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf3, 0xed, 0x48, 0x73, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 48 73 d9 12 \tvpshrdq $0x12,%zmm1,%zmm2,%zmm3",}, +{{0x62, 0x03, 0xad, 0x40, 0x73, 0xd9, 0x12, }, 7, 0, "", "", +"62 03 ad 40 73 d9 12 \tvpshrdq $0x12,%zmm25,%zmm26,%zmm27",}, +{{0x66, 0x0f, 0x3a, 0xce, 0xd9, 0x12, }, 6, 0, "", "", +"66 0f 3a ce d9 12 \tgf2p8affineqb $0x12,%xmm1,%xmm3",}, +{{0xc4, 0xe3, 0xe9, 0xce, 0xd9, 0x12, }, 6, 0, "", "", +"c4 e3 e9 ce d9 12 \tvgf2p8affineqb $0x12,%xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe3, 0xed, 0xce, 0xd9, 0x12, }, 6, 0, "", "", +"c4 e3 ed ce d9 12 \tvgf2p8affineqb $0x12,%ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf3, 0xed, 0x48, 0xce, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 48 ce d9 12 \tvgf2p8affineqb $0x12,%zmm1,%zmm2,%zmm3",}, +{{0x62, 0x03, 0xad, 0x40, 0xce, 0xd9, 0x12, }, 7, 0, "", "", +"62 03 ad 40 ce d9 12 \tvgf2p8affineqb $0x12,%zmm25,%zmm26,%zmm27",}, +{{0x66, 0x0f, 0x3a, 0xcf, 0xd9, 0x12, }, 6, 0, "", "", +"66 0f 3a cf d9 12 \tgf2p8affineinvqb $0x12,%xmm1,%xmm3",}, +{{0xc4, 0xe3, 0xe9, 0xcf, 0xd9, 0x12, }, 6, 0, "", "", +"c4 e3 e9 cf d9 12 \tvgf2p8affineinvqb $0x12,%xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe3, 0xed, 0xcf, 0xd9, 0x12, }, 6, 0, "", "", +"c4 e3 ed cf d9 12 \tvgf2p8affineinvqb $0x12,%ymm1,%ymm2,%ymm3",}, +{{0x62, 0xf3, 0xed, 0x48, 0xcf, 0xd9, 0x12, }, 7, 0, "", "", +"62 f3 ed 48 cf d9 12 \tvgf2p8affineinvqb $0x12,%zmm1,%zmm2,%zmm3",}, +{{0x62, 0x03, 0xad, 0x40, 0xcf, 0xd9, 0x12, }, 7, 0, "", "", +"62 03 ad 40 cf d9 12 \tvgf2p8affineinvqb $0x12,%zmm25,%zmm26,%zmm27",}, {{0x62, 0x91, 0x2d, 0x40, 0x72, 0xc1, 0x12, }, 7, 0, "", "", "62 91 2d 40 72 c1 12 \tvprord $0x12,%zmm25,%zmm26",}, {{0x62, 0x91, 0xad, 0x40, 0x72, 0xc1, 0x12, }, 7, 0, "", "", diff --git a/tools/perf/arch/x86/tests/insn-x86-dat-src.c b/tools/perf/arch/x86/tests/insn-x86-dat-src.c index dd85a3afd9ce..ddbf07c50bb8 100644 --- a/tools/perf/arch/x86/tests/insn-x86-dat-src.c +++ b/tools/perf/arch/x86/tests/insn-x86-dat-src.c @@ -510,6 +510,82 @@ int main(void) asm volatile("vrsqrt14ss %xmm24,%xmm25,%xmm26{%k7}"); asm volatile("vrsqrt14sd %xmm24,%xmm25,%xmm26{%k7}"); + /* AVX-512: Op code 0f 38 50 */ + + asm volatile("vpdpbusd %xmm1, %xmm2, %xmm3"); + asm volatile("vpdpbusd %ymm1, %ymm2, %ymm3"); + asm volatile("vpdpbusd %zmm1, %zmm2, %zmm3"); + asm volatile("vpdpbusd 0x12345678(%rax,%rcx,8),%zmm2,%zmm3"); + asm volatile("vpdpbusd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 38 51 */ + + asm volatile("vpdpbusds %xmm1, %xmm2, %xmm3"); + asm volatile("vpdpbusds %ymm1, %ymm2, %ymm3"); + asm volatile("vpdpbusds %zmm1, %zmm2, %zmm3"); + asm volatile("vpdpbusds 0x12345678(%rax,%rcx,8),%zmm2,%zmm3"); + asm volatile("vpdpbusds 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 38 52 */ + + asm volatile("vdpbf16ps %xmm1, %xmm2, %xmm3"); + asm volatile("vdpbf16ps %ymm1, %ymm2, %ymm3"); + asm volatile("vdpbf16ps %zmm1, %zmm2, %zmm3"); + asm volatile("vdpbf16ps 0x12345678(%rax,%rcx,8),%zmm2,%zmm3"); + asm volatile("vdpbf16ps 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + asm volatile("vpdpwssd %xmm1, %xmm2, %xmm3"); + asm volatile("vpdpwssd %ymm1, %ymm2, %ymm3"); + asm volatile("vpdpwssd %zmm1, %zmm2, %zmm3"); + asm volatile("vpdpwssd 0x12345678(%rax,%rcx,8),%zmm2,%zmm3"); + asm volatile("vpdpwssd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + asm volatile("vp4dpwssd (%rax), %zmm0, %zmm4"); + asm volatile("vp4dpwssd (%eax), %zmm0, %zmm4"); + asm volatile("vp4dpwssd 0x12345678(%rax,%rcx,8),%zmm0,%zmm4"); + asm volatile("vp4dpwssd 0x12345678(%eax,%ecx,8),%zmm0,%zmm4"); + + /* AVX-512: Op code 0f 38 53 */ + + asm volatile("vpdpwssds %xmm1, %xmm2, %xmm3"); + asm volatile("vpdpwssds %ymm1, %ymm2, %ymm3"); + asm volatile("vpdpwssds %zmm1, %zmm2, %zmm3"); + asm volatile("vpdpwssds 0x12345678(%rax,%rcx,8),%zmm2,%zmm3"); + asm volatile("vpdpwssds 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + asm volatile("vp4dpwssds (%rax), %zmm0, %zmm4"); + asm volatile("vp4dpwssds (%eax), %zmm0, %zmm4"); + asm volatile("vp4dpwssds 0x12345678(%rax,%rcx,8),%zmm0,%zmm4"); + asm volatile("vp4dpwssds 0x12345678(%eax,%ecx,8),%zmm0,%zmm4"); + + /* AVX-512: Op code 0f 38 54 */ + + asm volatile("vpopcntb %xmm1, %xmm2"); + asm volatile("vpopcntb %ymm1, %ymm2"); + asm volatile("vpopcntb %zmm1, %zmm2"); + asm volatile("vpopcntb 0x12345678(%rax,%rcx,8),%zmm2"); + asm volatile("vpopcntb 0x12345678(%eax,%ecx,8),%zmm2"); + + asm volatile("vpopcntw %xmm1, %xmm2"); + asm volatile("vpopcntw %ymm1, %ymm2"); + asm volatile("vpopcntw %zmm1, %zmm2"); + asm volatile("vpopcntw 0x12345678(%rax,%rcx,8),%zmm2"); + asm volatile("vpopcntw 0x12345678(%eax,%ecx,8),%zmm2"); + + /* AVX-512: Op code 0f 38 55 */ + + asm volatile("vpopcntd %xmm1, %xmm2"); + asm volatile("vpopcntd %ymm1, %ymm2"); + asm volatile("vpopcntd %zmm1, %zmm2"); + asm volatile("vpopcntd 0x12345678(%rax,%rcx,8),%zmm2"); + asm volatile("vpopcntd 0x12345678(%eax,%ecx,8),%zmm2"); + + asm volatile("vpopcntq %xmm1, %xmm2"); + asm volatile("vpopcntq %ymm1, %ymm2"); + asm volatile("vpopcntq %zmm1, %zmm2"); + asm volatile("vpopcntq 0x12345678(%rax,%rcx,8),%zmm2"); + asm volatile("vpopcntq 0x12345678(%eax,%ecx,8),%zmm2"); + /* AVX-512: Op code 0f 38 59 */ asm volatile("vpbroadcastq %xmm4,%xmm6"); @@ -526,6 +602,34 @@ int main(void) asm volatile("vbroadcasti32x8 (%rcx),%zmm28"); asm volatile("vbroadcasti64x4 (%rcx),%zmm26"); + /* AVX-512: Op code 0f 38 62 */ + + asm volatile("vpexpandb %xmm1, %xmm2"); + asm volatile("vpexpandb %ymm1, %ymm2"); + asm volatile("vpexpandb %zmm1, %zmm2"); + asm volatile("vpexpandb 0x12345678(%rax,%rcx,8),%zmm2"); + asm volatile("vpexpandb 0x12345678(%eax,%ecx,8),%zmm2"); + + asm volatile("vpexpandw %xmm1, %xmm2"); + asm volatile("vpexpandw %ymm1, %ymm2"); + asm volatile("vpexpandw %zmm1, %zmm2"); + asm volatile("vpexpandw 0x12345678(%rax,%rcx,8),%zmm2"); + asm volatile("vpexpandw 0x12345678(%eax,%ecx,8),%zmm2"); + + /* AVX-512: Op code 0f 38 63 */ + + asm volatile("vpcompressb %xmm1, %xmm2"); + asm volatile("vpcompressb %ymm1, %ymm2"); + asm volatile("vpcompressb %zmm1, %zmm2"); + asm volatile("vpcompressb %zmm2,0x12345678(%rax,%rcx,8)"); + asm volatile("vpcompressb %zmm2,0x12345678(%eax,%ecx,8)"); + + asm volatile("vpcompressw %xmm1, %xmm2"); + asm volatile("vpcompressw %ymm1, %ymm2"); + asm volatile("vpcompressw %zmm1, %zmm2"); + asm volatile("vpcompressw %zmm2,0x12345678(%rax,%rcx,8)"); + asm volatile("vpcompressw %zmm2,0x12345678(%eax,%ecx,8)"); + /* AVX-512: Op code 0f 38 64 */ asm volatile("vpblendmd %zmm26,%zmm27,%zmm28"); @@ -541,6 +645,76 @@ int main(void) asm volatile("vpblendmb %zmm26,%zmm27,%zmm28"); asm volatile("vpblendmw %zmm26,%zmm27,%zmm28"); + /* AVX-512: Op code 0f 38 68 */ + + asm volatile("vp2intersectd %xmm1, %xmm2, %k3"); + asm volatile("vp2intersectd %ymm1, %ymm2, %k3"); + asm volatile("vp2intersectd %zmm1, %zmm2, %k3"); + asm volatile("vp2intersectd 0x12345678(%rax,%rcx,8),%zmm2,%k3"); + asm volatile("vp2intersectd 0x12345678(%eax,%ecx,8),%zmm2,%k3"); + + asm volatile("vp2intersectq %xmm1, %xmm2, %k3"); + asm volatile("vp2intersectq %ymm1, %ymm2, %k3"); + asm volatile("vp2intersectq %zmm1, %zmm2, %k3"); + asm volatile("vp2intersectq 0x12345678(%rax,%rcx,8),%zmm2,%k3"); + asm volatile("vp2intersectq 0x12345678(%eax,%ecx,8),%zmm2,%k3"); + + /* AVX-512: Op code 0f 38 70 */ + + asm volatile("vpshldvw %xmm1, %xmm2, %xmm3"); + asm volatile("vpshldvw %ymm1, %ymm2, %ymm3"); + asm volatile("vpshldvw %zmm1, %zmm2, %zmm3"); + asm volatile("vpshldvw 0x12345678(%rax,%rcx,8),%zmm2,%zmm3"); + asm volatile("vpshldvw 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 38 71 */ + + asm volatile("vpshldvd %xmm1, %xmm2, %xmm3"); + asm volatile("vpshldvd %ymm1, %ymm2, %ymm3"); + asm volatile("vpshldvd %zmm1, %zmm2, %zmm3"); + asm volatile("vpshldvd 0x12345678(%rax,%rcx,8),%zmm2,%zmm3"); + asm volatile("vpshldvd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + asm volatile("vpshldvq %xmm1, %xmm2, %xmm3"); + asm volatile("vpshldvq %ymm1, %ymm2, %ymm3"); + asm volatile("vpshldvq %zmm1, %zmm2, %zmm3"); + asm volatile("vpshldvq 0x12345678(%rax,%rcx,8),%zmm2,%zmm3"); + asm volatile("vpshldvq 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 38 72 */ + + asm volatile("vcvtne2ps2bf16 %xmm1, %xmm2, %xmm3"); + asm volatile("vcvtne2ps2bf16 %ymm1, %ymm2, %ymm3"); + asm volatile("vcvtne2ps2bf16 %zmm1, %zmm2, %zmm3"); + asm volatile("vcvtne2ps2bf16 0x12345678(%rax,%rcx,8),%zmm2,%zmm3"); + asm volatile("vcvtne2ps2bf16 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + asm volatile("vcvtneps2bf16 %xmm1, %xmm2"); + asm volatile("vcvtneps2bf16 %ymm1, %xmm2"); + asm volatile("vcvtneps2bf16 %zmm1, %ymm2"); + asm volatile("vcvtneps2bf16 0x12345678(%rax,%rcx,8),%ymm2"); + asm volatile("vcvtneps2bf16 0x12345678(%eax,%ecx,8),%ymm2"); + + asm volatile("vpshrdvw %xmm1, %xmm2, %xmm3"); + asm volatile("vpshrdvw %ymm1, %ymm2, %ymm3"); + asm volatile("vpshrdvw %zmm1, %zmm2, %zmm3"); + asm volatile("vpshrdvw 0x12345678(%rax,%rcx,8),%zmm2,%zmm3"); + asm volatile("vpshrdvw 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 38 73 */ + + asm volatile("vpshrdvd %xmm1, %xmm2, %xmm3"); + asm volatile("vpshrdvd %ymm1, %ymm2, %ymm3"); + asm volatile("vpshrdvd %zmm1, %zmm2, %zmm3"); + asm volatile("vpshrdvd 0x12345678(%rax,%rcx,8),%zmm2,%zmm3"); + asm volatile("vpshrdvd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + asm volatile("vpshrdvq %xmm1, %xmm2, %xmm3"); + asm volatile("vpshrdvq %ymm1, %ymm2, %ymm3"); + asm volatile("vpshrdvq %zmm1, %zmm2, %zmm3"); + asm volatile("vpshrdvq 0x12345678(%rax,%rcx,8),%zmm2,%zmm3"); + asm volatile("vpshrdvq 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + /* AVX-512: Op code 0f 38 75 */ asm volatile("vpermi2b %zmm24,%zmm25,%zmm26"); @@ -613,6 +787,14 @@ int main(void) asm volatile("vpermb %zmm26,%zmm27,%zmm28"); asm volatile("vpermw %zmm26,%zmm27,%zmm28"); + /* AVX-512: Op code 0f 38 8f */ + + asm volatile("vpshufbitqmb %xmm1, %xmm2, %k3"); + asm volatile("vpshufbitqmb %ymm1, %ymm2, %k3"); + asm volatile("vpshufbitqmb %zmm1, %zmm2, %k3"); + asm volatile("vpshufbitqmb 0x12345678(%rax,%rcx,8),%zmm2,%k3"); + asm volatile("vpshufbitqmb 0x12345678(%eax,%ecx,8),%zmm2,%k3"); + /* AVX-512: Op code 0f 38 90 */ asm volatile("vpgatherdd %xmm2,0x02(%rbp,%xmm7,2),%xmm1"); @@ -627,6 +809,40 @@ int main(void) asm volatile("vpgatherqd 0x7b(%rbp,%zmm27,8),%ymm26{%k1}"); asm volatile("vpgatherqq 0x7b(%rbp,%zmm27,8),%zmm26{%k1}"); + /* AVX-512: Op code 0f 38 9a */ + + asm volatile("vfmsub132ps %xmm1, %xmm2, %xmm3"); + asm volatile("vfmsub132ps %ymm1, %ymm2, %ymm3"); + asm volatile("vfmsub132ps %zmm1, %zmm2, %zmm3"); + asm volatile("vfmsub132ps 0x12345678(%rax,%rcx,8),%zmm2,%zmm3"); + asm volatile("vfmsub132ps 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + asm volatile("vfmsub132pd %xmm1, %xmm2, %xmm3"); + asm volatile("vfmsub132pd %ymm1, %ymm2, %ymm3"); + asm volatile("vfmsub132pd %zmm1, %zmm2, %zmm3"); + asm volatile("vfmsub132pd 0x12345678(%rax,%rcx,8),%zmm2,%zmm3"); + asm volatile("vfmsub132pd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + asm volatile("v4fmaddps (%rax), %zmm0, %zmm4"); + asm volatile("v4fmaddps (%eax), %zmm0, %zmm4"); + asm volatile("v4fmaddps 0x12345678(%rax,%rcx,8),%zmm0,%zmm4"); + asm volatile("v4fmaddps 0x12345678(%eax,%ecx,8),%zmm0,%zmm4"); + + /* AVX-512: Op code 0f 38 9b */ + + asm volatile("vfmsub132ss %xmm1, %xmm2, %xmm3"); + asm volatile("vfmsub132ss 0x12345678(%rax,%rcx,8),%xmm2,%xmm3"); + asm volatile("vfmsub132ss 0x12345678(%eax,%ecx,8),%xmm2,%xmm3"); + + asm volatile("vfmsub132sd %xmm1, %xmm2, %xmm3"); + asm volatile("vfmsub132sd 0x12345678(%rax,%rcx,8),%xmm2,%xmm3"); + asm volatile("vfmsub132sd 0x12345678(%eax,%ecx,8),%xmm2,%xmm3"); + + asm volatile("v4fmaddss (%rax), %xmm0, %xmm4"); + asm volatile("v4fmaddss (%eax), %xmm0, %xmm4"); + asm volatile("v4fmaddss 0x12345678(%rax,%rcx,8),%xmm0,%xmm4"); + asm volatile("v4fmaddss 0x12345678(%eax,%ecx,8),%xmm0,%xmm4"); + /* AVX-512: Op code 0f 38 a0 */ asm volatile("vpscatterdd %zmm28,0x7b(%rbp,%zmm29,8){%k1}"); @@ -647,6 +863,40 @@ int main(void) asm volatile("vscatterqps %ymm6,0x7b(%rbp,%zmm29,8){%k1}"); asm volatile("vscatterqpd %zmm28,0x7b(%rbp,%zmm29,8){%k1}"); + /* AVX-512: Op code 0f 38 aa */ + + asm volatile("vfmsub213ps %xmm1, %xmm2, %xmm3"); + asm volatile("vfmsub213ps %ymm1, %ymm2, %ymm3"); + asm volatile("vfmsub213ps %zmm1, %zmm2, %zmm3"); + asm volatile("vfmsub213ps 0x12345678(%rax,%rcx,8),%zmm2,%zmm3"); + asm volatile("vfmsub213ps 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + asm volatile("vfmsub213pd %xmm1, %xmm2, %xmm3"); + asm volatile("vfmsub213pd %ymm1, %ymm2, %ymm3"); + asm volatile("vfmsub213pd %zmm1, %zmm2, %zmm3"); + asm volatile("vfmsub213pd 0x12345678(%rax,%rcx,8),%zmm2,%zmm3"); + asm volatile("vfmsub213pd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + asm volatile("v4fnmaddps (%rax), %zmm0, %zmm4"); + asm volatile("v4fnmaddps (%eax), %zmm0, %zmm4"); + asm volatile("v4fnmaddps 0x12345678(%rax,%rcx,8),%zmm0,%zmm4"); + asm volatile("v4fnmaddps 0x12345678(%eax,%ecx,8),%zmm0,%zmm4"); + + /* AVX-512: Op code 0f 38 ab */ + + asm volatile("vfmsub213ss %xmm1, %xmm2, %xmm3"); + asm volatile("vfmsub213ss 0x12345678(%rax,%rcx,8),%xmm2,%xmm3"); + asm volatile("vfmsub213ss 0x12345678(%eax,%ecx,8),%xmm2,%xmm3"); + + asm volatile("vfmsub213sd %xmm1, %xmm2, %xmm3"); + asm volatile("vfmsub213sd 0x12345678(%rax,%rcx,8),%xmm2,%xmm3"); + asm volatile("vfmsub213sd 0x12345678(%eax,%ecx,8),%xmm2,%xmm3"); + + asm volatile("v4fnmaddss (%rax), %xmm0, %xmm4"); + asm volatile("v4fnmaddss (%eax), %xmm0, %xmm4"); + asm volatile("v4fnmaddss 0x12345678(%rax,%rcx,8),%xmm0,%xmm4"); + asm volatile("v4fnmaddss 0x12345678(%eax,%ecx,8),%xmm0,%xmm4"); + /* AVX-512: Op code 0f 38 b4 */ asm volatile("vpmadd52luq %zmm26,%zmm27,%zmm28"); @@ -685,6 +935,50 @@ int main(void) asm volatile("vrsqrt28ss %xmm28,%xmm29,%xmm30{%k7}"); asm volatile("vrsqrt28sd %xmm25,%xmm26,%xmm27{%k7}"); + /* AVX-512: Op code 0f 38 cf */ + + asm volatile("gf2p8mulb %xmm1, %xmm3"); + asm volatile("gf2p8mulb 0x12345678(%rax,%rcx,8),%xmm3"); + asm volatile("gf2p8mulb 0x12345678(%eax,%ecx,8),%xmm3"); + + asm volatile("vgf2p8mulb %xmm1, %xmm2, %xmm3"); + asm volatile("vgf2p8mulb %ymm1, %ymm2, %ymm3"); + asm volatile("vgf2p8mulb %zmm1, %zmm2, %zmm3"); + asm volatile("vgf2p8mulb 0x12345678(%rax,%rcx,8),%zmm2,%zmm3"); + asm volatile("vgf2p8mulb 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 38 dc */ + + asm volatile("vaesenc %xmm1, %xmm2, %xmm3"); + asm volatile("vaesenc %ymm1, %ymm2, %ymm3"); + asm volatile("vaesenc %zmm1, %zmm2, %zmm3"); + asm volatile("vaesenc 0x12345678(%rax,%rcx,8),%zmm2,%zmm3"); + asm volatile("vaesenc 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 38 dd */ + + asm volatile("vaesenclast %xmm1, %xmm2, %xmm3"); + asm volatile("vaesenclast %ymm1, %ymm2, %ymm3"); + asm volatile("vaesenclast %zmm1, %zmm2, %zmm3"); + asm volatile("vaesenclast 0x12345678(%rax,%rcx,8),%zmm2,%zmm3"); + asm volatile("vaesenclast 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 38 de */ + + asm volatile("vaesdec %xmm1, %xmm2, %xmm3"); + asm volatile("vaesdec %ymm1, %ymm2, %ymm3"); + asm volatile("vaesdec %zmm1, %zmm2, %zmm3"); + asm volatile("vaesdec 0x12345678(%rax,%rcx,8),%zmm2,%zmm3"); + asm volatile("vaesdec 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 38 df */ + + asm volatile("vaesdeclast %xmm1, %xmm2, %xmm3"); + asm volatile("vaesdeclast %ymm1, %ymm2, %ymm3"); + asm volatile("vaesdeclast %zmm1, %zmm2, %zmm3"); + asm volatile("vaesdeclast 0x12345678(%rax,%rcx,8),%zmm2,%zmm3"); + asm volatile("vaesdeclast 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + /* AVX-512: Op code 0f 3a 03 */ asm volatile("valignd $0x12,%zmm28,%zmm29,%zmm30"); @@ -804,6 +1098,13 @@ int main(void) asm volatile("vshufi32x4 $0x12,%zmm25,%zmm26,%zmm27"); asm volatile("vshufi64x2 $0x12,%zmm28,%zmm29,%zmm30"); + /* AVX-512: Op code 0f 3a 44 */ + + asm volatile("vpclmulqdq $0x12,%xmm1,%xmm2,%xmm3"); + asm volatile("vpclmulqdq $0x12,%ymm1,%ymm2,%ymm3"); + asm volatile("vpclmulqdq $0x12,%zmm1,%zmm2,%zmm3"); + asm volatile("vpclmulqdq $0x12,%zmm25,%zmm26,%zmm27"); + /* AVX-512: Op code 0f 3a 50 */ asm volatile("vrangeps $0x12,%zmm25,%zmm26,%zmm27"); @@ -844,6 +1145,62 @@ int main(void) asm volatile("vfpclassss $0x12,%xmm27,%k5"); asm volatile("vfpclasssd $0x12,%xmm30,%k5"); + /* AVX-512: Op code 0f 3a 70 */ + + asm volatile("vpshldw $0x12,%xmm1,%xmm2,%xmm3"); + asm volatile("vpshldw $0x12,%ymm1,%ymm2,%ymm3"); + asm volatile("vpshldw $0x12,%zmm1,%zmm2,%zmm3"); + asm volatile("vpshldw $0x12,%zmm25,%zmm26,%zmm27"); + + /* AVX-512: Op code 0f 3a 71 */ + + asm volatile("vpshldd $0x12,%xmm1,%xmm2,%xmm3"); + asm volatile("vpshldd $0x12,%ymm1,%ymm2,%ymm3"); + asm volatile("vpshldd $0x12,%zmm1,%zmm2,%zmm3"); + asm volatile("vpshldd $0x12,%zmm25,%zmm26,%zmm27"); + + asm volatile("vpshldq $0x12,%xmm1,%xmm2,%xmm3"); + asm volatile("vpshldq $0x12,%ymm1,%ymm2,%ymm3"); + asm volatile("vpshldq $0x12,%zmm1,%zmm2,%zmm3"); + asm volatile("vpshldq $0x12,%zmm25,%zmm26,%zmm27"); + + /* AVX-512: Op code 0f 3a 72 */ + + asm volatile("vpshrdw $0x12,%xmm1,%xmm2,%xmm3"); + asm volatile("vpshrdw $0x12,%ymm1,%ymm2,%ymm3"); + asm volatile("vpshrdw $0x12,%zmm1,%zmm2,%zmm3"); + asm volatile("vpshrdw $0x12,%zmm25,%zmm26,%zmm27"); + + /* AVX-512: Op code 0f 3a 73 */ + + asm volatile("vpshrdd $0x12,%xmm1,%xmm2,%xmm3"); + asm volatile("vpshrdd $0x12,%ymm1,%ymm2,%ymm3"); + asm volatile("vpshrdd $0x12,%zmm1,%zmm2,%zmm3"); + asm volatile("vpshrdd $0x12,%zmm25,%zmm26,%zmm27"); + + asm volatile("vpshrdq $0x12,%xmm1,%xmm2,%xmm3"); + asm volatile("vpshrdq $0x12,%ymm1,%ymm2,%ymm3"); + asm volatile("vpshrdq $0x12,%zmm1,%zmm2,%zmm3"); + asm volatile("vpshrdq $0x12,%zmm25,%zmm26,%zmm27"); + + /* AVX-512: Op code 0f 3a ce */ + + asm volatile("gf2p8affineqb $0x12,%xmm1,%xmm3"); + + asm volatile("vgf2p8affineqb $0x12,%xmm1,%xmm2,%xmm3"); + asm volatile("vgf2p8affineqb $0x12,%ymm1,%ymm2,%ymm3"); + asm volatile("vgf2p8affineqb $0x12,%zmm1,%zmm2,%zmm3"); + asm volatile("vgf2p8affineqb $0x12,%zmm25,%zmm26,%zmm27"); + + /* AVX-512: Op code 0f 3a cf */ + + asm volatile("gf2p8affineinvqb $0x12,%xmm1,%xmm3"); + + asm volatile("vgf2p8affineinvqb $0x12,%xmm1,%xmm2,%xmm3"); + asm volatile("vgf2p8affineinvqb $0x12,%ymm1,%ymm2,%ymm3"); + asm volatile("vgf2p8affineinvqb $0x12,%zmm1,%zmm2,%zmm3"); + asm volatile("vgf2p8affineinvqb $0x12,%zmm25,%zmm26,%zmm27"); + /* AVX-512: Op code 0f 72 (Grp13) */ asm volatile("vprord $0x12,%zmm25,%zmm26"); @@ -1946,6 +2303,69 @@ int main(void) asm volatile("vrsqrt14ss %xmm4,%xmm5,%xmm6{%k7}"); asm volatile("vrsqrt14sd %xmm4,%xmm5,%xmm6{%k7}"); + /* AVX-512: Op code 0f 38 50 */ + + asm volatile("vpdpbusd %xmm1, %xmm2, %xmm3"); + asm volatile("vpdpbusd %ymm1, %ymm2, %ymm3"); + asm volatile("vpdpbusd %zmm1, %zmm2, %zmm3"); + asm volatile("vpdpbusd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 38 51 */ + + asm volatile("vpdpbusds %xmm1, %xmm2, %xmm3"); + asm volatile("vpdpbusds %ymm1, %ymm2, %ymm3"); + asm volatile("vpdpbusds %zmm1, %zmm2, %zmm3"); + asm volatile("vpdpbusds 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 38 52 */ + + asm volatile("vdpbf16ps %xmm1, %xmm2, %xmm3"); + asm volatile("vdpbf16ps %ymm1, %ymm2, %ymm3"); + asm volatile("vdpbf16ps %zmm1, %zmm2, %zmm3"); + asm volatile("vdpbf16ps 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + asm volatile("vpdpwssd %xmm1, %xmm2, %xmm3"); + asm volatile("vpdpwssd %ymm1, %ymm2, %ymm3"); + asm volatile("vpdpwssd %zmm1, %zmm2, %zmm3"); + asm volatile("vpdpwssd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + asm volatile("vp4dpwssd (%eax), %zmm0, %zmm4"); + asm volatile("vp4dpwssd 0x12345678(%eax,%ecx,8),%zmm0,%zmm4"); + + /* AVX-512: Op code 0f 38 53 */ + + asm volatile("vpdpwssds %xmm1, %xmm2, %xmm3"); + asm volatile("vpdpwssds %ymm1, %ymm2, %ymm3"); + asm volatile("vpdpwssds %zmm1, %zmm2, %zmm3"); + asm volatile("vpdpwssds 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + asm volatile("vp4dpwssds (%eax), %zmm0, %zmm4"); + asm volatile("vp4dpwssds 0x12345678(%eax,%ecx,8),%zmm0,%zmm4"); + + /* AVX-512: Op code 0f 38 54 */ + + asm volatile("vpopcntb %xmm1, %xmm2"); + asm volatile("vpopcntb %ymm1, %ymm2"); + asm volatile("vpopcntb %zmm1, %zmm2"); + asm volatile("vpopcntb 0x12345678(%eax,%ecx,8),%zmm2"); + + asm volatile("vpopcntw %xmm1, %xmm2"); + asm volatile("vpopcntw %ymm1, %ymm2"); + asm volatile("vpopcntw %zmm1, %zmm2"); + asm volatile("vpopcntw 0x12345678(%eax,%ecx,8),%zmm2"); + + /* AVX-512: Op code 0f 38 55 */ + + asm volatile("vpopcntd %xmm1, %xmm2"); + asm volatile("vpopcntd %ymm1, %ymm2"); + asm volatile("vpopcntd %zmm1, %zmm2"); + asm volatile("vpopcntd 0x12345678(%eax,%ecx,8),%zmm2"); + + asm volatile("vpopcntq %xmm1, %xmm2"); + asm volatile("vpopcntq %ymm1, %ymm2"); + asm volatile("vpopcntq %zmm1, %zmm2"); + asm volatile("vpopcntq 0x12345678(%eax,%ecx,8),%zmm2"); + /* AVX-512: Op code 0f 38 59 */ asm volatile("vpbroadcastq %xmm4,%xmm6"); @@ -1962,6 +2382,30 @@ int main(void) asm volatile("vbroadcasti32x8 (%ecx),%zmm6"); asm volatile("vbroadcasti64x4 (%ecx),%zmm6"); + /* AVX-512: Op code 0f 38 62 */ + + asm volatile("vpexpandb %xmm1, %xmm2"); + asm volatile("vpexpandb %ymm1, %ymm2"); + asm volatile("vpexpandb %zmm1, %zmm2"); + asm volatile("vpexpandb 0x12345678(%eax,%ecx,8),%zmm2"); + + asm volatile("vpexpandw %xmm1, %xmm2"); + asm volatile("vpexpandw %ymm1, %ymm2"); + asm volatile("vpexpandw %zmm1, %zmm2"); + asm volatile("vpexpandw 0x12345678(%eax,%ecx,8),%zmm2"); + + /* AVX-512: Op code 0f 38 63 */ + + asm volatile("vpcompressb %xmm1, %xmm2"); + asm volatile("vpcompressb %ymm1, %ymm2"); + asm volatile("vpcompressb %zmm1, %zmm2"); + asm volatile("vpcompressb %zmm2,0x12345678(%eax,%ecx,8)"); + + asm volatile("vpcompressw %xmm1, %xmm2"); + asm volatile("vpcompressw %ymm1, %ymm2"); + asm volatile("vpcompressw %zmm1, %zmm2"); + asm volatile("vpcompressw %zmm2,0x12345678(%eax,%ecx,8)"); + /* AVX-512: Op code 0f 38 64 */ asm volatile("vpblendmd %zmm4,%zmm5,%zmm6"); @@ -1977,6 +2421,66 @@ int main(void) asm volatile("vpblendmb %zmm4,%zmm5,%zmm6"); asm volatile("vpblendmw %zmm4,%zmm5,%zmm6"); + /* AVX-512: Op code 0f 38 68 */ + + asm volatile("vp2intersectd %xmm1, %xmm2, %k3"); + asm volatile("vp2intersectd %ymm1, %ymm2, %k3"); + asm volatile("vp2intersectd %zmm1, %zmm2, %k3"); + asm volatile("vp2intersectd 0x12345678(%eax,%ecx,8),%zmm2,%k3"); + + asm volatile("vp2intersectq %xmm1, %xmm2, %k3"); + asm volatile("vp2intersectq %ymm1, %ymm2, %k3"); + asm volatile("vp2intersectq %zmm1, %zmm2, %k3"); + asm volatile("vp2intersectq 0x12345678(%eax,%ecx,8),%zmm2,%k3"); + + /* AVX-512: Op code 0f 38 70 */ + + asm volatile("vpshldvw %xmm1, %xmm2, %xmm3"); + asm volatile("vpshldvw %ymm1, %ymm2, %ymm3"); + asm volatile("vpshldvw %zmm1, %zmm2, %zmm3"); + asm volatile("vpshldvw 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 38 71 */ + + asm volatile("vpshldvd %xmm1, %xmm2, %xmm3"); + asm volatile("vpshldvd %ymm1, %ymm2, %ymm3"); + asm volatile("vpshldvd %zmm1, %zmm2, %zmm3"); + asm volatile("vpshldvd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + asm volatile("vpshldvq %xmm1, %xmm2, %xmm3"); + asm volatile("vpshldvq %ymm1, %ymm2, %ymm3"); + asm volatile("vpshldvq %zmm1, %zmm2, %zmm3"); + asm volatile("vpshldvq 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 38 72 */ + + asm volatile("vcvtne2ps2bf16 %xmm1, %xmm2, %xmm3"); + asm volatile("vcvtne2ps2bf16 %ymm1, %ymm2, %ymm3"); + asm volatile("vcvtne2ps2bf16 %zmm1, %zmm2, %zmm3"); + asm volatile("vcvtne2ps2bf16 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + asm volatile("vcvtneps2bf16 %xmm1, %xmm2"); + asm volatile("vcvtneps2bf16 %ymm1, %xmm2"); + asm volatile("vcvtneps2bf16 %zmm1, %ymm2"); + asm volatile("vcvtneps2bf16 0x12345678(%eax,%ecx,8),%ymm2"); + + asm volatile("vpshrdvw %xmm1, %xmm2, %xmm3"); + asm volatile("vpshrdvw %ymm1, %ymm2, %ymm3"); + asm volatile("vpshrdvw %zmm1, %zmm2, %zmm3"); + asm volatile("vpshrdvw 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 38 73 */ + + asm volatile("vpshrdvd %xmm1, %xmm2, %xmm3"); + asm volatile("vpshrdvd %ymm1, %ymm2, %ymm3"); + asm volatile("vpshrdvd %zmm1, %zmm2, %zmm3"); + asm volatile("vpshrdvd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + asm volatile("vpshrdvq %xmm1, %xmm2, %xmm3"); + asm volatile("vpshrdvq %ymm1, %ymm2, %ymm3"); + asm volatile("vpshrdvq %zmm1, %zmm2, %zmm3"); + asm volatile("vpshrdvq 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + /* AVX-512: Op code 0f 38 75 */ asm volatile("vpermi2b %zmm4,%zmm5,%zmm6"); @@ -2048,6 +2552,13 @@ int main(void) asm volatile("vpermb %zmm4,%zmm5,%zmm6"); asm volatile("vpermw %zmm4,%zmm5,%zmm6"); + /* AVX-512: Op code 0f 38 8f */ + + asm volatile("vpshufbitqmb %xmm1, %xmm2, %k3"); + asm volatile("vpshufbitqmb %ymm1, %ymm2, %k3"); + asm volatile("vpshufbitqmb %zmm1, %zmm2, %k3"); + asm volatile("vpshufbitqmb 0x12345678(%eax,%ecx,8),%zmm2,%k3"); + /* AVX-512: Op code 0f 38 90 */ asm volatile("vpgatherdd %xmm2,0x02(%ebp,%xmm7,2),%xmm1"); @@ -2062,6 +2573,32 @@ int main(void) asm volatile("vpgatherqd 0x7b(%ebp,%zmm7,8),%ymm6{%k1}"); asm volatile("vpgatherqq 0x7b(%ebp,%zmm7,8),%zmm6{%k1}"); + /* AVX-512: Op code 0f 38 9a */ + + asm volatile("vfmsub132ps %xmm1, %xmm2, %xmm3"); + asm volatile("vfmsub132ps %ymm1, %ymm2, %ymm3"); + asm volatile("vfmsub132ps %zmm1, %zmm2, %zmm3"); + asm volatile("vfmsub132ps 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + asm volatile("vfmsub132pd %xmm1, %xmm2, %xmm3"); + asm volatile("vfmsub132pd %ymm1, %ymm2, %ymm3"); + asm volatile("vfmsub132pd %zmm1, %zmm2, %zmm3"); + asm volatile("vfmsub132pd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + asm volatile("v4fmaddps (%eax), %zmm0, %zmm4"); + asm volatile("v4fmaddps 0x12345678(%eax,%ecx,8),%zmm0,%zmm4"); + + /* AVX-512: Op code 0f 38 9b */ + + asm volatile("vfmsub132ss %xmm1, %xmm2, %xmm3"); + asm volatile("vfmsub132ss 0x12345678(%eax,%ecx,8),%xmm2,%xmm3"); + + asm volatile("vfmsub132sd %xmm1, %xmm2, %xmm3"); + asm volatile("vfmsub132sd 0x12345678(%eax,%ecx,8),%xmm2,%xmm3"); + + asm volatile("v4fmaddss (%eax), %xmm0, %xmm4"); + asm volatile("v4fmaddss 0x12345678(%eax,%ecx,8),%xmm0,%xmm4"); + /* AVX-512: Op code 0f 38 a0 */ asm volatile("vpscatterdd %zmm6,0x7b(%ebp,%zmm7,8){%k1}"); @@ -2082,6 +2619,32 @@ int main(void) asm volatile("vscatterqps %ymm6,0x7b(%ebp,%zmm7,8){%k1}"); asm volatile("vscatterqpd %zmm6,0x7b(%ebp,%zmm7,8){%k1}"); + /* AVX-512: Op code 0f 38 aa */ + + asm volatile("vfmsub213ps %xmm1, %xmm2, %xmm3"); + asm volatile("vfmsub213ps %ymm1, %ymm2, %ymm3"); + asm volatile("vfmsub213ps %zmm1, %zmm2, %zmm3"); + asm volatile("vfmsub213ps 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + asm volatile("vfmsub213pd %xmm1, %xmm2, %xmm3"); + asm volatile("vfmsub213pd %ymm1, %ymm2, %ymm3"); + asm volatile("vfmsub213pd %zmm1, %zmm2, %zmm3"); + asm volatile("vfmsub213pd 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + asm volatile("v4fnmaddps (%eax), %zmm0, %zmm4"); + asm volatile("v4fnmaddps 0x12345678(%eax,%ecx,8),%zmm0,%zmm4"); + + /* AVX-512: Op code 0f 38 ab */ + + asm volatile("vfmsub213ss %xmm1, %xmm2, %xmm3"); + asm volatile("vfmsub213ss 0x12345678(%eax,%ecx,8),%xmm2,%xmm3"); + + asm volatile("vfmsub213sd %xmm1, %xmm2, %xmm3"); + asm volatile("vfmsub213sd 0x12345678(%eax,%ecx,8),%xmm2,%xmm3"); + + asm volatile("v4fnmaddss (%eax), %xmm0, %xmm4"); + asm volatile("v4fnmaddss 0x12345678(%eax,%ecx,8),%xmm0,%xmm4"); + /* AVX-512: Op code 0f 38 b4 */ asm volatile("vpmadd52luq %zmm4,%zmm5,%zmm6"); @@ -2120,6 +2683,44 @@ int main(void) asm volatile("vrsqrt28ss %xmm5,%xmm6,%xmm7{%k7}"); asm volatile("vrsqrt28sd %xmm5,%xmm6,%xmm7{%k7}"); + /* AVX-512: Op code 0f 38 cf */ + + asm volatile("gf2p8mulb %xmm1, %xmm3"); + asm volatile("gf2p8mulb 0x12345678(%eax,%ecx,8),%xmm3"); + + asm volatile("vgf2p8mulb %xmm1, %xmm2, %xmm3"); + asm volatile("vgf2p8mulb %ymm1, %ymm2, %ymm3"); + asm volatile("vgf2p8mulb %zmm1, %zmm2, %zmm3"); + asm volatile("vgf2p8mulb 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 38 dc */ + + asm volatile("vaesenc %xmm1, %xmm2, %xmm3"); + asm volatile("vaesenc %ymm1, %ymm2, %ymm3"); + asm volatile("vaesenc %zmm1, %zmm2, %zmm3"); + asm volatile("vaesenc 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 38 dd */ + + asm volatile("vaesenclast %xmm1, %xmm2, %xmm3"); + asm volatile("vaesenclast %ymm1, %ymm2, %ymm3"); + asm volatile("vaesenclast %zmm1, %zmm2, %zmm3"); + asm volatile("vaesenclast 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 38 de */ + + asm volatile("vaesdec %xmm1, %xmm2, %xmm3"); + asm volatile("vaesdec %ymm1, %ymm2, %ymm3"); + asm volatile("vaesdec %zmm1, %zmm2, %zmm3"); + asm volatile("vaesdec 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 38 df */ + + asm volatile("vaesdeclast %xmm1, %xmm2, %xmm3"); + asm volatile("vaesdeclast %ymm1, %ymm2, %ymm3"); + asm volatile("vaesdeclast %zmm1, %zmm2, %zmm3"); + asm volatile("vaesdeclast 0x12345678(%eax,%ecx,8),%zmm2,%zmm3"); + /* AVX-512: Op code 0f 3a 03 */ asm volatile("valignd $0x12,%zmm5,%zmm6,%zmm7"); @@ -2239,6 +2840,12 @@ int main(void) asm volatile("vshufi32x4 $0x12,%zmm5,%zmm6,%zmm7"); asm volatile("vshufi64x2 $0x12,%zmm5,%zmm6,%zmm7"); + /* AVX-512: Op code 0f 3a 44 */ + + asm volatile("vpclmulqdq $0x12,%xmm1,%xmm2,%xmm3"); + asm volatile("vpclmulqdq $0x12,%ymm1,%ymm2,%ymm3"); + asm volatile("vpclmulqdq $0x12,%zmm1,%zmm2,%zmm3"); + /* AVX-512: Op code 0f 3a 50 */ asm volatile("vrangeps $0x12,%zmm5,%zmm6,%zmm7"); @@ -2279,6 +2886,54 @@ int main(void) asm volatile("vfpclassss $0x12,%xmm7,%k5"); asm volatile("vfpclasssd $0x12,%xmm7,%k5"); + /* AVX-512: Op code 0f 3a 70 */ + + asm volatile("vpshldw $0x12,%xmm1,%xmm2,%xmm3"); + asm volatile("vpshldw $0x12,%ymm1,%ymm2,%ymm3"); + asm volatile("vpshldw $0x12,%zmm1,%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 3a 71 */ + + asm volatile("vpshldd $0x12,%xmm1,%xmm2,%xmm3"); + asm volatile("vpshldd $0x12,%ymm1,%ymm2,%ymm3"); + asm volatile("vpshldd $0x12,%zmm1,%zmm2,%zmm3"); + + asm volatile("vpshldq $0x12,%xmm1,%xmm2,%xmm3"); + asm volatile("vpshldq $0x12,%ymm1,%ymm2,%ymm3"); + asm volatile("vpshldq $0x12,%zmm1,%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 3a 72 */ + + asm volatile("vpshrdw $0x12,%xmm1,%xmm2,%xmm3"); + asm volatile("vpshrdw $0x12,%ymm1,%ymm2,%ymm3"); + asm volatile("vpshrdw $0x12,%zmm1,%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 3a 73 */ + + asm volatile("vpshrdd $0x12,%xmm1,%xmm2,%xmm3"); + asm volatile("vpshrdd $0x12,%ymm1,%ymm2,%ymm3"); + asm volatile("vpshrdd $0x12,%zmm1,%zmm2,%zmm3"); + + asm volatile("vpshrdq $0x12,%xmm1,%xmm2,%xmm3"); + asm volatile("vpshrdq $0x12,%ymm1,%ymm2,%ymm3"); + asm volatile("vpshrdq $0x12,%zmm1,%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 3a ce */ + + asm volatile("gf2p8affineqb $0x12,%xmm1,%xmm3"); + + asm volatile("vgf2p8affineqb $0x12,%xmm1,%xmm2,%xmm3"); + asm volatile("vgf2p8affineqb $0x12,%ymm1,%ymm2,%ymm3"); + asm volatile("vgf2p8affineqb $0x12,%zmm1,%zmm2,%zmm3"); + + /* AVX-512: Op code 0f 3a cf */ + + asm volatile("gf2p8affineinvqb $0x12,%xmm1,%xmm3"); + + asm volatile("vgf2p8affineinvqb $0x12,%xmm1,%xmm2,%xmm3"); + asm volatile("vgf2p8affineinvqb $0x12,%ymm1,%ymm2,%ymm3"); + asm volatile("vgf2p8affineinvqb $0x12,%zmm1,%zmm2,%zmm3"); + /* AVX-512: Op code 0f 72 (Grp13) */ asm volatile("vprord $0x12,%zmm5,%zmm6"); diff --git a/tools/perf/arch/x86/util/event.c b/tools/perf/arch/x86/util/event.c index d1044df7c0d7..ac45015cc6ba 100644 --- a/tools/perf/arch/x86/util/event.c +++ b/tools/perf/arch/x86/util/event.c @@ -18,8 +18,7 @@ int perf_event__synthesize_extra_kmaps(struct perf_tool *tool, { int rc = 0; struct map *pos; - struct map_groups *kmaps = &machine->kmaps; - struct maps *maps = &kmaps->maps; + struct maps *kmaps = &machine->kmaps; union perf_event *event = zalloc(sizeof(event->mmap) + machine->id_hdr_size); @@ -29,7 +28,7 @@ int perf_event__synthesize_extra_kmaps(struct perf_tool *tool, return -1; } - maps__for_each_entry(maps, pos) { + maps__for_each_entry(kmaps, pos) { struct kmap *kmap; size_t size; diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 376dbf10ad64..f8b6ae557d8b 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -547,8 +547,8 @@ static int64_t block_cycles_diff_cmp(struct hist_entry *left, if (!pairs_left && !pairs_right) return 0; - l = labs(left->diff.cycles); - r = labs(right->diff.cycles); + l = llabs(left->diff.cycles); + r = llabs(right->diff.cycles); return r - l; } @@ -646,7 +646,7 @@ static void compute_cycles_diff(struct hist_entry *he, if (i >= he->block_info->num || i >= NUM_SPARKS) break; - val = labs(pair->block_info->cycles_spark[i] - + val = llabs(pair->block_info->cycles_spark[i] - he->block_info->cycles_spark[i]); update_spark_value(pair->diff.svals, NUM_SPARKS, diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index ab0f6e516b03..830d563de889 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -780,11 +780,6 @@ static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp) return printed; } -static int map_groups__fprintf_task(struct map_groups *mg, int indent, FILE *fp) -{ - return maps__fprintf_task(&mg->maps, indent, fp); -} - static void task__print_level(struct task *task, FILE *fp, int level) { struct thread *thread = task->thread; @@ -795,7 +790,7 @@ static void task__print_level(struct task *task, FILE *fp, int level) fprintf(fp, "%s\n", thread__comm_str(thread)); - map_groups__fprintf_task(thread->mg, comm_indent, fp); + maps__fprintf_task(thread->maps, comm_indent, fp); if (!list_empty(&task->children)) { list_for_each_entry(child, &task->children, list) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index f86c5cce5b2c..e2406b291c1c 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -448,7 +448,7 @@ static int perf_evsel__check_attr(struct evsel *evsel, "selected. Hence, no address to lookup the source line number.\n"); return -EINVAL; } - if (PRINT_FIELD(BRSTACKINSN) && + if (PRINT_FIELD(BRSTACKINSN) && !allow_user_set && !(perf_evlist__combined_branch_type(session->evlist) & PERF_SAMPLE_BRANCH_ANY)) { pr_err("Display of branch stack assembler requested, but non all-branch filter set\n" @@ -932,6 +932,48 @@ static int grab_bb(u8 *buffer, u64 start, u64 end, return len; } +static int map__fprintf_srccode(struct map *map, u64 addr, FILE *fp, struct srccode_state *state) +{ + char *srcfile; + int ret = 0; + unsigned line; + int len; + char *srccode; + + if (!map || !map->dso) + return 0; + srcfile = get_srcline_split(map->dso, + map__rip_2objdump(map, addr), + &line); + if (!srcfile) + return 0; + + /* Avoid redundant printing */ + if (state && + state->srcfile && + !strcmp(state->srcfile, srcfile) && + state->line == line) { + free(srcfile); + return 0; + } + + srccode = find_sourceline(srcfile, line, &len); + if (!srccode) + goto out_free_line; + + ret = fprintf(fp, "|%-8d %.*s", line, len, srccode); + + if (state) { + state->srcfile = srcfile; + state->line = line; + } + return ret; + +out_free_line: + free(srcfile); + return ret; +} + static int print_srccode(struct thread *thread, u8 cpumode, uint64_t addr) { struct addr_location al; @@ -1084,7 +1126,7 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample, insn++; } } - if (off != (unsigned)len) + if (off != end - start) printed += fprintf(fp, "\tmismatch of LBR data and executable\n"); } diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index e72accefd669..a3c595fba943 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -27,7 +27,7 @@ perf-y += wp.o perf-y += task-exit.o perf-y += sw-clock.o perf-y += mmap-thread-lookup.o -perf-y += thread-mg-share.o +perf-y += thread-maps-share.o perf-y += switch-tracking.o perf-y += keep-tracking.o perf-y += code-reading.o @@ -52,7 +52,7 @@ perf-y += perf-hooks.o perf-y += clang.o perf-y += unit_number__scnprintf.o perf-y += mem2node.o -perf-y += map_groups.o +perf-y += maps.o perf-y += time-utils-test.o $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 8b286e9b7549..7115aa32a51e 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -166,8 +166,8 @@ static struct test generic_tests[] = { .func = test__mmap_thread_lookup, }, { - .desc = "Share thread mg", - .func = test__thread_mg_share, + .desc = "Share thread maps", + .func = test__thread_maps_share, }, { .desc = "Sort output of hist entries", @@ -297,8 +297,8 @@ static struct test generic_tests[] = { .func = test__time_utils, }, { - .desc = "map_groups__merge_in", - .func = test__map_groups__merge_in, + .desc = "maps__merge_in", + .func = test__maps__merge_in, }, { .func = NULL, diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 1f017e1b2a55..6fe221d31f07 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -276,7 +276,7 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, len = al.map->end - addr; /* Read the object code using perf */ - ret_len = dso__data_read_offset(al.map->dso, thread->mg->machine, + ret_len = dso__data_read_offset(al.map->dso, thread->maps->machine, al.addr, buf1, len); if (ret_len != len) { pr_debug("dso__data_read_offset failed\n"); diff --git a/tools/perf/tests/map_groups.c b/tools/perf/tests/maps.c index 6b9f1cdcbe5b..edcbc70ff9d6 100644 --- a/tools/perf/tests/map_groups.c +++ b/tools/perf/tests/maps.c @@ -3,7 +3,7 @@ #include <linux/kernel.h> #include "tests.h" #include "map.h" -#include "map_groups.h" +#include "maps.h" #include "dso.h" #include "debug.h" @@ -13,12 +13,12 @@ struct map_def { u64 end; }; -static int check_maps(struct map_def *merged, unsigned int size, struct map_groups *mg) +static int check_maps(struct map_def *merged, unsigned int size, struct maps *maps) { struct map *map; unsigned int i = 0; - map_groups__for_each_entry(mg, map) { + maps__for_each_entry(maps, map) { if (i > 0) TEST_ASSERT_VAL("less maps expected", (map && i < size) || (!map && i == size)); @@ -33,9 +33,9 @@ static int check_maps(struct map_def *merged, unsigned int size, struct map_grou return TEST_OK; } -int test__map_groups__merge_in(struct test *t __maybe_unused, int subtest __maybe_unused) +int test__maps__merge_in(struct test *t __maybe_unused, int subtest __maybe_unused) { - struct map_groups mg; + struct maps maps; unsigned int i; struct map_def bpf_progs[] = { { "bpf_prog_1", 200, 300 }, @@ -64,7 +64,7 @@ int test__map_groups__merge_in(struct test *t __maybe_unused, int subtest __mayb struct map *map_kcore1, *map_kcore2, *map_kcore3; int ret; - map_groups__init(&mg, NULL); + maps__init(&maps, NULL); for (i = 0; i < ARRAY_SIZE(bpf_progs); i++) { struct map *map; @@ -74,7 +74,7 @@ int test__map_groups__merge_in(struct test *t __maybe_unused, int subtest __mayb map->start = bpf_progs[i].start; map->end = bpf_progs[i].end; - map_groups__insert(&mg, map); + maps__insert(&maps, map); map__put(map); } @@ -99,22 +99,22 @@ int test__map_groups__merge_in(struct test *t __maybe_unused, int subtest __mayb map_kcore3->start = 880; map_kcore3->end = 1100; - ret = map_groups__merge_in(&mg, map_kcore1); + ret = maps__merge_in(&maps, map_kcore1); TEST_ASSERT_VAL("failed to merge map", !ret); - ret = check_maps(merged12, ARRAY_SIZE(merged12), &mg); + ret = check_maps(merged12, ARRAY_SIZE(merged12), &maps); TEST_ASSERT_VAL("merge check failed", !ret); - ret = map_groups__merge_in(&mg, map_kcore2); + ret = maps__merge_in(&maps, map_kcore2); TEST_ASSERT_VAL("failed to merge map", !ret); - ret = check_maps(merged12, ARRAY_SIZE(merged12), &mg); + ret = check_maps(merged12, ARRAY_SIZE(merged12), &maps); TEST_ASSERT_VAL("merge check failed", !ret); - ret = map_groups__merge_in(&mg, map_kcore3); + ret = maps__merge_in(&maps, map_kcore3); TEST_ASSERT_VAL("failed to merge map", !ret); - ret = check_maps(merged3, ARRAY_SIZE(merged3), &mg); + ret = check_maps(merged3, ARRAY_SIZE(merged3), &maps); TEST_ASSERT_VAL("merge check failed", !ret); return TEST_OK; } diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 9837b6e93023..25aea387e2bf 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -73,7 +73,7 @@ int test__dwarf_unwind(struct test *test, int subtest); int test__expr(struct test *test, int subtest); int test__hists_filter(struct test *test, int subtest); int test__mmap_thread_lookup(struct test *test, int subtest); -int test__thread_mg_share(struct test *test, int subtest); +int test__thread_maps_share(struct test *test, int subtest); int test__hists_output(struct test *test, int subtest); int test__hists_cumulate(struct test *test, int subtest); int test__switch_tracking(struct test *test, int subtest); @@ -107,7 +107,7 @@ const char *test__clang_subtest_get_desc(int subtest); int test__clang_subtest_get_nr(void); int test__unit_number__scnprint(struct test *test, int subtest); int test__mem2node(struct test *t, int subtest); -int test__map_groups__merge_in(struct test *t, int subtest); +int test__maps__merge_in(struct test *t, int subtest); int test__time_utils(struct test *t, int subtest); bool test__bp_signal_is_supported(void); diff --git a/tools/perf/tests/thread-mg-share.c b/tools/perf/tests/thread-maps-share.c index cbac71716dec..9371484973f2 100644 --- a/tools/perf/tests/thread-mg-share.c +++ b/tools/perf/tests/thread-maps-share.c @@ -4,7 +4,7 @@ #include "thread.h" #include "debug.h" -int test__thread_mg_share(struct test *test __maybe_unused, int subtest __maybe_unused) +int test__thread_maps_share(struct test *test __maybe_unused, int subtest __maybe_unused) { struct machines machines; struct machine *machine; @@ -12,16 +12,16 @@ int test__thread_mg_share(struct test *test __maybe_unused, int subtest __maybe_ /* thread group */ struct thread *leader; struct thread *t1, *t2, *t3; - struct map_groups *mg; + struct maps *maps; /* other process */ struct thread *other, *other_leader; - struct map_groups *other_mg; + struct maps *other_maps; /* * This test create 2 processes abstractions (struct thread) * with several threads and checks they properly share and - * maintain map groups info (struct map_groups). + * maintain maps info (struct maps). * * thread group (pid: 0, tids: 0, 1, 2, 3) * other group (pid: 4, tids: 4, 5) @@ -42,17 +42,17 @@ int test__thread_mg_share(struct test *test __maybe_unused, int subtest __maybe_ TEST_ASSERT_VAL("failed to create threads", leader && t1 && t2 && t3 && other); - mg = leader->mg; - TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&mg->refcnt), 4); + maps = leader->maps; + TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 4); - /* test the map groups pointer is shared */ - TEST_ASSERT_VAL("map groups don't match", mg == t1->mg); - TEST_ASSERT_VAL("map groups don't match", mg == t2->mg); - TEST_ASSERT_VAL("map groups don't match", mg == t3->mg); + /* test the maps pointer is shared */ + TEST_ASSERT_VAL("maps don't match", maps == t1->maps); + TEST_ASSERT_VAL("maps don't match", maps == t2->maps); + TEST_ASSERT_VAL("maps don't match", maps == t3->maps); /* * Verify the other leader was created by previous call. - * It should have shared map groups with no change in + * It should have shared maps with no change in * refcnt. */ other_leader = machine__find_thread(machine, 4, 4); @@ -70,26 +70,26 @@ int test__thread_mg_share(struct test *test __maybe_unused, int subtest __maybe_ machine__remove_thread(machine, other); machine__remove_thread(machine, other_leader); - other_mg = other->mg; - TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&other_mg->refcnt), 2); + other_maps = other->maps; + TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&other_maps->refcnt), 2); - TEST_ASSERT_VAL("map groups don't match", other_mg == other_leader->mg); + TEST_ASSERT_VAL("maps don't match", other_maps == other_leader->maps); /* release thread group */ thread__put(leader); - TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&mg->refcnt), 3); + TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 3); thread__put(t1); - TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&mg->refcnt), 2); + TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 2); thread__put(t2); - TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&mg->refcnt), 1); + TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 1); thread__put(t3); /* release other group */ thread__put(other_leader); - TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&other_mg->refcnt), 1); + TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&other_maps->refcnt), 1); thread__put(other); diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c index ff649078da9a..193b7c91b4e2 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -190,10 +190,9 @@ next_pair: * so use the short name, less descriptive but the same ("[kernel]" in * both cases. */ - pair = map_groups__find_by_name(&kallsyms.kmaps, - (map->dso->kernel ? - map->dso->short_name : - map->dso->name)); + pair = maps__find_by_name(&kallsyms.kmaps, (map->dso->kernel ? + map->dso->short_name : + map->dso->name)); if (pair) { pair->priv = 1; } else { @@ -213,7 +212,7 @@ next_pair: mem_start = vmlinux_map->unmap_ip(vmlinux_map, map->start); mem_end = vmlinux_map->unmap_ip(vmlinux_map, map->end); - pair = map_groups__find(&kallsyms.kmaps, mem_start); + pair = maps__find(&kallsyms.kmaps, mem_start); if (pair == NULL || pair->priv) continue; diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 992705c78bd0..badbddbb30f8 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -430,7 +430,7 @@ static bool annotate_browser__callq(struct annotate_browser *browser, return true; } - target_ms.mg = ms->mg; + target_ms.maps = ms->maps; target_ms.map = ms->map; target_ms.sym = dl->ops.target.sym; pthread_mutex_unlock(¬es->lock); diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index 132056c7d5b7..2ab2af4d4849 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c @@ -8,7 +8,7 @@ #include "../../util/event.h" #include "../../util/hist.h" #include "../../util/map.h" -#include "../../util/map_groups.h" +#include "../../util/maps.h" #include "../../util/symbol.h" #include "../../util/sort.h" #include "../../util/evsel.h" @@ -885,7 +885,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, } if (h->ms.map == NULL && verbose > 1) { - map_groups__fprintf(h->thread->mg, fp); + maps__fprintf(h->thread->maps, fp); fprintf(fp, "%.10s end\n", graph_dotted_line); } } diff --git a/tools/perf/util/Build b/tools/perf/util/Build index b8e05a147b2b..07da6c790b63 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -49,6 +49,7 @@ perf-y += header.o perf-y += callchain.o perf-y += values.o perf-y += debug.o +perf-y += fncache.o perf-y += machine.o perf-y += map.o perf-y += pstack.o @@ -76,6 +77,7 @@ perf-y += sort.o perf-y += hist.o perf-y += util.o perf-y += cpumap.o +perf-y += affinity.o perf-y += cputopo.o perf-y += cgroup.o perf-y += target.o diff --git a/tools/perf/util/affinity.c b/tools/perf/util/affinity.c new file mode 100644 index 000000000000..a5e31f826828 --- /dev/null +++ b/tools/perf/util/affinity.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Manage affinity to optimize IPIs inside the kernel perf API. */ +#define _GNU_SOURCE 1 +#include <sched.h> +#include <stdlib.h> +#include <linux/bitmap.h> +#include <linux/zalloc.h> +#include "perf.h" +#include "cpumap.h" +#include "affinity.h" + +static int get_cpu_set_size(void) +{ + int sz = cpu__max_cpu() + 8 - 1; + /* + * sched_getaffinity doesn't like masks smaller than the kernel. + * Hopefully that's big enough. + */ + if (sz < 4096) + sz = 4096; + return sz / 8; +} + +int affinity__setup(struct affinity *a) +{ + int cpu_set_size = get_cpu_set_size(); + + a->orig_cpus = bitmap_alloc(cpu_set_size * 8); + if (!a->orig_cpus) + return -1; + sched_getaffinity(0, cpu_set_size, (cpu_set_t *)a->orig_cpus); + a->sched_cpus = bitmap_alloc(cpu_set_size * 8); + if (!a->sched_cpus) { + zfree(&a->orig_cpus); + return -1; + } + bitmap_zero((unsigned long *)a->sched_cpus, cpu_set_size); + a->changed = false; + return 0; +} + +/* + * perf_event_open does an IPI internally to the target CPU. + * It is more efficient to change perf's affinity to the target + * CPU and then set up all events on that CPU, so we amortize + * CPU communication. + */ +void affinity__set(struct affinity *a, int cpu) +{ + int cpu_set_size = get_cpu_set_size(); + + if (cpu == -1) + return; + a->changed = true; + set_bit(cpu, a->sched_cpus); + /* + * We ignore errors because affinity is just an optimization. + * This could happen for example with isolated CPUs or cpusets. + * In this case the IPIs inside the kernel's perf API still work. + */ + sched_setaffinity(0, cpu_set_size, (cpu_set_t *)a->sched_cpus); + clear_bit(cpu, a->sched_cpus); +} + +void affinity__cleanup(struct affinity *a) +{ + int cpu_set_size = get_cpu_set_size(); + + if (a->changed) + sched_setaffinity(0, cpu_set_size, (cpu_set_t *)a->orig_cpus); + zfree(&a->sched_cpus); + zfree(&a->orig_cpus); +} diff --git a/tools/perf/util/affinity.h b/tools/perf/util/affinity.h new file mode 100644 index 000000000000..0ad6a18ef20c --- /dev/null +++ b/tools/perf/util/affinity.h @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef PERF_AFFINITY_H +#define PERF_AFFINITY_H 1 + +#include <stdbool.h> + +struct affinity { + unsigned long *orig_cpus; + unsigned long *sched_cpus; + bool changed; +}; + +void affinity__cleanup(struct affinity *a); +void affinity__set(struct affinity *a, int cpu); +int affinity__setup(struct affinity *a); + +#endif // PERF_AFFINITY_H diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 5ea9a4534848..f5e77ed237e8 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -23,7 +23,7 @@ #include "dso.h" #include "env.h" #include "map.h" -#include "map_groups.h" +#include "maps.h" #include "symbol.h" #include "srcline.h" #include "units.h" @@ -271,7 +271,7 @@ static int call__parse(struct arch *arch, struct ins_operands *ops, struct map_s find_target: target.addr = map__objdump_2mem(map, ops->target.addr); - if (map_groups__find_ams(ms->mg, &target) == 0 && + if (maps__find_ams(ms->maps, &target) == 0 && map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr) ops->target.sym = target.ms.sym; @@ -391,7 +391,7 @@ static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_s * Actual navigation will come next, with further understanding of how * the symbol searching and disassembly should be done. */ - if (map_groups__find_ams(ms->mg, &target) == 0 && + if (maps__find_ams(ms->maps, &target) == 0 && map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr) ops->target.sym = target.ms.sym; @@ -1545,7 +1545,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, .ms = { .map = map, }, }; - if (!map_groups__find_ams(args->ms.mg, &target) && + if (!maps__find_ams(args->ms.maps, &target) && target.ms.sym->start == target.al_addr) dl->ops.target.sym = target.ms.sym; } diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index f7ed5d122e22..a3207d900339 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c @@ -52,9 +52,7 @@ static int machine__process_bpf_event_load(struct machine *machine, for (i = 0; i < info_linear->info.nr_jited_ksyms; i++) { u64 *addrs = (u64 *)(uintptr_t)(info_linear->info.jited_ksyms); u64 addr = addrs[i]; - struct map *map; - - map = map_groups__find(&machine->kmaps, addr); + struct map *map = maps__find(&machine->kmaps, addr); if (map) { map->dso->binary_type = DSO_BINARY_TYPE__BPF_PROG_INFO; diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 5cefce33b66b..818aa4efd386 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -1106,7 +1106,7 @@ int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *samp int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *node, bool hide_unresolved) { - al->mg = node->ms.mg; + al->maps = node->ms.maps; al->map = node->ms.map; al->sym = node->ms.sym; al->srcline = node->srcline; @@ -1119,8 +1119,8 @@ int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node * goto out; } - if (al->mg == &al->mg->machine->kmaps) { - if (machine__is_host(al->mg->machine)) { + if (al->maps == &al->maps->machine->kmaps) { + if (machine__is_host(al->maps->machine)) { al->cpumode = PERF_RECORD_MISC_KERNEL; al->level = 'k'; } else { @@ -1128,7 +1128,7 @@ int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node * al->level = 'g'; } } else { - if (machine__is_host(al->mg->machine)) { + if (machine__is_host(al->maps->machine)) { al->cpumode = PERF_RECORD_MISC_USER; al->level = '.'; } else if (perf_guest) { diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index f5f855fff412..5471045ebf5c 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -2569,7 +2569,7 @@ int cs_etm__process_auxtrace_info(union perf_event *event, if (err) goto err_delete_thread; - if (thread__init_map_groups(etm->unknown_thread, etm->machine)) { + if (thread__init_maps(etm->unknown_thread, etm->machine)) { err = -ENOMEM; goto err_delete_thread; } diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c index d029faf9fc9f..db7447154622 100644 --- a/tools/perf/util/db-export.c +++ b/tools/perf/util/db-export.c @@ -181,7 +181,7 @@ static int db_ids_from_al(struct db_export *dbe, struct addr_location *al, if (al->map) { struct dso *dso = al->map->dso; - err = db_export__dso(dbe, dso, al->mg->machine); + err = db_export__dso(dbe, dso, al->maps->machine); if (err) return err; *dso_db_id = dso->db_id; @@ -251,7 +251,7 @@ static struct call_path *call_path_from_sample(struct db_export *dbe, */ al.sym = node->ms.sym; al.map = node->ms.map; - al.mg = thread->mg; + al.maps = thread->maps; al.addr = node->ip; if (al.map && !al.sym) @@ -360,13 +360,13 @@ int db_export__sample(struct db_export *dbe, union perf_event *event, if (err) return err; - err = db_export__machine(dbe, al->mg->machine); + err = db_export__machine(dbe, al->maps->machine); if (err) return err; - main_thread = thread__main_thread(al->mg->machine, thread); + main_thread = thread__main_thread(al->maps->machine, thread); - err = db_export__threads(dbe, thread, main_thread, al->mg->machine, &comm); + err = db_export__threads(dbe, thread, main_thread, al->maps->machine, &comm); if (err) goto out_put; @@ -380,7 +380,7 @@ int db_export__sample(struct db_export *dbe, union perf_event *event, goto out_put; if (dbe->cpr) { - struct call_path *cp = call_path_from_sample(dbe, al->mg->machine, + struct call_path *cp = call_path_from_sample(dbe, al->maps->machine, thread, sample, evsel); if (cp) { diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 0141b26bae47..c5447ff516a2 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -457,11 +457,11 @@ int perf_event__process(struct perf_tool *tool __maybe_unused, struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr, struct addr_location *al) { - struct map_groups *mg = thread->mg; - struct machine *machine = mg->machine; + struct maps *maps = thread->maps; + struct machine *machine = maps->machine; bool load_map = false; - al->mg = mg; + al->maps = maps; al->thread = thread; al->addr = addr; al->cpumode = cpumode; @@ -474,13 +474,13 @@ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr, if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) { al->level = 'k'; - al->mg = mg = &machine->kmaps; + al->maps = maps = &machine->kmaps; load_map = true; } else if (cpumode == PERF_RECORD_MISC_USER && perf_host) { al->level = '.'; } else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) { al->level = 'g'; - al->mg = mg = &machine->kmaps; + al->maps = maps = &machine->kmaps; load_map = true; } else if (cpumode == PERF_RECORD_MISC_GUEST_USER && perf_guest) { al->level = 'u'; @@ -500,7 +500,7 @@ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr, return NULL; } - al->map = map_groups__find(mg, al->addr); + al->map = maps__find(maps, al->addr); if (al->map != NULL) { /* * Kernel maps might be changed when loading symbols so loading @@ -523,7 +523,7 @@ struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr, struct addr_location *al) { struct map *map = thread__find_map(thread, cpumode, addr, al); - struct machine *machine = thread->mg->machine; + struct machine *machine = thread->maps->machine; u8 addr_cpumode = machine__addr_cpumode(machine, cpumode, addr); if (map || addr_cpumode == cpumode) diff --git a/tools/perf/util/fncache.c b/tools/perf/util/fncache.c new file mode 100644 index 000000000000..6225cbc52310 --- /dev/null +++ b/tools/perf/util/fncache.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Manage a cache of file names' existence */ +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <linux/list.h> +#include "fncache.h" + +struct fncache { + struct hlist_node nd; + bool res; + char name[]; +}; + +#define FNHSIZE 61 + +static struct hlist_head fncache_hash[FNHSIZE]; + +unsigned shash(const unsigned char *s) +{ + unsigned h = 0; + while (*s) + h = 65599 * h + *s++; + return h ^ (h >> 16); +} + +static bool lookup_fncache(const char *name, bool *res) +{ + int h = shash((const unsigned char *)name) % FNHSIZE; + struct fncache *n; + + hlist_for_each_entry(n, &fncache_hash[h], nd) { + if (!strcmp(n->name, name)) { + *res = n->res; + return true; + } + } + return false; +} + +static void update_fncache(const char *name, bool res) +{ + struct fncache *n = malloc(sizeof(struct fncache) + strlen(name) + 1); + int h = shash((const unsigned char *)name) % FNHSIZE; + + if (!n) + return; + strcpy(n->name, name); + n->res = res; + hlist_add_head(&n->nd, &fncache_hash[h]); +} + +/* No LRU, only use when bounded in some other way. */ +bool file_available(const char *name) +{ + bool res; + + if (lookup_fncache(name, &res)) + return res; + res = access(name, R_OK) == 0; + update_fncache(name, res); + return res; +} diff --git a/tools/perf/util/fncache.h b/tools/perf/util/fncache.h new file mode 100644 index 000000000000..fe020beaefb1 --- /dev/null +++ b/tools/perf/util/fncache.h @@ -0,0 +1,7 @@ +#ifndef _FCACHE_H +#define _FCACHE_H 1 + +unsigned shash(const unsigned char *s); +bool file_available(const char *name); + +#endif diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 0a8d72ae93ca..ca5a8f4d007e 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -692,7 +692,7 @@ __hists__add_entry(struct hists *hists, .ino = ns ? ns->link_info[CGROUP_NS_INDEX].ino : 0, }, .ms = { - .mg = al->mg, + .maps = al->maps, .map = al->map, .sym = al->sym, }, @@ -760,7 +760,7 @@ struct hist_entry *hists__add_entry_block(struct hists *hists, .block_info = block_info, .hists = hists, .ms = { - .mg = al->mg, + .maps = al->maps, .map = al->map, .sym = al->sym, }, @@ -895,7 +895,7 @@ iter_next_branch_entry(struct hist_entry_iter *iter, struct addr_location *al) if (iter->curr >= iter->total) return 0; - al->mg = bi[i].to.ms.mg; + al->maps = bi[i].to.ms.maps; al->map = bi[i].to.ms.map; al->sym = bi[i].to.ms.sym; al->addr = bi[i].to.addr; @@ -1072,7 +1072,7 @@ iter_add_next_cumulative_entry(struct hist_entry_iter *iter, .comm = thread__comm(al->thread), .ip = al->addr, .ms = { - .mg = al->mg, + .maps = al->maps, .map = al->map, .sym = al->sym, }, diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index 409afc611be9..33cf8928cf05 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -3296,7 +3296,7 @@ int intel_pt_process_auxtrace_info(union perf_event *event, err = thread__set_comm(pt->unknown_thread, "unknown", 0); if (err) goto err_delete_thread; - if (thread__init_map_groups(pt->unknown_thread, pt->machine)) { + if (thread__init_maps(pt->unknown_thread, pt->machine)) { err = -ENOMEM; goto err_delete_thread; } diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index e2a312c649f0..416d174d223c 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -86,7 +86,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid) int err = -ENOMEM; memset(machine, 0, sizeof(*machine)); - map_groups__init(&machine->kmaps, machine); + maps__init(&machine->kmaps, machine); RB_CLEAR_NODE(&machine->rb_node); dsos__init(&machine->dsos); @@ -217,7 +217,7 @@ void machine__exit(struct machine *machine) return; machine__destroy_kernel_maps(machine); - map_groups__exit(&machine->kmaps); + maps__exit(&machine->kmaps); dsos__exit(&machine->dsos); machine__exit_vdso(machine); zfree(&machine->root_dir); @@ -412,28 +412,28 @@ static void machine__update_thread_pid(struct machine *machine, if (!leader) goto out_err; - if (!leader->mg) - leader->mg = map_groups__new(machine); + if (!leader->maps) + leader->maps = maps__new(machine); - if (!leader->mg) + if (!leader->maps) goto out_err; - if (th->mg == leader->mg) + if (th->maps == leader->maps) return; - if (th->mg) { + if (th->maps) { /* * Maps are created from MMAP events which provide the pid and * tid. Consequently there never should be any maps on a thread * with an unknown pid. Just print an error if there are. */ - if (!map_groups__empty(th->mg)) + if (!maps__empty(th->maps)) pr_err("Discarding thread maps for %d:%d\n", th->pid_, th->tid); - map_groups__put(th->mg); + maps__put(th->maps); } - th->mg = map_groups__get(leader->mg); + th->maps = maps__get(leader->maps); out_put: thread__put(leader); return; @@ -536,14 +536,13 @@ static struct thread *____machine__findnew_thread(struct machine *machine, rb_insert_color_cached(&th->rb_node, &threads->entries, leftmost); /* - * We have to initialize map_groups separately - * after rb tree is updated. + * We have to initialize maps separately after rb tree is updated. * * The reason is that we call machine__findnew_thread - * within thread__init_map_groups to find the thread + * within thread__init_maps to find the thread * leader and that would screwed the rb tree. */ - if (thread__init_map_groups(th, machine)) { + if (thread__init_maps(th, machine)) { rb_erase_cached(&th->rb_node, &threads->entries); RB_CLEAR_NODE(&th->rb_node); thread__put(th); @@ -724,9 +723,8 @@ static int machine__process_ksymbol_register(struct machine *machine, struct perf_sample *sample __maybe_unused) { struct symbol *sym; - struct map *map; + struct map *map = maps__find(&machine->kmaps, event->ksymbol.addr); - map = map_groups__find(&machine->kmaps, event->ksymbol.addr); if (!map) { map = dso__new_map(event->ksymbol.name); if (!map) @@ -734,7 +732,7 @@ static int machine__process_ksymbol_register(struct machine *machine, map->start = event->ksymbol.addr; map->end = map->start + event->ksymbol.len; - map_groups__insert(&machine->kmaps, map); + maps__insert(&machine->kmaps, map); } sym = symbol__new(map->map_ip(map, map->start), @@ -752,9 +750,9 @@ static int machine__process_ksymbol_unregister(struct machine *machine, { struct map *map; - map = map_groups__find(&machine->kmaps, event->ksymbol.addr); + map = maps__find(&machine->kmaps, event->ksymbol.addr); if (map) - map_groups__remove(&machine->kmaps, map); + maps__remove(&machine->kmaps, map); return 0; } @@ -790,9 +788,9 @@ static struct map *machine__addnew_module_map(struct machine *machine, u64 start if (map == NULL) goto out; - map_groups__insert(&machine->kmaps, map); + maps__insert(&machine->kmaps, map); - /* Put the map here because map_groups__insert alread got it */ + /* Put the map here because maps__insert alread got it */ map__put(map); out: /* put the dso here, corresponding to machine__findnew_module_dso */ @@ -977,7 +975,7 @@ int machine__create_extra_kernel_map(struct machine *machine, kmap->kmaps = &machine->kmaps; strlcpy(kmap->name, xm->name, KMAP_NAME_LEN); - map_groups__insert(&machine->kmaps, map); + maps__insert(&machine->kmaps, map); pr_debug2("Added extra kernel map %s %" PRIx64 "-%" PRIx64 "\n", kmap->name, map->start, map->end); @@ -1022,8 +1020,7 @@ static u64 find_entry_trampoline(struct dso *dso) int machine__map_x86_64_entry_trampolines(struct machine *machine, struct dso *kernel) { - struct map_groups *kmaps = &machine->kmaps; - struct maps *maps = &kmaps->maps; + struct maps *kmaps = &machine->kmaps; int nr_cpus_avail, cpu; bool found = false; struct map *map; @@ -1033,14 +1030,14 @@ int machine__map_x86_64_entry_trampolines(struct machine *machine, * In the vmlinux case, pgoff is a virtual address which must now be * mapped to a vmlinux offset. */ - maps__for_each_entry(maps, map) { + maps__for_each_entry(kmaps, map) { struct kmap *kmap = __map__kmap(map); struct map *dest_map; if (!kmap || !is_entry_trampoline(kmap->name)) continue; - dest_map = map_groups__find(kmaps, map->pgoff); + dest_map = maps__find(kmaps, map->pgoff); if (dest_map != map) map->pgoff = dest_map->map_ip(dest_map, map->pgoff); found = true; @@ -1102,7 +1099,7 @@ __machine__create_kernel_maps(struct machine *machine, struct dso *kernel) return -1; kmap->kmaps = &machine->kmaps; - map_groups__insert(&machine->kmaps, map); + maps__insert(&machine->kmaps, map); return 0; } @@ -1116,7 +1113,7 @@ void machine__destroy_kernel_maps(struct machine *machine) return; kmap = map__kmap(map); - map_groups__remove(&machine->kmaps, map); + maps__remove(&machine->kmaps, map); if (kmap && kmap->ref_reloc_sym) { zfree((char **)&kmap->ref_reloc_sym->name); zfree(&kmap->ref_reloc_sym); @@ -1211,7 +1208,7 @@ int machine__load_kallsyms(struct machine *machine, const char *filename) * kernel, with modules between them, fixup the end of all * sections. */ - map_groups__fixup_end(&machine->kmaps); + maps__fixup_end(&machine->kmaps); } return ret; @@ -1262,11 +1259,10 @@ static bool is_kmod_dso(struct dso *dso) dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE; } -static int map_groups__set_module_path(struct map_groups *mg, const char *path, - struct kmod_path *m) +static int maps__set_module_path(struct maps *maps, const char *path, struct kmod_path *m) { char *long_name; - struct map *map = map_groups__find_by_name(mg, m->name); + struct map *map = maps__find_by_name(maps, m->name); if (map == NULL) return 0; @@ -1290,8 +1286,7 @@ static int map_groups__set_module_path(struct map_groups *mg, const char *path, return 0; } -static int map_groups__set_modules_path_dir(struct map_groups *mg, - const char *dir_name, int depth) +static int maps__set_modules_path_dir(struct maps *maps, const char *dir_name, int depth) { struct dirent *dent; DIR *dir = opendir(dir_name); @@ -1323,8 +1318,7 @@ static int map_groups__set_modules_path_dir(struct map_groups *mg, continue; } - ret = map_groups__set_modules_path_dir(mg, path, - depth + 1); + ret = maps__set_modules_path_dir(maps, path, depth + 1); if (ret < 0) goto out; } else { @@ -1335,7 +1329,7 @@ static int map_groups__set_modules_path_dir(struct map_groups *mg, goto out; if (m.kmod) - ret = map_groups__set_module_path(mg, path, &m); + ret = maps__set_module_path(maps, path, &m); zfree(&m.name); @@ -1362,7 +1356,7 @@ static int machine__set_modules_path(struct machine *machine) machine->root_dir, version); free(version); - return map_groups__set_modules_path_dir(&machine->kmaps, modules_path, 0); + return maps__set_modules_path_dir(&machine->kmaps, modules_path, 0); } int __weak arch__fix_module_text_start(u64 *start __maybe_unused, u64 *size __maybe_unused, @@ -1435,11 +1429,11 @@ static void machine__update_kernel_mmap(struct machine *machine, struct map *map = machine__kernel_map(machine); map__get(map); - map_groups__remove(&machine->kmaps, map); + maps__remove(&machine->kmaps, map); machine__set_kernel_mmap(machine, start, end); - map_groups__insert(&machine->kmaps, map); + maps__insert(&machine->kmaps, map); map__put(map); } @@ -1940,7 +1934,7 @@ static void ip__resolve_ams(struct thread *thread, ams->addr = ip; ams->al_addr = al.addr; - ams->ms.mg = al.mg; + ams->ms.maps = al.maps; ams->ms.sym = al.sym; ams->ms.map = al.map; ams->phys_addr = 0; @@ -1958,7 +1952,7 @@ static void ip__resolve_data(struct thread *thread, ams->addr = addr; ams->al_addr = al.addr; - ams->ms.mg = al.mg; + ams->ms.maps = al.maps; ams->ms.sym = al.sym; ams->ms.map = al.map; ams->phys_addr = phys_addr; @@ -2075,7 +2069,7 @@ static int add_callchain_ip(struct thread *thread, iter_cycles = iter->cycles; } - ms.mg = al.mg; + ms.maps = al.maps; ms.map = al.map; ms.sym = al.sym; srcline = callchain_srcline(&ms, al.addr); diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index 499be204830d..be0a930eca89 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -4,7 +4,7 @@ #include <sys/types.h> #include <linux/rbtree.h> -#include "map_groups.h" +#include "maps.h" #include "dsos.h" #include "rwsem.h" @@ -51,7 +51,7 @@ struct machine { struct vdso_info *vdso_info; struct perf_env *env; struct dsos dsos; - struct map_groups kmaps; + struct maps kmaps; struct map *vmlinux_map; u64 kernel_start; pid_t *current_tid; @@ -83,7 +83,7 @@ struct map *machine__kernel_map(struct machine *machine) static inline struct maps *machine__kernel_maps(struct machine *machine) { - return &machine->kmaps.maps; + return &machine->kmaps; } int machine__get_kernel_start(struct machine *machine); @@ -212,7 +212,7 @@ static inline struct symbol *machine__find_kernel_symbol(struct machine *machine, u64 addr, struct map **mapp) { - return map_groups__find_symbol(&machine->kmaps, addr, mapp); + return maps__find_symbol(&machine->kmaps, addr, mapp); } static inline @@ -220,7 +220,7 @@ struct symbol *machine__find_kernel_symbol_by_name(struct machine *machine, const char *name, struct map **mapp) { - return map_groups__find_symbol_by_name(&machine->kmaps, name, mapp); + return maps__find_symbol_by_name(&machine->kmaps, name, mapp); } int arch__fix_module_text_start(u64 *start, u64 *size, const char *name); diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 744bfbaf35cf..fdd5bddb3075 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -433,51 +433,6 @@ int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix, return ret; } -int map__fprintf_srccode(struct map *map, u64 addr, - FILE *fp, - struct srccode_state *state) -{ - char *srcfile; - int ret = 0; - unsigned line; - int len; - char *srccode; - - if (!map || !map->dso) - return 0; - srcfile = get_srcline_split(map->dso, - map__rip_2objdump(map, addr), - &line); - if (!srcfile) - return 0; - - /* Avoid redundant printing */ - if (state && - state->srcfile && - !strcmp(state->srcfile, srcfile) && - state->line == line) { - free(srcfile); - return 0; - } - - srccode = find_sourceline(srcfile, line, &len); - if (!srccode) - goto out_free_line; - - ret = fprintf(fp, "|%-8d %.*s", line, len, srccode); - - if (state) { - state->srcfile = srcfile; - state->line = line; - } - return ret; - -out_free_line: - free(srcfile); - return ret; -} - - void srccode_state_free(struct srccode_state *state) { zfree(&state->srcfile); @@ -557,73 +512,71 @@ u64 map__objdump_2mem(struct map *map, u64 ip) return ip + map->reloc; } -static void maps__init(struct maps *maps) +void maps__init(struct maps *maps, struct machine *machine) { maps->entries = RB_ROOT; init_rwsem(&maps->lock); + maps->machine = machine; + maps->last_search_by_name = NULL; + maps->nr_maps = 0; + maps->maps_by_name = NULL; + refcount_set(&maps->refcnt, 1); } -void map_groups__init(struct map_groups *mg, struct machine *machine) -{ - maps__init(&mg->maps); - mg->machine = machine; - mg->last_search_by_name = NULL; - mg->nr_maps = 0; - mg->maps_by_name = NULL; - refcount_set(&mg->refcnt, 1); -} - -static void __map_groups__free_maps_by_name(struct map_groups *mg) +static void __maps__free_maps_by_name(struct maps *maps) { /* * Free everything to try to do it from the rbtree in the next search */ - zfree(&mg->maps_by_name); - mg->nr_maps_allocated = 0; + zfree(&maps->maps_by_name); + maps->nr_maps_allocated = 0; } -void map_groups__insert(struct map_groups *mg, struct map *map) +void maps__insert(struct maps *maps, struct map *map) { - struct maps *maps = &mg->maps; - down_write(&maps->lock); __maps__insert(maps, map); - ++mg->nr_maps; + ++maps->nr_maps; /* * If we already performed some search by name, then we need to add the just * inserted map and resort. */ - if (mg->maps_by_name) { - if (mg->nr_maps > mg->nr_maps_allocated) { - int nr_allocate = mg->nr_maps * 2; - struct map **maps_by_name = realloc(mg->maps_by_name, nr_allocate * sizeof(map)); + if (maps->maps_by_name) { + if (maps->nr_maps > maps->nr_maps_allocated) { + int nr_allocate = maps->nr_maps * 2; + struct map **maps_by_name = realloc(maps->maps_by_name, nr_allocate * sizeof(map)); if (maps_by_name == NULL) { - __map_groups__free_maps_by_name(mg); + __maps__free_maps_by_name(maps); return; } - mg->maps_by_name = maps_by_name; - mg->nr_maps_allocated = nr_allocate; + maps->maps_by_name = maps_by_name; + maps->nr_maps_allocated = nr_allocate; } - mg->maps_by_name[mg->nr_maps - 1] = map; - __map_groups__sort_by_name(mg); + maps->maps_by_name[maps->nr_maps - 1] = map; + __maps__sort_by_name(maps); } up_write(&maps->lock); } -void map_groups__remove(struct map_groups *mg, struct map *map) +static void __maps__remove(struct maps *maps, struct map *map) +{ + rb_erase_init(&map->rb_node, &maps->entries); + map__put(map); +} + +void maps__remove(struct maps *maps, struct map *map) { - struct maps *maps = &mg->maps; down_write(&maps->lock); - if (mg->last_search_by_name == map) - mg->last_search_by_name = NULL; + if (maps->last_search_by_name == map) + maps->last_search_by_name = NULL; __maps__remove(maps, map); - --mg->nr_maps; - if (mg->maps_by_name) - __map_groups__free_maps_by_name(mg); + --maps->nr_maps; + if (maps->maps_by_name) + __maps__free_maps_by_name(maps); up_write(&maps->lock); } @@ -637,50 +590,44 @@ static void __maps__purge(struct maps *maps) } } -static void maps__exit(struct maps *maps) +void maps__exit(struct maps *maps) { down_write(&maps->lock); __maps__purge(maps); up_write(&maps->lock); } -void map_groups__exit(struct map_groups *mg) -{ - maps__exit(&mg->maps); -} - -bool map_groups__empty(struct map_groups *mg) +bool maps__empty(struct maps *maps) { - return !maps__first(&mg->maps); + return !maps__first(maps); } -struct map_groups *map_groups__new(struct machine *machine) +struct maps *maps__new(struct machine *machine) { - struct map_groups *mg = zalloc(sizeof(*mg)); + struct maps *maps = zalloc(sizeof(*maps)); - if (mg != NULL) - map_groups__init(mg, machine); + if (maps != NULL) + maps__init(maps, machine); - return mg; + return maps; } -void map_groups__delete(struct map_groups *mg) +void maps__delete(struct maps *maps) { - map_groups__exit(mg); - unwind__finish_access(mg); - free(mg); + maps__exit(maps); + unwind__finish_access(maps); + free(maps); } -void map_groups__put(struct map_groups *mg) +void maps__put(struct maps *maps) { - if (mg && refcount_dec_and_test(&mg->refcnt)) - map_groups__delete(mg); + if (maps && refcount_dec_and_test(&maps->refcnt)) + maps__delete(maps); } -struct symbol *map_groups__find_symbol(struct map_groups *mg, - u64 addr, struct map **mapp) +struct symbol *maps__find_symbol(struct maps *maps, u64 addr, struct map **mapp) { - struct map *map = map_groups__find(mg, addr); + struct map *map = maps__find(maps, addr); /* Ensure map is loaded before using map->map_ip */ if (map != NULL && map__load(map) >= 0) { @@ -699,8 +646,7 @@ static bool map__contains_symbol(struct map *map, struct symbol *sym) return ip >= map->start && ip < map->end; } -struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name, - struct map **mapp) +struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name, struct map **mapp) { struct symbol *sym; struct map *pos; @@ -727,19 +673,12 @@ out: return sym; } -struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg, - const char *name, - struct map **mapp) -{ - return maps__find_symbol_by_name(&mg->maps, name, mapp); -} - -int map_groups__find_ams(struct map_groups *mg, struct addr_map_symbol *ams) +int maps__find_ams(struct maps *maps, struct addr_map_symbol *ams) { if (ams->addr < ams->ms.map->start || ams->addr >= ams->ms.map->end) { - if (mg == NULL) + if (maps == NULL) return -1; - ams->ms.map = map_groups__find(mg, ams->addr); + ams->ms.map = maps__find(maps, ams->addr); if (ams->ms.map == NULL) return -1; } @@ -750,7 +689,7 @@ int map_groups__find_ams(struct map_groups *mg, struct addr_map_symbol *ams) return ams->ms.sym ? 0 : -1; } -static size_t maps__fprintf(struct maps *maps, FILE *fp) +size_t maps__fprintf(struct maps *maps, FILE *fp) { size_t printed = 0; struct map *pos; @@ -771,19 +710,8 @@ static size_t maps__fprintf(struct maps *maps, FILE *fp) return printed; } -size_t map_groups__fprintf(struct map_groups *mg, FILE *fp) -{ - return maps__fprintf(&mg->maps, fp); -} - -static void __map_groups__insert(struct map_groups *mg, struct map *map) -{ - __maps__insert(&mg->maps, map); -} - -int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, FILE *fp) +int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) { - struct maps *maps = &mg->maps; struct rb_root *root; struct rb_node *next, *first; int err = 0; @@ -848,7 +776,7 @@ int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, FILE } before->end = map->start; - __map_groups__insert(mg, before); + __maps__insert(maps, before); if (verbose >= 2 && !use_browser) map__fprintf(before, fp); map__put(before); @@ -865,7 +793,7 @@ int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, FILE after->start = map->end; after->pgoff += map->end - pos->start; assert(pos->map_ip(pos, map->end) == after->map_ip(after, map->end)); - __map_groups__insert(mg, after); + __maps__insert(maps, after); if (verbose >= 2 && !use_browser) map__fprintf(after, fp); map__put(after); @@ -886,31 +814,30 @@ out: /* * XXX This should not really _copy_ te maps, but refcount them. */ -int map_groups__clone(struct thread *thread, struct map_groups *parent) +int maps__clone(struct thread *thread, struct maps *parent) { - struct map_groups *mg = thread->mg; + struct maps *maps = thread->maps; int err = -ENOMEM; struct map *map; - struct maps *maps = &parent->maps; - down_read(&maps->lock); + down_read(&parent->lock); - maps__for_each_entry(maps, map) { + maps__for_each_entry(parent, map) { struct map *new = map__clone(map); if (new == NULL) goto out_unlock; - err = unwind__prepare_access(mg, new, NULL); + err = unwind__prepare_access(maps, new, NULL); if (err) goto out_unlock; - map_groups__insert(mg, new); + maps__insert(maps, new); map__put(new); } err = 0; out_unlock: - up_read(&maps->lock); + up_read(&parent->lock); return err; } @@ -935,26 +862,6 @@ static void __maps__insert(struct maps *maps, struct map *map) map__get(map); } -void maps__insert(struct maps *maps, struct map *map) -{ - down_write(&maps->lock); - __maps__insert(maps, map); - up_write(&maps->lock); -} - -void __maps__remove(struct maps *maps, struct map *map) -{ - rb_erase_init(&map->rb_node, &maps->entries); - map__put(map); -} - -void maps__remove(struct maps *maps, struct map *map) -{ - down_write(&maps->lock); - __maps__remove(maps, map); - up_write(&maps->lock); -} - struct map *maps__find(struct maps *maps, u64 ip) { struct rb_node *p; @@ -1018,7 +925,7 @@ struct kmap *map__kmap(struct map *map) return kmap; } -struct map_groups *map__kmaps(struct map *map) +struct maps *map__kmaps(struct map *map) { struct kmap *kmap = map__kmap(map); diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 5e8899883231..067036e8970c 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -12,11 +12,8 @@ #include <linux/types.h> struct dso; -struct ip_callchain; -struct ref_reloc_sym; -struct map_groups; +struct maps; struct machine; -struct evsel; struct map { union { @@ -45,7 +42,7 @@ struct kmap; struct kmap *__map__kmap(struct map *map); struct kmap *map__kmap(struct map *map); -struct map_groups *map__kmaps(struct map *map); +struct maps *map__kmaps(struct map *map); static inline u64 map__map_ip(struct map *map, u64 ip) { @@ -138,19 +135,12 @@ char *map__srcline(struct map *map, u64 addr, struct symbol *sym); int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix, FILE *fp); -struct srccode_state; - -int map__fprintf_srccode(struct map *map, u64 addr, - FILE *fp, struct srccode_state *state); - int map__load(struct map *map); struct symbol *map__find_symbol(struct map *map, u64 addr); struct symbol *map__find_symbol_by_name(struct map *map, const char *name); void map__fixup_start(struct map *map); void map__fixup_end(struct map *map); -void map__reloc_vmlinux(struct map *map); - int map__set_kallsyms_ref_reloc_sym(struct map *map, const char *symbol_name, u64 addr); diff --git a/tools/perf/util/map_groups.h b/tools/perf/util/map_groups.h deleted file mode 100644 index 63ed211fe241..000000000000 --- a/tools/perf/util/map_groups.h +++ /dev/null @@ -1,106 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __PERF_MAP_GROUPS_H -#define __PERF_MAP_GROUPS_H - -#include <linux/refcount.h> -#include <linux/rbtree.h> -#include <stdio.h> -#include <stdbool.h> -#include <linux/types.h> -#include "rwsem.h" - -struct ref_reloc_sym; -struct machine; -struct map; -struct thread; - -struct maps { - struct rb_root entries; - struct rw_semaphore lock; -}; - -void maps__insert(struct maps *maps, struct map *map); -void maps__remove(struct maps *maps, struct map *map); -void __maps__remove(struct maps *maps, struct map *map); -struct map *maps__find(struct maps *maps, u64 addr); -struct map *maps__first(struct maps *maps); -struct map *map__next(struct map *map); - -#define maps__for_each_entry(maps, map) \ - for (map = maps__first(maps); map; map = map__next(map)) - -#define maps__for_each_entry_safe(maps, map, next) \ - for (map = maps__first(maps), next = map__next(map); map; map = next, next = map__next(map)) - -struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name, struct map **mapp); - -struct map_groups { - struct maps maps; - struct machine *machine; - struct map *last_search_by_name; - struct map **maps_by_name; - refcount_t refcnt; - unsigned int nr_maps; - unsigned int nr_maps_allocated; -#ifdef HAVE_LIBUNWIND_SUPPORT - void *addr_space; - struct unwind_libunwind_ops *unwind_libunwind_ops; -#endif -}; - -#define KMAP_NAME_LEN 256 - -struct kmap { - struct ref_reloc_sym *ref_reloc_sym; - struct map_groups *kmaps; - char name[KMAP_NAME_LEN]; -}; - -struct map_groups *map_groups__new(struct machine *machine); -void map_groups__delete(struct map_groups *mg); -bool map_groups__empty(struct map_groups *mg); - -static inline struct map_groups *map_groups__get(struct map_groups *mg) -{ - if (mg) - refcount_inc(&mg->refcnt); - return mg; -} - -void map_groups__put(struct map_groups *mg); -void map_groups__init(struct map_groups *mg, struct machine *machine); -void map_groups__exit(struct map_groups *mg); -int map_groups__clone(struct thread *thread, struct map_groups *parent); -size_t map_groups__fprintf(struct map_groups *mg, FILE *fp); - -void map_groups__insert(struct map_groups *mg, struct map *map); - -void map_groups__remove(struct map_groups *mg, struct map *map); - -static inline struct map *map_groups__find(struct map_groups *mg, u64 addr) -{ - return maps__find(&mg->maps, addr); -} - -#define map_groups__for_each_entry(mg, map) \ - for (map = maps__first(&mg->maps); map; map = map__next(map)) - -#define map_groups__for_each_entry_safe(mg, map, next) \ - for (map = maps__first(&mg->maps), next = map__next(map); map; map = next, next = map__next(map)) - -struct symbol *map_groups__find_symbol(struct map_groups *mg, u64 addr, struct map **mapp); -struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg, const char *name, struct map **mapp); - -struct addr_map_symbol; - -int map_groups__find_ams(struct map_groups *mg, struct addr_map_symbol *ams); - -int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, FILE *fp); - -struct map *map_groups__find_by_name(struct map_groups *mg, const char *name); - -int map_groups__merge_in(struct map_groups *kmaps, struct map *new_map); - -void __map_groups__sort_by_name(struct map_groups *mg); - -#endif // __PERF_MAP_GROUPS_H diff --git a/tools/perf/util/map_symbol.h b/tools/perf/util/map_symbol.h index 2964d971aeab..5b8ca93798e9 100644 --- a/tools/perf/util/map_symbol.h +++ b/tools/perf/util/map_symbol.h @@ -4,12 +4,12 @@ #include <linux/types.h> -struct map_groups; +struct maps; struct map; struct symbol; struct map_symbol { - struct map_groups *mg; + struct maps *maps; struct map *map; struct symbol *sym; }; diff --git a/tools/perf/util/maps.h b/tools/perf/util/maps.h new file mode 100644 index 000000000000..3dd000ddf925 --- /dev/null +++ b/tools/perf/util/maps.h @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __PERF_MAPS_H +#define __PERF_MAPS_H + +#include <linux/refcount.h> +#include <linux/rbtree.h> +#include <stdio.h> +#include <stdbool.h> +#include <linux/types.h> +#include "rwsem.h" + +struct ref_reloc_sym; +struct machine; +struct map; +struct maps; +struct thread; + +struct map *maps__find(struct maps *maps, u64 addr); +struct map *maps__first(struct maps *maps); +struct map *map__next(struct map *map); + +#define maps__for_each_entry(maps, map) \ + for (map = maps__first(maps); map; map = map__next(map)) + +#define maps__for_each_entry_safe(maps, map, next) \ + for (map = maps__first(maps), next = map__next(map); map; map = next, next = map__next(map)) + +struct maps { + struct rb_root entries; + struct rw_semaphore lock; + struct machine *machine; + struct map *last_search_by_name; + struct map **maps_by_name; + refcount_t refcnt; + unsigned int nr_maps; + unsigned int nr_maps_allocated; +#ifdef HAVE_LIBUNWIND_SUPPORT + void *addr_space; + struct unwind_libunwind_ops *unwind_libunwind_ops; +#endif +}; + +#define KMAP_NAME_LEN 256 + +struct kmap { + struct ref_reloc_sym *ref_reloc_sym; + struct maps *kmaps; + char name[KMAP_NAME_LEN]; +}; + +struct maps *maps__new(struct machine *machine); +void maps__delete(struct maps *maps); +bool maps__empty(struct maps *maps); + +static inline struct maps *maps__get(struct maps *maps) +{ + if (maps) + refcount_inc(&maps->refcnt); + return maps; +} + +void maps__put(struct maps *maps); +void maps__init(struct maps *maps, struct machine *machine); +void maps__exit(struct maps *maps); +int maps__clone(struct thread *thread, struct maps *parent); +size_t maps__fprintf(struct maps *maps, FILE *fp); + +void maps__insert(struct maps *maps, struct map *map); + +void maps__remove(struct maps *maps, struct map *map); + +struct symbol *maps__find_symbol(struct maps *maps, u64 addr, struct map **mapp); +struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name, struct map **mapp); + +struct addr_map_symbol; + +int maps__find_ams(struct maps *maps, struct addr_map_symbol *ams); + +int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp); + +struct map *maps__find_by_name(struct maps *maps, const char *name); + +int maps__merge_in(struct maps *kmaps, struct map *new_map); + +void __maps__sort_by_name(struct maps *maps); + +#endif // __PERF_MAPS_H diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h index e014c2c038f4..a45499126184 100644 --- a/tools/perf/util/perf_regs.h +++ b/tools/perf/util/perf_regs.h @@ -41,7 +41,7 @@ int perf_reg_value(u64 *valp, struct regs_dump *regs, int id); static inline const char *perf_reg_name(int id __maybe_unused) { - return NULL; + return "unknown"; } static inline int perf_reg_value(u64 *valp __maybe_unused, diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index e8d348988026..8b99fd312aae 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -24,6 +24,7 @@ #include "pmu-events/pmu-events.h" #include "string2.h" #include "strbuf.h" +#include "fncache.h" struct perf_pmu_format { char *name; @@ -82,7 +83,6 @@ int perf_pmu__format_parse(char *dir, struct list_head *head) */ static int pmu_format(const char *name, struct list_head *format) { - struct stat st; char path[PATH_MAX]; const char *sysfs = sysfs__mountpoint(); @@ -92,8 +92,8 @@ static int pmu_format(const char *name, struct list_head *format) snprintf(path, PATH_MAX, "%s" EVENT_SOURCE_DEVICE_PATH "%s/format", sysfs, name); - if (stat(path, &st) < 0) - return 0; /* no error if format does not exist */ + if (!file_available(path)) + return 0; if (perf_pmu__format_parse(path, format)) return -1; @@ -475,7 +475,6 @@ static int pmu_aliases_parse(char *dir, struct list_head *head) */ static int pmu_aliases(const char *name, struct list_head *head) { - struct stat st; char path[PATH_MAX]; const char *sysfs = sysfs__mountpoint(); @@ -485,8 +484,8 @@ static int pmu_aliases(const char *name, struct list_head *head) snprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s/events", sysfs, name); - if (stat(path, &st) < 0) - return 0; /* no error if 'events' does not exist */ + if (!file_available(path)) + return 0; if (pmu_aliases_parse(path, head)) return -1; @@ -525,7 +524,6 @@ static int pmu_alias_terms(struct perf_pmu_alias *alias, */ static int pmu_type(const char *name, __u32 *type) { - struct stat st; char path[PATH_MAX]; FILE *file; int ret = 0; @@ -537,7 +535,7 @@ static int pmu_type(const char *name, __u32 *type) snprintf(path, PATH_MAX, "%s" EVENT_SOURCE_DEVICE_PATH "%s/type", sysfs, name); - if (stat(path, &st) < 0) + if (access(path, R_OK) < 0) return -1; file = fopen(path, "r"); @@ -628,14 +626,11 @@ static struct perf_cpu_map *pmu_cpumask(const char *name) static bool pmu_is_uncore(const char *name) { char path[PATH_MAX]; - struct perf_cpu_map *cpus; - const char *sysfs = sysfs__mountpoint(); + const char *sysfs; + sysfs = sysfs__mountpoint(); snprintf(path, PATH_MAX, CPUS_TEMPLATE_UNCORE, sysfs, name); - cpus = __pmu_cpumask(path); - perf_cpu_map__put(cpus); - - return !!cpus; + return file_available(path); } /* @@ -645,7 +640,6 @@ static bool pmu_is_uncore(const char *name) */ static int is_arm_pmu_core(const char *name) { - struct stat st; char path[PATH_MAX]; const char *sysfs = sysfs__mountpoint(); @@ -655,10 +649,7 @@ static int is_arm_pmu_core(const char *name) /* Look for cpu sysfs (specific to arm) */ scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s/cpus", sysfs, name); - if (stat(path, &st) == 0) - return 1; - - return 0; + return file_available(path); } static char *perf_pmu__getcpuid(struct perf_pmu *pmu) @@ -1544,7 +1535,6 @@ bool pmu_have_event(const char *pname, const char *name) static FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name) { - struct stat st; char path[PATH_MAX]; const char *sysfs; @@ -1554,10 +1544,8 @@ static FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name) snprintf(path, PATH_MAX, "%s" EVENT_SOURCE_DEVICE_PATH "%s/%s", sysfs, pmu->name, name); - - if (stat(path, &st) < 0) + if (!file_available(path)) return NULL; - return fopen(path, "r"); } diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 52b2d165453a..eea132f512b0 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -28,7 +28,7 @@ #include "dso.h" #include "color.h" #include "map.h" -#include "map_groups.h" +#include "maps.h" #include "symbol.h" #include <api/fs/fs.h> #include "trace-event.h" /* For __maybe_unused */ @@ -321,7 +321,7 @@ static int kernel_get_module_dso(const char *module, struct dso **pdso) char module_name[128]; snprintf(module_name, sizeof(module_name), "[%s]", module); - map = map_groups__find_by_name(&host_machine->kmaps, module_name); + map = maps__find_by_name(&host_machine->kmaps, module_name); if (map) { dso = map->dso; goto found; diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources index 9af183860fbd..e7279ea6043a 100644 --- a/tools/perf/util/python-ext-sources +++ b/tools/perf/util/python-ext-sources @@ -33,3 +33,4 @@ util/trace-event.c util/string.c util/symbol_fprintf.c util/units.c +util/affinity.c diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 9581a904af29..80ca5d0ab7fe 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -1127,7 +1127,7 @@ static void python_export_sample_table(struct db_export *dbe, tuple_set_u64(t, 0, es->db_id); tuple_set_u64(t, 1, es->evsel->db_id); - tuple_set_u64(t, 2, es->al->mg->machine->db_id); + tuple_set_u64(t, 2, es->al->maps->machine->db_id); tuple_set_u64(t, 3, es->al->thread->db_id); tuple_set_u64(t, 4, es->comm_db_id); tuple_set_u64(t, 5, es->dso_db_id); diff --git a/tools/perf/util/srccode.c b/tools/perf/util/srccode.c index d84ed8b6caaa..c29edaaca863 100644 --- a/tools/perf/util/srccode.c +++ b/tools/perf/util/srccode.c @@ -16,6 +16,7 @@ #include "srccode.h" #include "debug.h" #include <internal/lib.h> // page_size +#include "fncache.h" #define MAXSRCCACHE (32*1024*1024) #define MAXSRCFILES 64 @@ -36,14 +37,6 @@ static LIST_HEAD(srcfile_list); static long map_total_sz; static int num_srcfiles; -static unsigned shash(unsigned char *s) -{ - unsigned h = 0; - while (*s) - h = 65599 * h + *s++; - return h ^ (h >> 16); -} - static int countlines(char *map, int maplen) { int numl; diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 16776d5fbaea..6658fbf196e6 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -9,7 +9,7 @@ #include "dso.h" #include "map.h" -#include "map_groups.h" +#include "maps.h" #include "symbol.h" #include "symsrc.h" #include "demangle-java.h" @@ -844,7 +844,7 @@ void __weak arch__sym_update(struct symbol *s __maybe_unused, static int dso__process_kernel_symbol(struct dso *dso, struct map *map, GElf_Sym *sym, GElf_Shdr *shdr, - struct map_groups *kmaps, struct kmap *kmap, + struct maps *kmaps, struct kmap *kmap, struct dso **curr_dsop, struct map **curr_mapp, const char *section_name, bool adjust_kernel_syms, bool kmodule, bool *remap_kernel) @@ -876,8 +876,8 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, /* Ensure maps are correctly ordered */ if (kmaps) { map__get(map); - map_groups__remove(kmaps, map); - map_groups__insert(kmaps, map); + maps__remove(kmaps, map); + maps__insert(kmaps, map); map__put(map); } } @@ -902,7 +902,7 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, snprintf(dso_name, sizeof(dso_name), "%s%s", dso->short_name, section_name); - curr_map = map_groups__find_by_name(kmaps, dso_name); + curr_map = maps__find_by_name(kmaps, dso_name); if (curr_map == NULL) { u64 start = sym->st_value; @@ -928,7 +928,7 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; } curr_dso->symtab_type = dso->symtab_type; - map_groups__insert(kmaps, curr_map); + maps__insert(kmaps, curr_map); /* * Add it before we drop the referece to curr_map, i.e. while * we still are sure to have a reference to this DSO via @@ -950,7 +950,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, struct symsrc *runtime_ss, int kmodule) { struct kmap *kmap = dso->kernel ? map__kmap(map) : NULL; - struct map_groups *kmaps = kmap ? map__kmaps(map) : NULL; + struct maps *kmaps = kmap ? map__kmaps(map) : NULL; struct map *curr_map = map; struct dso *curr_dso = dso; Elf_Data *symstrs, *secstrs; @@ -1162,7 +1162,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, * We need to fixup this here too because we create new * maps here, for things like vsyscall sections. */ - map_groups__fixup_end(kmaps); + maps__fixup_end(kmaps); } } err = nr; diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index db9667aacb88..3b379b1296f1 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -239,9 +239,8 @@ void symbols__fixup_end(struct rb_root_cached *symbols) curr->end = roundup(curr->start, 4096) + 4096; } -void map_groups__fixup_end(struct map_groups *mg) +void maps__fixup_end(struct maps *maps) { - struct maps *maps = &mg->maps; struct map *prev = NULL, *curr; down_write(&maps->lock); @@ -698,7 +697,7 @@ static int dso__load_all_kallsyms(struct dso *dso, const char *filename) return kallsyms__parse(filename, dso, map__process_kallsym_symbol); } -static int map_groups__split_kallsyms_for_kcore(struct map_groups *kmaps, struct dso *dso) +static int maps__split_kallsyms_for_kcore(struct maps *kmaps, struct dso *dso) { struct map *curr_map; struct symbol *pos; @@ -724,7 +723,7 @@ static int map_groups__split_kallsyms_for_kcore(struct map_groups *kmaps, struct if (module) *module = '\0'; - curr_map = map_groups__find(kmaps, pos->start); + curr_map = maps__find(kmaps, pos->start); if (!curr_map) { symbol__delete(pos); @@ -751,8 +750,8 @@ static int map_groups__split_kallsyms_for_kcore(struct map_groups *kmaps, struct * kernel range is broken in several maps, named [kernel].N, as we don't have * the original ELF section names vmlinux have. */ -static int map_groups__split_kallsyms(struct map_groups *kmaps, struct dso *dso, u64 delta, - struct map *initial_map) +static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, + struct map *initial_map) { struct machine *machine; struct map *curr_map = initial_map; @@ -797,7 +796,7 @@ static int map_groups__split_kallsyms(struct map_groups *kmaps, struct dso *dso, dso__set_loaded(curr_map->dso); } - curr_map = map_groups__find_by_name(kmaps, module); + curr_map = maps__find_by_name(kmaps, module); if (curr_map == NULL) { pr_debug("%s/proc/{kallsyms,modules} " "inconsistency while looking " @@ -864,7 +863,7 @@ static int map_groups__split_kallsyms(struct map_groups *kmaps, struct dso *dso, } curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; - map_groups__insert(kmaps, curr_map); + maps__insert(kmaps, curr_map); ++kernel_range; } else if (delta) { /* Kernel was relocated at boot time */ @@ -1049,8 +1048,7 @@ out_delete_from: return ret; } -static int do_validate_kcore_modules(const char *filename, - struct map_groups *kmaps) +static int do_validate_kcore_modules(const char *filename, struct maps *kmaps) { struct rb_root modules = RB_ROOT; struct map *old_map; @@ -1060,7 +1058,7 @@ static int do_validate_kcore_modules(const char *filename, if (err) return err; - map_groups__for_each_entry(kmaps, old_map) { + maps__for_each_entry(kmaps, old_map) { struct module_info *mi; if (!__map__is_kmodule(old_map)) { @@ -1107,7 +1105,7 @@ static bool filename_from_kallsyms_filename(char *filename, static int validate_kcore_modules(const char *kallsyms_filename, struct map *map) { - struct map_groups *kmaps = map__kmaps(map); + struct maps *kmaps = map__kmaps(map); char modules_filename[PATH_MAX]; if (!kmaps) @@ -1167,15 +1165,15 @@ static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data) } /* - * Merges map into map_groups by splitting the new map - * within the existing map regions. + * Merges map into maps by splitting the new map within the existing map + * regions. */ -int map_groups__merge_in(struct map_groups *kmaps, struct map *new_map) +int maps__merge_in(struct maps *kmaps, struct map *new_map) { struct map *old_map; LIST_HEAD(merged); - map_groups__for_each_entry(kmaps, old_map) { + maps__for_each_entry(kmaps, old_map) { /* no overload with this one */ if (new_map->end < old_map->start || new_map->start >= old_map->end) @@ -1232,12 +1230,12 @@ int map_groups__merge_in(struct map_groups *kmaps, struct map *new_map) while (!list_empty(&merged)) { old_map = list_entry(merged.next, struct map, node); list_del_init(&old_map->node); - map_groups__insert(kmaps, old_map); + maps__insert(kmaps, old_map); map__put(old_map); } if (new_map) { - map_groups__insert(kmaps, new_map); + maps__insert(kmaps, new_map); map__put(new_map); } return 0; @@ -1246,7 +1244,7 @@ int map_groups__merge_in(struct map_groups *kmaps, struct map *new_map) static int dso__load_kcore(struct dso *dso, struct map *map, const char *kallsyms_filename) { - struct map_groups *kmaps = map__kmaps(map); + struct maps *kmaps = map__kmaps(map); struct kcore_mapfn_data md; struct map *old_map, *new_map, *replacement_map = NULL, *next; struct machine *machine; @@ -1295,14 +1293,14 @@ static int dso__load_kcore(struct dso *dso, struct map *map, } /* Remove old maps */ - map_groups__for_each_entry_safe(kmaps, old_map, next) { + maps__for_each_entry_safe(kmaps, old_map, next) { /* * We need to preserve eBPF maps even if they are * covered by kcore, because we need to access * eBPF dso for source data. */ if (old_map != map && !__map__is_bpf_prog(old_map)) - map_groups__remove(kmaps, old_map); + maps__remove(kmaps, old_map); } machine->trampolines_mapped = false; @@ -1331,8 +1329,8 @@ static int dso__load_kcore(struct dso *dso, struct map *map, map->unmap_ip = new_map->unmap_ip; /* Ensure maps are correctly ordered */ map__get(map); - map_groups__remove(kmaps, map); - map_groups__insert(kmaps, map); + maps__remove(kmaps, map); + maps__insert(kmaps, map); map__put(map); map__put(new_map); } else { @@ -1341,7 +1339,7 @@ static int dso__load_kcore(struct dso *dso, struct map *map, * and ensure that current maps (eBPF) * stay intact. */ - if (map_groups__merge_in(kmaps, new_map)) + if (maps__merge_in(kmaps, new_map)) goto out_err; } } @@ -1433,9 +1431,9 @@ int __dso__load_kallsyms(struct dso *dso, const char *filename, dso->symtab_type = DSO_BINARY_TYPE__KALLSYMS; if (!no_kcore && !dso__load_kcore(dso, map, filename)) - return map_groups__split_kallsyms_for_kcore(kmap->kmaps, dso); + return maps__split_kallsyms_for_kcore(kmap->kmaps, dso); else - return map_groups__split_kallsyms(kmap->kmaps, dso, delta, map); + return maps__split_kallsyms(kmap->kmaps, dso, delta, map); } int dso__load_kallsyms(struct dso *dso, const char *filename, @@ -1772,68 +1770,67 @@ static int map__strcmp_name(const void *name, const void *b) return strcmp(name, map->dso->short_name); } -void __map_groups__sort_by_name(struct map_groups *mg) +void __maps__sort_by_name(struct maps *maps) { - qsort(mg->maps_by_name, mg->nr_maps, sizeof(struct map *), map__strcmp); + qsort(maps->maps_by_name, maps->nr_maps, sizeof(struct map *), map__strcmp); } -static int map__groups__sort_by_name_from_rbtree(struct map_groups *mg) +static int map__groups__sort_by_name_from_rbtree(struct maps *maps) { struct map *map; - struct map **maps_by_name = realloc(mg->maps_by_name, mg->nr_maps * sizeof(map)); + struct map **maps_by_name = realloc(maps->maps_by_name, maps->nr_maps * sizeof(map)); int i = 0; if (maps_by_name == NULL) return -1; - mg->maps_by_name = maps_by_name; - mg->nr_maps_allocated = mg->nr_maps; + maps->maps_by_name = maps_by_name; + maps->nr_maps_allocated = maps->nr_maps; - maps__for_each_entry(&mg->maps, map) + maps__for_each_entry(maps, map) maps_by_name[i++] = map; - __map_groups__sort_by_name(mg); + __maps__sort_by_name(maps); return 0; } -static struct map *__map_groups__find_by_name(struct map_groups *mg, const char *name) +static struct map *__maps__find_by_name(struct maps *maps, const char *name) { struct map **mapp; - if (mg->maps_by_name == NULL && - map__groups__sort_by_name_from_rbtree(mg)) + if (maps->maps_by_name == NULL && + map__groups__sort_by_name_from_rbtree(maps)) return NULL; - mapp = bsearch(name, mg->maps_by_name, mg->nr_maps, sizeof(*mapp), map__strcmp_name); + mapp = bsearch(name, maps->maps_by_name, maps->nr_maps, sizeof(*mapp), map__strcmp_name); if (mapp) return *mapp; return NULL; } -struct map *map_groups__find_by_name(struct map_groups *mg, const char *name) +struct map *maps__find_by_name(struct maps *maps, const char *name) { - struct maps *maps = &mg->maps; struct map *map; down_read(&maps->lock); - if (mg->last_search_by_name && strcmp(mg->last_search_by_name->dso->short_name, name) == 0) { - map = mg->last_search_by_name; + if (maps->last_search_by_name && strcmp(maps->last_search_by_name->dso->short_name, name) == 0) { + map = maps->last_search_by_name; goto out_unlock; } /* - * If we have mg->maps_by_name, then the name isn't in the rbtree, - * as mg->maps_by_name mirrors the rbtree when lookups by name are + * If we have maps->maps_by_name, then the name isn't in the rbtree, + * as maps->maps_by_name mirrors the rbtree when lookups by name are * made. */ - map = __map_groups__find_by_name(mg, name); - if (map || mg->maps_by_name != NULL) + map = __maps__find_by_name(maps, name); + if (map || maps->maps_by_name != NULL) goto out_unlock; /* Fallback to traversing the rbtree... */ maps__for_each_entry(maps, map) if (strcmp(map->dso->short_name, name) == 0) { - mg->last_search_by_name = map; + maps->last_search_by_name = map; goto out_unlock; } diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 0b718cc9fb28..93fc43db1be3 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -21,7 +21,7 @@ struct dso; struct map; -struct map_groups; +struct maps; struct option; /* @@ -108,7 +108,7 @@ struct ref_reloc_sym { struct addr_location { struct thread *thread; - struct map_groups *mg; + struct maps *maps; struct map *map; struct symbol *sym; const char *srcline; @@ -186,7 +186,7 @@ void __symbols__insert(struct rb_root_cached *symbols, struct symbol *sym, void symbols__insert(struct rb_root_cached *symbols, struct symbol *sym); void symbols__fixup_duplicate(struct rb_root_cached *symbols); void symbols__fixup_end(struct rb_root_cached *symbols); -void map_groups__fixup_end(struct map_groups *mg); +void maps__fixup_end(struct maps *maps); typedef int (*mapfn_t)(u64 start, u64 len, u64 pgoff, void *data); int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data, diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c index 48c3f8b9c852..c423298fe62d 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -493,7 +493,7 @@ static int __event__synthesize_thread(union perf_event *comm_event, /* * send mmap only for thread group leader - * see thread__init_map_groups + * see thread__init_maps() */ if (pid == tgid && perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, diff --git a/tools/perf/util/thread-stack.c b/tools/perf/util/thread-stack.c index cd8a948d03ec..0885967d5bc3 100644 --- a/tools/perf/util/thread-stack.c +++ b/tools/perf/util/thread-stack.c @@ -134,8 +134,8 @@ static int thread_stack__init(struct thread_stack *ts, struct thread *thread, if (err) return err; - if (thread->mg && thread->mg->machine) { - struct machine *machine = thread->mg->machine; + if (thread->maps && thread->maps->machine) { + struct machine *machine = thread->maps->machine; const char *arch = perf_env__arch(machine->env); ts->kernel_start = machine__kernel_start(machine); diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 0a277a920970..28b719388028 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -19,21 +19,21 @@ #include <api/fs/fs.h> -int thread__init_map_groups(struct thread *thread, struct machine *machine) +int thread__init_maps(struct thread *thread, struct machine *machine) { pid_t pid = thread->pid_; if (pid == thread->tid || pid == -1) { - thread->mg = map_groups__new(machine); + thread->maps = maps__new(machine); } else { struct thread *leader = __machine__findnew_thread(machine, pid, pid); if (leader) { - thread->mg = map_groups__get(leader->mg); + thread->maps = maps__get(leader->maps); thread__put(leader); } } - return thread->mg ? 0 : -1; + return thread->maps ? 0 : -1; } struct thread *thread__new(pid_t pid, pid_t tid) @@ -86,9 +86,9 @@ void thread__delete(struct thread *thread) thread_stack__free(thread); - if (thread->mg) { - map_groups__put(thread->mg); - thread->mg = NULL; + if (thread->maps) { + maps__put(thread->maps); + thread->maps = NULL; } down_write(&thread->namespaces_lock); list_for_each_entry_safe(namespaces, tmp_namespaces, @@ -251,7 +251,7 @@ static int ____thread__set_comm(struct thread *thread, const char *str, list_add(&new->list, &thread->comm_list); if (exec) - unwind__flush_access(thread->mg); + unwind__flush_access(thread->maps); } thread->comm_set = true; @@ -324,19 +324,19 @@ int thread__comm_len(struct thread *thread) size_t thread__fprintf(struct thread *thread, FILE *fp) { return fprintf(fp, "Thread %d %s\n", thread->tid, thread__comm_str(thread)) + - map_groups__fprintf(thread->mg, fp); + maps__fprintf(thread->maps, fp); } int thread__insert_map(struct thread *thread, struct map *map) { int ret; - ret = unwind__prepare_access(thread->mg, map, NULL); + ret = unwind__prepare_access(thread->maps, map, NULL); if (ret) return ret; - map_groups__fixup_overlappings(thread->mg, map, stderr); - map_groups__insert(thread->mg, map); + maps__fixup_overlappings(thread->maps, map, stderr); + maps__insert(thread->maps, map); return 0; } @@ -345,13 +345,13 @@ static int __thread__prepare_access(struct thread *thread) { bool initialized = false; int err = 0; - struct maps *maps = &thread->mg->maps; + struct maps *maps = thread->maps; struct map *map; down_read(&maps->lock); maps__for_each_entry(maps, map) { - err = unwind__prepare_access(thread->mg, map, &initialized); + err = unwind__prepare_access(thread->maps, map, &initialized); if (err || initialized) break; } @@ -371,21 +371,19 @@ static int thread__prepare_access(struct thread *thread) return err; } -static int thread__clone_map_groups(struct thread *thread, - struct thread *parent, - bool do_maps_clone) +static int thread__clone_maps(struct thread *thread, struct thread *parent, bool do_maps_clone) { /* This is new thread, we share map groups for process. */ if (thread->pid_ == parent->pid_) return thread__prepare_access(thread); - if (thread->mg == parent->mg) { + if (thread->maps == parent->maps) { pr_debug("broken map groups on thread %d/%d parent %d/%d\n", thread->pid_, thread->tid, parent->pid_, parent->tid); return 0; } /* But this one is new process, copy maps. */ - return do_maps_clone ? map_groups__clone(thread, parent->mg) : 0; + return do_maps_clone ? maps__clone(thread, parent->maps) : 0; } int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp, bool do_maps_clone) @@ -401,7 +399,7 @@ int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp, bo } thread->ppid = parent->tid; - return thread__clone_map_groups(thread, parent, do_maps_clone); + return thread__clone_maps(thread, parent, do_maps_clone); } void thread__find_cpumode_addr_location(struct thread *thread, u64 addr, diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index 51bdb9a7af7f..20b96b5d1f15 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h @@ -25,7 +25,7 @@ struct thread { struct rb_node rb_node; struct list_head node; }; - struct map_groups *mg; + struct maps *maps; pid_t pid_; /* Not all tools update this */ pid_t tid; pid_t ppid; @@ -53,7 +53,7 @@ struct namespaces; struct comm; struct thread *thread__new(pid_t pid, pid_t tid); -int thread__init_map_groups(struct thread *thread, struct machine *machine); +int thread__init_maps(struct thread *thread, struct machine *machine); void thread__delete(struct thread *thread); struct thread *thread__get(struct thread *thread); diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c index d2a8df01c4a7..7a3dbc259cec 100644 --- a/tools/perf/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw.c @@ -81,7 +81,7 @@ static int entry(u64 ip, struct unwind_info *ui) return -1; e->ip = ip; - e->ms.mg = al.mg; + e->ms.maps = al.maps; e->ms.map = al.map; e->ms.sym = al.sym; @@ -200,7 +200,7 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, struct unwind_info *ui, ui_buf = { .sample = data, .thread = thread, - .machine = thread->mg->machine, + .machine = thread->maps->machine, .cb = cb, .arg = arg, .max_stack = max_stack, diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c index 6d53347d6744..b4649f5a0c2f 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c @@ -578,7 +578,7 @@ static int entry(u64 ip, struct thread *thread, e.ms.sym = thread__find_symbol(thread, PERF_RECORD_MISC_USER, ip, &al); e.ip = ip; e.ms.map = al.map; - e.ms.mg = al.mg; + e.ms.maps = al.maps; pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n", al.sym ? al.sym->name : "''", @@ -616,26 +616,26 @@ static unw_accessors_t accessors = { .get_proc_name = get_proc_name, }; -static int _unwind__prepare_access(struct map_groups *mg) +static int _unwind__prepare_access(struct maps *maps) { - mg->addr_space = unw_create_addr_space(&accessors, 0); - if (!mg->addr_space) { + maps->addr_space = unw_create_addr_space(&accessors, 0); + if (!maps->addr_space) { pr_err("unwind: Can't create unwind address space.\n"); return -ENOMEM; } - unw_set_caching_policy(mg->addr_space, UNW_CACHE_GLOBAL); + unw_set_caching_policy(maps->addr_space, UNW_CACHE_GLOBAL); return 0; } -static void _unwind__flush_access(struct map_groups *mg) +static void _unwind__flush_access(struct maps *maps) { - unw_flush_cache(mg->addr_space, 0, 0); + unw_flush_cache(maps->addr_space, 0, 0); } -static void _unwind__finish_access(struct map_groups *mg) +static void _unwind__finish_access(struct maps *maps) { - unw_destroy_addr_space(mg->addr_space); + unw_destroy_addr_space(maps->addr_space); } static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, @@ -660,7 +660,7 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, */ if (max_stack - 1 > 0) { WARN_ONCE(!ui->thread, "WARNING: ui->thread is NULL"); - addr_space = ui->thread->mg->addr_space; + addr_space = ui->thread->maps->addr_space; if (addr_space == NULL) return -1; @@ -709,7 +709,7 @@ static int _unwind__get_entries(unwind_entry_cb_t cb, void *arg, struct unwind_info ui = { .sample = data, .thread = thread, - .machine = thread->mg->machine, + .machine = thread->maps->machine, }; if (!data->user_regs.regs) diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c index a24fb57c9b2c..e89a5479b361 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c @@ -12,14 +12,12 @@ struct unwind_libunwind_ops __weak *local_unwind_libunwind_ops; struct unwind_libunwind_ops __weak *x86_32_unwind_libunwind_ops; struct unwind_libunwind_ops __weak *arm64_unwind_libunwind_ops; -static void unwind__register_ops(struct map_groups *mg, - struct unwind_libunwind_ops *ops) +static void unwind__register_ops(struct maps *maps, struct unwind_libunwind_ops *ops) { - mg->unwind_libunwind_ops = ops; + maps->unwind_libunwind_ops = ops; } -int unwind__prepare_access(struct map_groups *mg, struct map *map, - bool *initialized) +int unwind__prepare_access(struct maps *maps, struct map *map, bool *initialized) { const char *arch; enum dso_type dso_type; @@ -29,7 +27,7 @@ int unwind__prepare_access(struct map_groups *mg, struct map *map, if (!dwarf_callchain_users) return 0; - if (mg->addr_space) { + if (maps->addr_space) { pr_debug("unwind: thread map already set, dso=%s\n", map->dso->name); if (initialized) @@ -38,14 +36,14 @@ int unwind__prepare_access(struct map_groups *mg, struct map *map, } /* env->arch is NULL for live-mode (i.e. perf top) */ - if (!mg->machine->env || !mg->machine->env->arch) + if (!maps->machine->env || !maps->machine->env->arch) goto out_register; - dso_type = dso__type(map->dso, mg->machine); + dso_type = dso__type(map->dso, maps->machine); if (dso_type == DSO__TYPE_UNKNOWN) return 0; - arch = perf_env__arch(mg->machine->env); + arch = perf_env__arch(maps->machine->env); if (!strcmp(arch, "x86")) { if (dso_type != DSO__TYPE_64BIT) @@ -60,31 +58,31 @@ int unwind__prepare_access(struct map_groups *mg, struct map *map, return 0; } out_register: - unwind__register_ops(mg, ops); + unwind__register_ops(maps, ops); - err = mg->unwind_libunwind_ops->prepare_access(mg); + err = maps->unwind_libunwind_ops->prepare_access(maps); if (initialized) *initialized = err ? false : true; return err; } -void unwind__flush_access(struct map_groups *mg) +void unwind__flush_access(struct maps *maps) { - if (mg->unwind_libunwind_ops) - mg->unwind_libunwind_ops->flush_access(mg); + if (maps->unwind_libunwind_ops) + maps->unwind_libunwind_ops->flush_access(maps); } -void unwind__finish_access(struct map_groups *mg) +void unwind__finish_access(struct maps *maps) { - if (mg->unwind_libunwind_ops) - mg->unwind_libunwind_ops->finish_access(mg); + if (maps->unwind_libunwind_ops) + maps->unwind_libunwind_ops->finish_access(maps); } int unwind__get_entries(unwind_entry_cb_t cb, void *arg, struct thread *thread, struct perf_sample *data, int max_stack) { - if (thread->mg->unwind_libunwind_ops) - return thread->mg->unwind_libunwind_ops->get_entries(cb, arg, thread, data, max_stack); + if (thread->maps->unwind_libunwind_ops) + return thread->maps->unwind_libunwind_ops->get_entries(cb, arg, thread, data, max_stack); return 0; } diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h index 50337c966979..ab8ad469c8de 100644 --- a/tools/perf/util/unwind.h +++ b/tools/perf/util/unwind.h @@ -6,7 +6,7 @@ #include <linux/types.h> #include "util/map_symbol.h" -struct map_groups; +struct maps; struct perf_sample; struct thread; @@ -18,9 +18,9 @@ struct unwind_entry { typedef int (*unwind_entry_cb_t)(struct unwind_entry *entry, void *arg); struct unwind_libunwind_ops { - int (*prepare_access)(struct map_groups *mg); - void (*flush_access)(struct map_groups *mg); - void (*finish_access)(struct map_groups *mg); + int (*prepare_access)(struct maps *maps); + void (*flush_access)(struct maps *maps); + void (*finish_access)(struct maps *maps); int (*get_entries)(unwind_entry_cb_t cb, void *arg, struct thread *thread, struct perf_sample *data, int max_stack); @@ -45,20 +45,19 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, #endif int LIBUNWIND__ARCH_REG_ID(int regnum); -int unwind__prepare_access(struct map_groups *mg, struct map *map, - bool *initialized); -void unwind__flush_access(struct map_groups *mg); -void unwind__finish_access(struct map_groups *mg); +int unwind__prepare_access(struct maps *maps, struct map *map, bool *initialized); +void unwind__flush_access(struct maps *maps); +void unwind__finish_access(struct maps *maps); #else -static inline int unwind__prepare_access(struct map_groups *mg __maybe_unused, +static inline int unwind__prepare_access(struct maps *maps __maybe_unused, struct map *map __maybe_unused, bool *initialized __maybe_unused) { return 0; } -static inline void unwind__flush_access(struct map_groups *mg __maybe_unused) {} -static inline void unwind__finish_access(struct map_groups *mg __maybe_unused) {} +static inline void unwind__flush_access(struct maps *maps __maybe_unused) {} +static inline void unwind__finish_access(struct maps *maps __maybe_unused) {} #endif #else static inline int @@ -71,14 +70,14 @@ unwind__get_entries(unwind_entry_cb_t cb __maybe_unused, return 0; } -static inline int unwind__prepare_access(struct map_groups *mg __maybe_unused, +static inline int unwind__prepare_access(struct maps *maps __maybe_unused, struct map *map __maybe_unused, bool *initialized __maybe_unused) { return 0; } -static inline void unwind__flush_access(struct map_groups *mg __maybe_unused) {} -static inline void unwind__finish_access(struct map_groups *mg __maybe_unused) {} +static inline void unwind__flush_access(struct maps *maps __maybe_unused) {} +static inline void unwind__finish_access(struct maps *maps __maybe_unused) {} #endif /* HAVE_DWARF_UNWIND_SUPPORT */ #endif /* __UNWIND_H */ diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c index 6e00793c10ee..3cc91ad048ea 100644 --- a/tools/perf/util/vdso.c +++ b/tools/perf/util/vdso.c @@ -144,7 +144,7 @@ static enum dso_type machine__thread_dso_type(struct machine *machine, enum dso_type dso_type = DSO__TYPE_UNKNOWN; struct map *map; - map_groups__for_each_entry(thread->mg, map) { + maps__for_each_entry(thread->maps, map) { struct dso *dso = map->dso; if (!dso || dso->long_name[0] != '/') continue; diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 2a9890c8395a..944183f9ed5a 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -11,10 +11,11 @@ struct process_cmd_struct { char *feature; char *command; - void (*process_fn)(void); + void (*process_fn)(int arg); + int arg; }; -static const char *version_str = "v1.0"; +static const char *version_str = "v1.1"; static const int supported_api_ver = 1; static struct isst_if_platform_info isst_platform_info; static char *progname; @@ -22,6 +23,7 @@ static int debug_flag; static FILE *outf; static int cpu_model; +static int cpu_stepping; #define MAX_CPUS_IN_ONE_REQ 64 static short max_target_cpus; @@ -39,6 +41,7 @@ static unsigned long long fact_trl; static int out_format_json; static int cmd_help; static int force_online_offline; +static int auto_mode; /* clos related */ static int current_clos = -1; @@ -70,7 +73,16 @@ void debug_printf(const char *format, ...) va_end(args); } -static void update_cpu_model(void) + +int is_clx_n_platform(void) +{ + if (cpu_model == 0x55) + if (cpu_stepping == 0x6 || cpu_stepping == 0x7) + return 1; + return 0; +} + +static int update_cpu_model(void) { unsigned int ebx, ecx, edx; unsigned int fms, family; @@ -80,6 +92,33 @@ static void update_cpu_model(void) cpu_model = (fms >> 4) & 0xf; if (family == 6 || family == 0xf) cpu_model += ((fms >> 16) & 0xf) << 4; + + cpu_stepping = fms & 0xf; + /* only three CascadeLake-N models are supported */ + if (is_clx_n_platform()) { + FILE *fp; + size_t n = 0; + char *line = NULL; + int ret = 1; + + fp = fopen("/proc/cpuinfo", "r"); + if (!fp) + err(-1, "cannot open /proc/cpuinfo\n"); + + while (getline(&line, &n, fp) > 0) { + if (strstr(line, "model name")) { + if (strstr(line, "6252N") || + strstr(line, "6230N") || + strstr(line, "5218N")) + ret = 0; + break; + } + } + free(line); + fclose(fp); + return ret; + } + return 0; } /* Open a file, and exit on failure */ @@ -161,6 +200,11 @@ int get_physical_die_id(int cpu) return ret; } +int get_cpufreq_base_freq(int cpu) +{ + return parse_int_file(0, "/sys/devices/system/cpu/cpu%d/cpufreq/base_frequency", cpu); +} + int get_topo_max_cpus(void) { return topo_max_cpus; @@ -169,7 +213,7 @@ int get_topo_max_cpus(void) static void set_cpu_online_offline(int cpu, int state) { char buffer[128]; - int fd; + int fd, ret; snprintf(buffer, sizeof(buffer), "/sys/devices/system/cpu/cpu%d/online", cpu); @@ -179,9 +223,12 @@ static void set_cpu_online_offline(int cpu, int state) err(-1, "%s open failed", buffer); if (state) - write(fd, "1\n", 2); + ret = write(fd, "1\n", 2); else - write(fd, "0\n", 2); + ret = write(fd, "0\n", 2); + + if (ret == -1) + perror("Online/Offline: Operation failed\n"); close(fd); } @@ -291,6 +338,7 @@ void free_cpu_set(cpu_set_t *cpu_set) } static int cpu_cnt[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE]; +static long long core_mask[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE]; static void set_cpu_present_cpu_mask(void) { size_t size; @@ -315,13 +363,33 @@ static void set_cpu_present_cpu_mask(void) pkg_id = get_physical_package_id(i); if (pkg_id < MAX_PACKAGE_COUNT && - die_id < MAX_DIE_PER_PACKAGE) + die_id < MAX_DIE_PER_PACKAGE) { + int core_id = get_physical_core_id(i); + cpu_cnt[pkg_id][die_id]++; + core_mask[pkg_id][die_id] |= (1ULL << core_id); + } } closedir(dir); } } +int get_core_count(int pkg_id, int die_id) +{ + int cnt = 0; + + if (pkg_id < MAX_PACKAGE_COUNT && die_id < MAX_DIE_PER_PACKAGE) { + int i; + + for (i = 0; i < sizeof(long long) * 8; ++i) { + if (core_mask[pkg_id][die_id] & (1ULL << i)) + cnt++; + } + } + + return cnt; +} + int get_cpu_count(int pkg_id, int die_id) { if (pkg_id < MAX_PACKAGE_COUNT && die_id < MAX_DIE_PER_PACKAGE) @@ -532,12 +600,6 @@ int isst_send_mbox_command(unsigned int cpu, unsigned char command, if (!ret && !write) *resp = value; break; - case CLOS_PM_QOS_CONFIG: - ret = isst_send_mmio_command(cpu, PM_QOS_CONFIG_OFFSET, - write, &value); - if (!ret && !write) - *resp = value; - break; case CLOS_STATUS: break; default: @@ -562,6 +624,7 @@ int isst_send_mbox_command(unsigned int cpu, unsigned char command, fprintf(outf, "Error: mbox_cmd cpu:%d command:%x sub_command:%x parameter:%x req_data:%x\n", cpu, command, sub_command, parameter, req_data); + return -1; } else { *resp = mbox_cmds.mbox_cmd[0].resp_data; debug_printf( @@ -678,7 +741,7 @@ static void exec_on_get_ctdp_cpu(int cpu, void *arg1, void *arg2, void *arg3, } #define _get_tdp_level(desc, suffix, object, help) \ - static void get_tdp_##object(void) \ + static void get_tdp_##object(int arg) \ { \ struct isst_pkg_ctdp ctdp; \ \ @@ -708,6 +771,152 @@ _get_tdp_level("get-config-current_level", levels, current_level, "Current TDP Level"); _get_tdp_level("get-lock-status", levels, locked, "TDP lock status"); +struct isst_pkg_ctdp clx_n_pkg_dev; + +static int clx_n_get_base_ratio(void) +{ + FILE *fp; + char *begin, *end, *line = NULL; + char number[5]; + float value = 0; + size_t n = 0; + + fp = fopen("/proc/cpuinfo", "r"); + if (!fp) + err(-1, "cannot open /proc/cpuinfo\n"); + + while (getline(&line, &n, fp) > 0) { + if (strstr(line, "model name")) { + /* this is true for CascadeLake-N */ + begin = strstr(line, "@ ") + 2; + end = strstr(line, "GHz"); + strncpy(number, begin, end - begin); + value = atof(number) * 10; + break; + } + } + free(line); + fclose(fp); + + return (int)(value); +} + +static int clx_n_config(int cpu) +{ + int i, ret, pkg_id, die_id; + unsigned long cpu_bf; + struct isst_pkg_ctdp_level_info *ctdp_level; + struct isst_pbf_info *pbf_info; + + ctdp_level = &clx_n_pkg_dev.ctdp_level[0]; + pbf_info = &ctdp_level->pbf_info; + ctdp_level->core_cpumask_size = + alloc_cpu_set(&ctdp_level->core_cpumask); + + /* find the frequency base ratio */ + ctdp_level->tdp_ratio = clx_n_get_base_ratio(); + if (ctdp_level->tdp_ratio == 0) { + debug_printf("CLX: cn base ratio is zero\n"); + ret = -1; + goto error_ret; + } + + /* find the high and low priority frequencies */ + pbf_info->p1_high = 0; + pbf_info->p1_low = ~0; + + pkg_id = get_physical_package_id(cpu); + die_id = get_physical_die_id(cpu); + + for (i = 0; i < topo_max_cpus; i++) { + if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask)) + continue; + + if (pkg_id != get_physical_package_id(i) || + die_id != get_physical_die_id(i)) + continue; + + CPU_SET_S(i, ctdp_level->core_cpumask_size, + ctdp_level->core_cpumask); + + cpu_bf = parse_int_file(1, + "/sys/devices/system/cpu/cpu%d/cpufreq/base_frequency", + i); + if (cpu_bf > pbf_info->p1_high) + pbf_info->p1_high = cpu_bf; + if (cpu_bf < pbf_info->p1_low) + pbf_info->p1_low = cpu_bf; + } + + if (pbf_info->p1_high == ~0UL) { + debug_printf("CLX: maximum base frequency not set\n"); + ret = -1; + goto error_ret; + } + + if (pbf_info->p1_low == 0) { + debug_printf("CLX: minimum base frequency not set\n"); + ret = -1; + goto error_ret; + } + + /* convert frequencies back to ratios */ + pbf_info->p1_high = pbf_info->p1_high / 100000; + pbf_info->p1_low = pbf_info->p1_low / 100000; + + /* create high priority cpu mask */ + pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask); + for (i = 0; i < topo_max_cpus; i++) { + if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask)) + continue; + + if (pkg_id != get_physical_package_id(i) || + die_id != get_physical_die_id(i)) + continue; + + cpu_bf = parse_int_file(1, + "/sys/devices/system/cpu/cpu%d/cpufreq/base_frequency", + i); + cpu_bf = cpu_bf / 100000; + if (cpu_bf == pbf_info->p1_high) + CPU_SET_S(i, pbf_info->core_cpumask_size, + pbf_info->core_cpumask); + } + + /* extra ctdp & pbf struct parameters */ + ctdp_level->processed = 1; + ctdp_level->pbf_support = 1; /* PBF is always supported and enabled */ + ctdp_level->pbf_enabled = 1; + ctdp_level->fact_support = 0; /* FACT is never supported */ + ctdp_level->fact_enabled = 0; + + return 0; + +error_ret: + free_cpu_set(ctdp_level->core_cpumask); + return ret; +} + +static void dump_clx_n_config_for_cpu(int cpu, void *arg1, void *arg2, + void *arg3, void *arg4) +{ + int ret; + + ret = clx_n_config(cpu); + if (ret) { + perror("isst_get_process_ctdp"); + } else { + struct isst_pkg_ctdp_level_info *ctdp_level; + struct isst_pbf_info *pbf_info; + + ctdp_level = &clx_n_pkg_dev.ctdp_level[0]; + pbf_info = &ctdp_level->pbf_info; + isst_ctdp_display_information(cpu, outf, tdp_level, &clx_n_pkg_dev); + free_cpu_set(ctdp_level->core_cpumask); + free_cpu_set(pbf_info->core_cpumask); + } +} + static void dump_isst_config_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, void *arg4) { @@ -724,8 +933,10 @@ static void dump_isst_config_for_cpu(int cpu, void *arg1, void *arg2, } } -static void dump_isst_config(void) +static void dump_isst_config(int arg) { + void *fn; + if (cmd_help) { fprintf(stderr, "Print Intel(R) Speed Select Technology Performance profile configuration\n"); @@ -737,14 +948,17 @@ static void dump_isst_config(void) exit(0); } + if (!is_clx_n_platform()) + fn = dump_isst_config_for_cpu; + else + fn = dump_clx_n_config_for_cpu; + isst_ctdp_display_information_start(outf); if (max_target_cpus) - for_each_online_target_cpu_in_set(dump_isst_config_for_cpu, - NULL, NULL, NULL, NULL); + for_each_online_target_cpu_in_set(fn, NULL, NULL, NULL, NULL); else - for_each_online_package_in_set(dump_isst_config_for_cpu, NULL, - NULL, NULL, NULL); + for_each_online_package_in_set(fn, NULL, NULL, NULL, NULL); isst_ctdp_display_information_end(outf); } @@ -787,7 +1001,7 @@ static void set_tdp_level_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, } } -static void set_tdp_level(void) +static void set_tdp_level(int arg) { if (cmd_help) { fprintf(stderr, "Set Config TDP level\n"); @@ -812,6 +1026,26 @@ static void set_tdp_level(void) isst_ctdp_display_information_end(outf); } +static void clx_n_dump_pbf_config_for_cpu(int cpu, void *arg1, void *arg2, + void *arg3, void *arg4) +{ + int ret; + + ret = clx_n_config(cpu); + if (ret) { + perror("isst_get_process_ctdp"); + } else { + struct isst_pkg_ctdp_level_info *ctdp_level; + struct isst_pbf_info *pbf_info; + + ctdp_level = &clx_n_pkg_dev.ctdp_level[0]; + pbf_info = &ctdp_level->pbf_info; + isst_pbf_display_information(cpu, outf, tdp_level, pbf_info); + free_cpu_set(ctdp_level->core_cpumask); + free_cpu_set(pbf_info->core_cpumask); + } +} + static void dump_pbf_config_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, void *arg4) { @@ -827,8 +1061,10 @@ static void dump_pbf_config_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, } } -static void dump_pbf_config(void) +static void dump_pbf_config(int arg) { + void *fn; + if (cmd_help) { fprintf(stderr, "Print Intel(R) Speed Select Technology base frequency configuration for a TDP level\n"); @@ -842,72 +1078,372 @@ static void dump_pbf_config(void) exit(1); } + if (!is_clx_n_platform()) + fn = dump_pbf_config_for_cpu; + else + fn = clx_n_dump_pbf_config_for_cpu; + isst_ctdp_display_information_start(outf); + if (max_target_cpus) - for_each_online_target_cpu_in_set(dump_pbf_config_for_cpu, NULL, - NULL, NULL, NULL); + for_each_online_target_cpu_in_set(fn, NULL, NULL, NULL, NULL); else - for_each_online_package_in_set(dump_pbf_config_for_cpu, NULL, - NULL, NULL, NULL); + for_each_online_package_in_set(fn, NULL, NULL, NULL, NULL); + isst_ctdp_display_information_end(outf); } -static void set_pbf_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, - void *arg4) +static int set_clos_param(int cpu, int clos, int epp, int wt, int min, int max) { + struct isst_clos_config clos_config; int ret; - int status = *(int *)arg4; - ret = isst_set_pbf_fact_status(cpu, 1, status); + ret = isst_pm_get_clos(cpu, clos, &clos_config); if (ret) { - perror("isst_set_pbf"); - } else { - if (status) - isst_display_result(cpu, outf, "base-freq", "enable", - ret); + perror("isst_pm_get_clos"); + return ret; + } + clos_config.clos_min = min; + clos_config.clos_max = max; + clos_config.epp = epp; + clos_config.clos_prop_prio = wt; + ret = isst_set_clos(cpu, clos, &clos_config); + if (ret) { + perror("isst_pm_set_clos"); + return ret; + } + + return 0; +} + +static int set_cpufreq_scaling_min_max(int cpu, int max, int freq) +{ + char buffer[128], freq_str[16]; + int fd, ret, len; + + if (max) + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", cpu); + else + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu); + + fd = open(buffer, O_WRONLY); + if (fd < 0) + return fd; + + snprintf(freq_str, sizeof(freq_str), "%d", freq); + len = strlen(freq_str); + ret = write(fd, freq_str, len); + if (ret == -1) { + close(fd); + return ret; + } + close(fd); + + return 0; +} + +static int set_clx_pbf_cpufreq_scaling_min_max(int cpu) +{ + struct isst_pkg_ctdp_level_info *ctdp_level; + struct isst_pbf_info *pbf_info; + int i, pkg_id, die_id, freq, freq_high, freq_low; + int ret; + + ret = clx_n_config(cpu); + if (ret) { + perror("set_clx_pbf_cpufreq_scaling_min_max"); + return ret; + } + + ctdp_level = &clx_n_pkg_dev.ctdp_level[0]; + pbf_info = &ctdp_level->pbf_info; + freq_high = pbf_info->p1_high * 100000; + freq_low = pbf_info->p1_low * 100000; + + pkg_id = get_physical_package_id(cpu); + die_id = get_physical_die_id(cpu); + for (i = 0; i < get_topo_max_cpus(); ++i) { + if (pkg_id != get_physical_package_id(i) || + die_id != get_physical_die_id(i)) + continue; + + if (CPU_ISSET_S(i, pbf_info->core_cpumask_size, + pbf_info->core_cpumask)) + freq = freq_high; else - isst_display_result(cpu, outf, "base-freq", "disable", - ret); + freq = freq_low; + + set_cpufreq_scaling_min_max(i, 1, freq); + set_cpufreq_scaling_min_max(i, 0, freq); } + + return 0; } -static void set_pbf_enable(void) +static int set_cpufreq_scaling_min_max_from_cpuinfo(int cpu, int cpuinfo_max, int scaling_max) { - int status = 1; + char buffer[128], min_freq[16]; + int fd, ret, len; - if (cmd_help) { - fprintf(stderr, - "Enable Intel Speed Select Technology base frequency feature [No command arguments are required]\n"); - exit(0); + if (!CPU_ISSET_S(cpu, present_cpumask_size, present_cpumask)) + return -1; + + if (cpuinfo_max) + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", cpu); + else + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_min_freq", cpu); + + fd = open(buffer, O_RDONLY); + if (fd < 0) + return fd; + + len = read(fd, min_freq, sizeof(min_freq)); + close(fd); + + if (len < 0) + return len; + + if (scaling_max) + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", cpu); + else + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu); + + fd = open(buffer, O_WRONLY); + if (fd < 0) + return fd; + + len = strlen(min_freq); + ret = write(fd, min_freq, len); + if (ret == -1) { + close(fd); + return ret; } + close(fd); - isst_ctdp_display_information_start(outf); - if (max_target_cpus) - for_each_online_target_cpu_in_set(set_pbf_for_cpu, NULL, NULL, - NULL, &status); + return 0; +} + +static void set_scaling_min_to_cpuinfo_max(int cpu) +{ + int i, pkg_id, die_id; + + pkg_id = get_physical_package_id(cpu); + die_id = get_physical_die_id(cpu); + for (i = 0; i < get_topo_max_cpus(); ++i) { + if (pkg_id != get_physical_package_id(i) || + die_id != get_physical_die_id(i)) + continue; + + set_cpufreq_scaling_min_max_from_cpuinfo(i, 1, 0); + } +} + +static void set_scaling_min_to_cpuinfo_min(int cpu) +{ + int i, pkg_id, die_id; + + pkg_id = get_physical_package_id(cpu); + die_id = get_physical_die_id(cpu); + for (i = 0; i < get_topo_max_cpus(); ++i) { + if (pkg_id != get_physical_package_id(i) || + die_id != get_physical_die_id(i)) + continue; + + set_cpufreq_scaling_min_max_from_cpuinfo(i, 0, 0); + } +} + +static void set_scaling_max_to_cpuinfo_max(int cpu) +{ + int i, pkg_id, die_id; + + pkg_id = get_physical_package_id(cpu); + die_id = get_physical_die_id(cpu); + for (i = 0; i < get_topo_max_cpus(); ++i) { + if (pkg_id != get_physical_package_id(i) || + die_id != get_physical_die_id(i)) + continue; + + set_cpufreq_scaling_min_max_from_cpuinfo(i, 1, 1); + } +} + +static int set_core_priority_and_min(int cpu, int mask_size, + cpu_set_t *cpu_mask, int min_high, + int min_low) +{ + int pkg_id, die_id, ret, i; + + if (!CPU_COUNT_S(mask_size, cpu_mask)) + return -1; + + ret = set_clos_param(cpu, 0, 0, 0, min_high, 0xff); + if (ret) + return ret; + + ret = set_clos_param(cpu, 1, 15, 15, min_low, 0xff); + if (ret) + return ret; + + ret = set_clos_param(cpu, 2, 15, 15, min_low, 0xff); + if (ret) + return ret; + + ret = set_clos_param(cpu, 3, 15, 15, min_low, 0xff); + if (ret) + return ret; + + pkg_id = get_physical_package_id(cpu); + die_id = get_physical_die_id(cpu); + for (i = 0; i < get_topo_max_cpus(); ++i) { + int clos; + + if (pkg_id != get_physical_package_id(i) || + die_id != get_physical_die_id(i)) + continue; + + if (CPU_ISSET_S(i, mask_size, cpu_mask)) + clos = 0; + else + clos = 3; + + debug_printf("Associate cpu: %d clos: %d\n", i, clos); + ret = isst_clos_associate(i, clos); + if (ret) { + perror("isst_clos_associate"); + return ret; + } + } + + return 0; +} + +static int set_pbf_core_power(int cpu) +{ + struct isst_pbf_info pbf_info; + struct isst_pkg_ctdp pkg_dev; + int ret; + + ret = isst_get_ctdp_levels(cpu, &pkg_dev); + if (ret) { + perror("isst_get_ctdp_levels"); + return ret; + } + debug_printf("Current_level: %d\n", pkg_dev.current_level); + + ret = isst_get_pbf_info(cpu, pkg_dev.current_level, &pbf_info); + if (ret) { + perror("isst_get_pbf_info"); + return ret; + } + debug_printf("p1_high: %d p1_low: %d\n", pbf_info.p1_high, + pbf_info.p1_low); + + ret = set_core_priority_and_min(cpu, pbf_info.core_cpumask_size, + pbf_info.core_cpumask, + pbf_info.p1_high, pbf_info.p1_low); + if (ret) { + perror("set_core_priority_and_min"); + return ret; + } + + ret = isst_pm_qos_config(cpu, 1, 1); + if (ret) { + perror("isst_pm_qos_config"); + return ret; + } + + return 0; +} + +static void set_pbf_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, + void *arg4) +{ + int ret; + int status = *(int *)arg4; + + if (is_clx_n_platform()) { + if (status) { + ret = 0; + if (auto_mode) + set_clx_pbf_cpufreq_scaling_min_max(cpu); + + } else { + ret = -1; + if (auto_mode) { + set_scaling_max_to_cpuinfo_max(cpu); + set_scaling_min_to_cpuinfo_min(cpu); + } + } + goto disp_result; + } + + if (auto_mode) { + if (status) { + ret = set_pbf_core_power(cpu); + if (ret) + goto disp_result; + } else { + isst_pm_qos_config(cpu, 0, 0); + } + } + + ret = isst_set_pbf_fact_status(cpu, 1, status); + if (ret) { + perror("isst_set_pbf"); + if (auto_mode) + isst_pm_qos_config(cpu, 0, 0); + } else { + if (auto_mode) { + if (status) + set_scaling_min_to_cpuinfo_max(cpu); + else + set_scaling_min_to_cpuinfo_min(cpu); + } + } + +disp_result: + if (status) + isst_display_result(cpu, outf, "base-freq", "enable", + ret); else - for_each_online_package_in_set(set_pbf_for_cpu, NULL, NULL, - NULL, &status); - isst_ctdp_display_information_end(outf); + isst_display_result(cpu, outf, "base-freq", "disable", + ret); } -static void set_pbf_disable(void) +static void set_pbf_enable(int arg) { - int status = 0; + int enable = arg; if (cmd_help) { - fprintf(stderr, - "Disable Intel Speed Select Technology base frequency feature [No command arguments are required]\n"); + if (enable) { + fprintf(stderr, + "Enable Intel Speed Select Technology base frequency feature\n"); + fprintf(stderr, + "\tOptional Arguments: -a|--auto : Use priority of cores to set core-power associations\n"); + } else { + + fprintf(stderr, + "Disable Intel Speed Select Technology base frequency feature\n"); + fprintf(stderr, + "\tOptional Arguments: -a|--auto : Also disable core-power associations\n"); + } exit(0); } isst_ctdp_display_information_start(outf); if (max_target_cpus) for_each_online_target_cpu_in_set(set_pbf_for_cpu, NULL, NULL, - NULL, &status); + NULL, &enable); else for_each_online_package_in_set(set_pbf_for_cpu, NULL, NULL, - NULL, &status); + NULL, &enable); isst_ctdp_display_information_end(outf); } @@ -925,7 +1461,7 @@ static void dump_fact_config_for_cpu(int cpu, void *arg1, void *arg2, fact_avx, &fact_info); } -static void dump_fact_config(void) +static void dump_fact_config(int arg) { if (cmd_help) { fprintf(stderr, @@ -960,73 +1496,156 @@ static void set_fact_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, int ret; int status = *(int *)arg4; + if (auto_mode) { + if (status) { + ret = isst_pm_qos_config(cpu, 1, 1); + if (ret) + goto disp_results; + } else { + isst_pm_qos_config(cpu, 0, 0); + } + } + ret = isst_set_pbf_fact_status(cpu, 0, status); - if (ret) + if (ret) { perror("isst_set_fact"); - else { - if (status) { - struct isst_pkg_ctdp pkg_dev; + if (auto_mode) + isst_pm_qos_config(cpu, 0, 0); - ret = isst_get_ctdp_levels(cpu, &pkg_dev); - if (ret) { - isst_display_result(cpu, outf, "turbo-freq", - "enable", ret); - return; - } + goto disp_results; + } + + /* Set TRL */ + if (status) { + struct isst_pkg_ctdp pkg_dev; + + ret = isst_get_ctdp_levels(cpu, &pkg_dev); + if (!ret) ret = isst_set_trl(cpu, fact_trl); - isst_display_result(cpu, outf, "turbo-freq", "enable", - ret); - } else { - /* Since we modified TRL during Fact enable, restore it */ - isst_set_trl_from_current_tdp(cpu, fact_trl); - isst_display_result(cpu, outf, "turbo-freq", "disable", - ret); - } + if (ret && auto_mode) + isst_pm_qos_config(cpu, 0, 0); + } + +disp_results: + if (status) { + isst_display_result(cpu, outf, "turbo-freq", "enable", ret); + } else { + /* Since we modified TRL during Fact enable, restore it */ + isst_set_trl_from_current_tdp(cpu, fact_trl); + isst_display_result(cpu, outf, "turbo-freq", "disable", ret); } } -static void set_fact_enable(void) +static void set_fact_enable(int arg) { - int status = 1; + int i, ret, enable = arg; if (cmd_help) { - fprintf(stderr, - "Enable Intel Speed Select Technology Turbo frequency feature\n"); - fprintf(stderr, - "Optional: -t|--trl : Specify turbo ratio limit\n"); + if (enable) { + fprintf(stderr, + "Enable Intel Speed Select Technology Turbo frequency feature\n"); + fprintf(stderr, + "Optional: -t|--trl : Specify turbo ratio limit\n"); + fprintf(stderr, + "\tOptional Arguments: -a|--auto : Designate specified target CPUs with"); + fprintf(stderr, + "-C|--cpu option as as high priority using core-power feature\n"); + } else { + fprintf(stderr, + "Disable Intel Speed Select Technology turbo frequency feature\n"); + fprintf(stderr, + "Optional: -t|--trl : Specify turbo ratio limit\n"); + fprintf(stderr, + "\tOptional Arguments: -a|--auto : Also disable core-power associations\n"); + } exit(0); } isst_ctdp_display_information_start(outf); if (max_target_cpus) for_each_online_target_cpu_in_set(set_fact_for_cpu, NULL, NULL, - NULL, &status); + NULL, &enable); else for_each_online_package_in_set(set_fact_for_cpu, NULL, NULL, - NULL, &status); + NULL, &enable); isst_ctdp_display_information_end(outf); -} -static void set_fact_disable(void) -{ - int status = 0; + if (enable && auto_mode) { + /* + * When we adjust CLOS param, we have to set for siblings also. + * So for the each user specified CPU, also add the sibling + * in the present_cpu_mask. + */ + for (i = 0; i < get_topo_max_cpus(); ++i) { + char buffer[128], sibling_list[128], *cpu_str; + int fd, len; - if (cmd_help) { - fprintf(stderr, - "Disable Intel Speed Select Technology turbo frequency feature\n"); - fprintf(stderr, - "Optional: -t|--trl : Specify turbo ratio limit\n"); - exit(0); + if (!CPU_ISSET_S(i, target_cpumask_size, target_cpumask)) + continue; + + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", i); + + fd = open(buffer, O_RDONLY); + if (fd < 0) + continue; + + len = read(fd, sibling_list, sizeof(sibling_list)); + close(fd); + + if (len < 0) + continue; + + cpu_str = strtok(sibling_list, ","); + while (cpu_str != NULL) { + int cpu; + + sscanf(cpu_str, "%d", &cpu); + CPU_SET_S(cpu, target_cpumask_size, target_cpumask); + cpu_str = strtok(NULL, ","); + } + } + + for (i = 0; i < get_topo_max_cpus(); ++i) { + int clos; + + if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask)) + continue; + + ret = set_clos_param(i, 0, 0, 0, 0, 0xff); + if (ret) + goto error_disp; + + ret = set_clos_param(i, 1, 15, 15, 0, 0xff); + if (ret) + goto error_disp; + + ret = set_clos_param(i, 2, 15, 15, 0, 0xff); + if (ret) + goto error_disp; + + ret = set_clos_param(i, 3, 15, 15, 0, 0xff); + if (ret) + goto error_disp; + + if (CPU_ISSET_S(i, target_cpumask_size, target_cpumask)) + clos = 0; + else + clos = 3; + + debug_printf("Associate cpu: %d clos: %d\n", i, clos); + ret = isst_clos_associate(i, clos); + if (ret) + goto error_disp; + } + isst_display_result(i, outf, "turbo-freq --auto", "enable", 0); } - isst_ctdp_display_information_start(outf); - if (max_target_cpus) - for_each_online_target_cpu_in_set(set_fact_for_cpu, NULL, NULL, - NULL, &status); - else - for_each_online_package_in_set(set_fact_for_cpu, NULL, NULL, - NULL, &status); - isst_ctdp_display_information_end(outf); + return; + +error_disp: + isst_display_result(i, outf, "turbo-freq --auto", "enable", ret); + } static void enable_clos_qos_config(int cpu, void *arg1, void *arg2, void *arg3, @@ -1036,31 +1655,36 @@ static void enable_clos_qos_config(int cpu, void *arg1, void *arg2, void *arg3, int status = *(int *)arg4; ret = isst_pm_qos_config(cpu, status, clos_priority_type); - if (ret) { + if (ret) perror("isst_pm_qos_config"); - } else { - if (status) - isst_display_result(cpu, outf, "core-power", "enable", - ret); - else - isst_display_result(cpu, outf, "core-power", "disable", - ret); - } + + if (status) + isst_display_result(cpu, outf, "core-power", "enable", + ret); + else + isst_display_result(cpu, outf, "core-power", "disable", + ret); } -static void set_clos_enable(void) +static void set_clos_enable(int arg) { - int status = 1; + int enable = arg; if (cmd_help) { - fprintf(stderr, "Enable core-power for a package/die\n"); - fprintf(stderr, - "\tClos Enable: Specify priority type with [--priority|-p]\n"); - fprintf(stderr, "\t\t 0: Proportional, 1: Ordered\n"); + if (enable) { + fprintf(stderr, + "Enable core-power for a package/die\n"); + fprintf(stderr, + "\tClos Enable: Specify priority type with [--priority|-p]\n"); + fprintf(stderr, "\t\t 0: Proportional, 1: Ordered\n"); + } else { + fprintf(stderr, + "Disable core-power: [No command arguments are required]\n"); + } exit(0); } - if (cpufreq_sysfs_present()) { + if (enable && cpufreq_sysfs_present()) { fprintf(stderr, "cpufreq subsystem and core-power enable will interfere with each other!\n"); } @@ -1068,30 +1692,10 @@ static void set_clos_enable(void) isst_ctdp_display_information_start(outf); if (max_target_cpus) for_each_online_target_cpu_in_set(enable_clos_qos_config, NULL, - NULL, NULL, &status); + NULL, NULL, &enable); else for_each_online_package_in_set(enable_clos_qos_config, NULL, - NULL, NULL, &status); - isst_ctdp_display_information_end(outf); -} - -static void set_clos_disable(void) -{ - int status = 0; - - if (cmd_help) { - fprintf(stderr, - "Disable core-power: [No command arguments are required]\n"); - exit(0); - } - - isst_ctdp_display_information_start(outf); - if (max_target_cpus) - for_each_online_target_cpu_in_set(enable_clos_qos_config, NULL, - NULL, NULL, &status); - else - for_each_online_package_in_set(enable_clos_qos_config, NULL, - NULL, NULL, &status); + NULL, NULL, &enable); isst_ctdp_display_information_end(outf); } @@ -1109,7 +1713,7 @@ static void dump_clos_config_for_cpu(int cpu, void *arg1, void *arg2, &clos_config); } -static void dump_clos_config(void) +static void dump_clos_config(int arg) { if (cmd_help) { fprintf(stderr, @@ -1145,7 +1749,7 @@ static void get_clos_info_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, isst_clos_display_clos_information(cpu, outf, enable, prio_type); } -static void dump_clos_info(void) +static void dump_clos_info(int arg) { if (cmd_help) { fprintf(stderr, @@ -1188,7 +1792,7 @@ static void set_clos_config_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, isst_display_result(cpu, outf, "core-power", "config", ret); } -static void set_clos_config(void) +static void set_clos_config(int arg) { if (cmd_help) { fprintf(stderr, @@ -1198,9 +1802,9 @@ static void set_clos_config(void) fprintf(stderr, "\tSpecify clos EPP with [--epp|-e]\n"); fprintf(stderr, "\tSpecify clos Proportional Priority [--weight|-w]\n"); - fprintf(stderr, "\tSpecify clos min with [--min|-n]\n"); - fprintf(stderr, "\tSpecify clos max with [--max|-m]\n"); - fprintf(stderr, "\tSpecify clos desired with [--desired|-d]\n"); + fprintf(stderr, "\tSpecify clos min in MHz with [--min|-n]\n"); + fprintf(stderr, "\tSpecify clos max in MHz with [--max|-m]\n"); + fprintf(stderr, "\tSpecify clos desired in MHz with [--desired|-d]\n"); exit(0); } @@ -1222,7 +1826,7 @@ static void set_clos_config(void) clos_min = 0; } if (clos_max < 0) { - fprintf(stderr, "clos max is not specified, default: 0xff\n"); + fprintf(stderr, "clos max is not specified, default: 25500 MHz\n"); clos_max = 0xff; } if (clos_desired < 0) { @@ -1252,7 +1856,7 @@ static void set_clos_assoc_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, isst_display_result(cpu, outf, "core-power", "assoc", ret); } -static void set_clos_assoc(void) +static void set_clos_assoc(int arg) { if (cmd_help) { fprintf(stderr, "Associate a clos id to a CPU\n"); @@ -1286,7 +1890,7 @@ static void get_clos_assoc_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, isst_clos_display_assoc_information(cpu, outf, clos); } -static void get_clos_assoc(void) +static void get_clos_assoc(int arg) { if (cmd_help) { fprintf(stderr, "Get associate clos id to a CPU\n"); @@ -1306,27 +1910,36 @@ static void get_clos_assoc(void) isst_ctdp_display_information_end(outf); } +static struct process_cmd_struct clx_n_cmds[] = { + { "perf-profile", "info", dump_isst_config, 0 }, + { "base-freq", "info", dump_pbf_config, 0 }, + { "base-freq", "enable", set_pbf_enable, 1 }, + { "base-freq", "disable", set_pbf_enable, 0 }, + { NULL, NULL, NULL, 0 } +}; + static struct process_cmd_struct isst_cmds[] = { - { "perf-profile", "get-lock-status", get_tdp_locked }, - { "perf-profile", "get-config-levels", get_tdp_levels }, - { "perf-profile", "get-config-version", get_tdp_version }, - { "perf-profile", "get-config-enabled", get_tdp_enabled }, - { "perf-profile", "get-config-current-level", get_tdp_current_level }, - { "perf-profile", "set-config-level", set_tdp_level }, - { "perf-profile", "info", dump_isst_config }, - { "base-freq", "info", dump_pbf_config }, - { "base-freq", "enable", set_pbf_enable }, - { "base-freq", "disable", set_pbf_disable }, - { "turbo-freq", "info", dump_fact_config }, - { "turbo-freq", "enable", set_fact_enable }, - { "turbo-freq", "disable", set_fact_disable }, - { "core-power", "info", dump_clos_info }, - { "core-power", "enable", set_clos_enable }, - { "core-power", "disable", set_clos_disable }, - { "core-power", "config", set_clos_config }, - { "core-power", "get-config", dump_clos_config }, - { "core-power", "assoc", set_clos_assoc }, - { "core-power", "get-assoc", get_clos_assoc }, + { "perf-profile", "get-lock-status", get_tdp_locked, 0 }, + { "perf-profile", "get-config-levels", get_tdp_levels, 0 }, + { "perf-profile", "get-config-version", get_tdp_version, 0 }, + { "perf-profile", "get-config-enabled", get_tdp_enabled, 0 }, + { "perf-profile", "get-config-current-level", get_tdp_current_level, + 0 }, + { "perf-profile", "set-config-level", set_tdp_level, 0 }, + { "perf-profile", "info", dump_isst_config, 0 }, + { "base-freq", "info", dump_pbf_config, 0 }, + { "base-freq", "enable", set_pbf_enable, 1 }, + { "base-freq", "disable", set_pbf_enable, 0 }, + { "turbo-freq", "info", dump_fact_config, 0 }, + { "turbo-freq", "enable", set_fact_enable, 1 }, + { "turbo-freq", "disable", set_fact_enable, 0 }, + { "core-power", "info", dump_clos_info, 0 }, + { "core-power", "enable", set_clos_enable, 1 }, + { "core-power", "disable", set_clos_enable, 0 }, + { "core-power", "config", set_clos_config, 0 }, + { "core-power", "get-config", dump_clos_config, 0 }, + { "core-power", "assoc", set_clos_assoc, 0 }, + { "core-power", "get-assoc", get_clos_assoc, 0 }, { NULL, NULL, NULL } }; @@ -1417,15 +2030,19 @@ static void parse_cmd_args(int argc, int start, char **argv) { "max", required_argument, 0, 'm' }, { "priority", required_argument, 0, 'p' }, { "weight", required_argument, 0, 'w' }, + { "auto", no_argument, 0, 'a' }, { 0, 0, 0, 0 } }; option_index = start; optind = start + 1; - while ((opt = getopt_long(argc, argv, "b:l:t:c:d:e:n:m:p:w:ho", + while ((opt = getopt_long(argc, argv, "b:l:t:c:d:e:n:m:p:w:hoa", long_options, &option_index)) != -1) { switch (opt) { + case 'a': + auto_mode = 1; + break; case 'b': fact_bucket = atoi(optarg); break; @@ -1459,15 +2076,18 @@ static void parse_cmd_args(int argc, int start, char **argv) break; case 'd': clos_desired = atoi(optarg); + clos_desired /= DISP_FREQ_MULTIPLIER; break; case 'e': clos_epp = atoi(optarg); break; case 'n': clos_min = atoi(optarg); + clos_min /= DISP_FREQ_MULTIPLIER; break; case 'm': clos_max = atoi(optarg); + clos_max /= DISP_FREQ_MULTIPLIER; break; case 'p': clos_priority_type = atoi(optarg); @@ -1489,12 +2109,15 @@ static void isst_help(void) TDP, etc.\n"); printf("\nCommands : For feature=perf-profile\n"); printf("\tinfo\n"); - printf("\tget-lock-status\n"); - printf("\tget-config-levels\n"); - printf("\tget-config-version\n"); - printf("\tget-config-enabled\n"); - printf("\tget-config-current-level\n"); - printf("\tset-config-level\n"); + + if (!is_clx_n_platform()) { + printf("\tget-lock-status\n"); + printf("\tget-config-levels\n"); + printf("\tget-config-version\n"); + printf("\tget-config-enabled\n"); + printf("\tget-config-current-level\n"); + printf("\tset-config-level\n"); + } } static void pbf_help(void) @@ -1544,7 +2167,15 @@ static struct process_cmd_help_struct isst_help_cmds[] = { { NULL, NULL } }; -void process_command(int argc, char **argv) +static struct process_cmd_help_struct clx_n_help_cmds[] = { + { "perf-profile", isst_help }, + { "base-freq", pbf_help }, + { NULL, NULL } +}; + +void process_command(int argc, char **argv, + struct process_cmd_help_struct *help_cmds, + struct process_cmd_struct *cmds) { int i = 0, matched = 0; char *feature = argv[optind]; @@ -1555,23 +2186,24 @@ void process_command(int argc, char **argv) debug_printf("feature name [%s] command [%s]\n", feature, cmd); if (!strcmp(cmd, "-h") || !strcmp(cmd, "--help")) { - while (isst_help_cmds[i].feature) { - if (!strcmp(isst_help_cmds[i].feature, feature)) { - isst_help_cmds[i].process_fn(); + while (help_cmds[i].feature) { + if (!strcmp(help_cmds[i].feature, feature)) { + help_cmds[i].process_fn(); exit(0); } ++i; } } - create_cpu_map(); + if (!is_clx_n_platform()) + create_cpu_map(); i = 0; - while (isst_cmds[i].feature) { - if (!strcmp(isst_cmds[i].feature, feature) && - !strcmp(isst_cmds[i].command, cmd)) { + while (cmds[i].feature) { + if (!strcmp(cmds[i].feature, feature) && + !strcmp(cmds[i].command, cmd)) { parse_cmd_args(argc, optind + 1, argv); - isst_cmds[i].process_fn(); + cmds[i].process_fn(cmds[i].arg); matched = 1; break; } @@ -1682,17 +2314,23 @@ static void cmdline(int argc, char **argv) fprintf(stderr, "Feature name and|or command not specified\n"); exit(0); } - update_cpu_model(); + ret = update_cpu_model(); + if (ret) + err(-1, "Invalid CPU model (%d)\n", cpu_model); printf("Intel(R) Speed Select Technology\n"); printf("Executing on CPU model:%d[0x%x]\n", cpu_model, cpu_model); set_max_cpu_num(); set_cpu_present_cpu_mask(); set_cpu_target_cpu_mask(); - ret = isst_fill_platform_info(); - if (ret) - goto out; - process_command(argc, argv); + if (!is_clx_n_platform()) { + ret = isst_fill_platform_info(); + if (ret) + goto out; + process_command(argc, argv, isst_help_cmds, isst_cmds); + } else { + process_command(argc, argv, clx_n_help_cmds, clx_n_cmds); + } out: free_cpu_set(present_cpumask); free_cpu_set(target_cpumask); diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 6dee5332c9d3..d14c7bcd327a 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -13,8 +13,14 @@ int isst_get_ctdp_levels(int cpu, struct isst_pkg_ctdp *pkg_dev) ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_LEVELS_INFO, 0, 0, &resp); - if (ret) - return ret; + if (ret) { + pkg_dev->levels = 0; + pkg_dev->locked = 1; + pkg_dev->current_level = 0; + pkg_dev->version = 0; + pkg_dev->enabled = 0; + return 0; + } debug_printf("cpu:%d CONFIG_TDP_GET_LEVELS_INFO resp:%x\n", cpu, resp); @@ -95,6 +101,69 @@ int isst_get_pwr_info(int cpu, int config_index, return 0; } +void isst_get_uncore_p0_p1_info(int cpu, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + unsigned int resp; + int ret; + ret = isst_send_mbox_command(cpu, CONFIG_TDP, + CONFIG_TDP_GET_UNCORE_P0_P1_INFO, 0, + config_index, &resp); + if (ret) { + ctdp_level->uncore_p0 = 0; + ctdp_level->uncore_p1 = 0; + return; + } + + ctdp_level->uncore_p0 = resp & GENMASK(7, 0); + ctdp_level->uncore_p1 = (resp & GENMASK(15, 8)) >> 8; + debug_printf( + "cpu:%d ctdp:%d CONFIG_TDP_GET_UNCORE_P0_P1_INFO resp:%x uncore p0:%d uncore p1:%d\n", + cpu, config_index, resp, ctdp_level->uncore_p0, + ctdp_level->uncore_p1); +} + +void isst_get_p1_info(int cpu, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + unsigned int resp; + int ret; + ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_P1_INFO, 0, + config_index, &resp); + if (ret) { + ctdp_level->sse_p1 = 0; + ctdp_level->avx2_p1 = 0; + ctdp_level->avx512_p1 = 0; + return; + } + + ctdp_level->sse_p1 = resp & GENMASK(7, 0); + ctdp_level->avx2_p1 = (resp & GENMASK(15, 8)) >> 8; + ctdp_level->avx512_p1 = (resp & GENMASK(23, 16)) >> 16; + debug_printf( + "cpu:%d ctdp:%d CONFIG_TDP_GET_P1_INFO resp:%x sse_p1:%d avx2_p1:%d avx512_p1:%d\n", + cpu, config_index, resp, ctdp_level->sse_p1, + ctdp_level->avx2_p1, ctdp_level->avx512_p1); +} + +void isst_get_uncore_mem_freq(int cpu, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + unsigned int resp; + int ret; + ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_MEM_FREQ, + 0, config_index, &resp); + if (ret) { + ctdp_level->mem_freq = 0; + return; + } + + ctdp_level->mem_freq = resp & GENMASK(7, 0); + debug_printf( + "cpu:%d ctdp:%d CONFIG_TDP_GET_MEM_FREQ resp:%x uncore mem_freq:%d\n", + cpu, config_index, resp, ctdp_level->mem_freq); +} + int isst_get_tjmax_info(int cpu, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level) { @@ -149,6 +218,27 @@ int isst_get_coremask_info(int cpu, int config_index, return 0; } +int isst_get_get_trl_from_msr(int cpu, int *trl) +{ + unsigned long long msr_trl; + int ret; + + ret = isst_send_msr_command(cpu, 0x1AD, 0, &msr_trl); + if (ret) + return ret; + + trl[0] = msr_trl & GENMASK(7, 0); + trl[1] = (msr_trl & GENMASK(15, 8)) >> 8; + trl[2] = (msr_trl & GENMASK(23, 16)) >> 16; + trl[3] = (msr_trl & GENMASK(31, 24)) >> 24; + trl[4] = (msr_trl & GENMASK(39, 32)) >> 32; + trl[5] = (msr_trl & GENMASK(47, 40)) >> 40; + trl[6] = (msr_trl & GENMASK(55, 48)) >> 48; + trl[7] = (msr_trl & GENMASK(63, 56)) >> 56; + + return 0; +} + int isst_get_get_trl(int cpu, int level, int avx_level, int *trl) { unsigned int req, resp; @@ -245,12 +335,15 @@ int isst_set_tdp_level(int cpu, int tdp_level) int isst_get_pbf_info(int cpu, int level, struct isst_pbf_info *pbf_info) { + int i, ret, core_cnt, max; unsigned int req, resp; - int i, ret; pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask); - for (i = 0; i < 2; ++i) { + core_cnt = get_core_count(get_physical_package_id(cpu), get_physical_die_id(cpu)); + max = core_cnt > 32 ? 2 : 1; + + for (i = 0; i < max; ++i) { unsigned long long mask; int count; @@ -258,7 +351,7 @@ int isst_get_pbf_info(int cpu, int level, struct isst_pbf_info *pbf_info) CONFIG_TDP_PBF_GET_CORE_MASK_INFO, 0, (i << 8) | level, &resp); if (ret) - return ret; + break; debug_printf( "cpu:%d CONFIG_TDP_PBF_GET_CORE_MASK_INFO resp:%x\n", @@ -323,7 +416,7 @@ int isst_set_pbf_fact_status(int cpu, int pbf, int enable) ret = isst_get_ctdp_levels(cpu, &pkg_dev); if (ret) - return ret; + debug_printf("cpu:%d No support for dynamic ISST\n", cpu); current_level = pkg_dev.current_level; @@ -553,7 +646,6 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev) i); ctdp_level = &pkg_dev->ctdp_level[i]; - ctdp_level->processed = 1; ctdp_level->level = i; ctdp_level->control_cpu = cpu; ctdp_level->pkg_id = get_physical_package_id(cpu); @@ -561,7 +653,37 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev) ret = isst_get_ctdp_control(cpu, i, ctdp_level); if (ret) - return ret; + continue; + + pkg_dev->processed = 1; + ctdp_level->processed = 1; + + if (ctdp_level->pbf_support) { + ret = isst_get_pbf_info(cpu, i, &ctdp_level->pbf_info); + if (!ret) + ctdp_level->pbf_found = 1; + } + + if (ctdp_level->fact_support) { + ret = isst_get_fact_info(cpu, i, + &ctdp_level->fact_info); + if (ret) + return ret; + } + + if (!pkg_dev->enabled) { + int freq; + + freq = get_cpufreq_base_freq(cpu); + if (freq > 0) { + ctdp_level->sse_p1 = freq / 100000; + ctdp_level->tdp_ratio = ctdp_level->sse_p1; + } + + isst_get_get_trl_from_msr(cpu, ctdp_level->trl_sse_active_cores); + isst_get_trl_bucket_info(cpu, &ctdp_level->buckets_info); + continue; + } ret = isst_get_tdp_info(cpu, i, ctdp_level); if (ret) @@ -600,22 +722,11 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev) if (ret) return ret; - if (ctdp_level->pbf_support) { - ret = isst_get_pbf_info(cpu, i, &ctdp_level->pbf_info); - if (!ret) - ctdp_level->pbf_found = 1; - } - - if (ctdp_level->fact_support) { - ret = isst_get_fact_info(cpu, i, - &ctdp_level->fact_info); - if (ret) - return ret; - } + isst_get_uncore_p0_p1_info(cpu, i, ctdp_level); + isst_get_p1_info(cpu, i, ctdp_level); + isst_get_uncore_mem_freq(cpu, i, ctdp_level); } - pkg_dev->processed = 1; - return 0; } @@ -649,6 +760,27 @@ int isst_pm_qos_config(int cpu, int enable_clos, int priority_type) unsigned int req, resp; int ret; + if (!enable_clos) { + struct isst_pkg_ctdp pkg_dev; + struct isst_pkg_ctdp_level_info ctdp_level; + + ret = isst_get_ctdp_levels(cpu, &pkg_dev); + if (ret) { + debug_printf("isst_get_ctdp_levels\n"); + return ret; + } + + ret = isst_get_ctdp_control(cpu, pkg_dev.current_level, + &ctdp_level); + if (ret) + return ret; + + if (ctdp_level.fact_enabled) { + debug_printf("Turbo-freq feature must be disabled first\n"); + return -EINVAL; + } + } + ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0, &resp); if (ret) diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 40346d534f78..040dd09d5eee 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -6,8 +6,6 @@ #include "isst.h" -#define DISP_FREQ_MULTIPLIER 100 - static void printcpulist(int str_len, char *str, int mask_size, cpu_set_t *cpu_mask) { @@ -204,6 +202,9 @@ static void _isst_pbf_display_information(int cpu, FILE *outf, int level, pbf_info->p1_low * DISP_FREQ_MULTIPLIER); format_and_print(outf, disp_level + 1, header, value); + if (is_clx_n_platform()) + return; + snprintf(header, sizeof(header), "tjunction-temperature(C)"); snprintf(value, sizeof(value), "%d", pbf_info->t_prochot); format_and_print(outf, disp_level + 1, header, value); @@ -314,7 +315,8 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, char value[256]; int i, base_level = 1; - print_package_info(cpu, outf); + if (pkg_dev->processed) + print_package_info(cpu, outf); for (i = 0; i <= pkg_dev->levels; ++i) { struct isst_pkg_ctdp_level_info *ctdp_level; @@ -334,27 +336,66 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, snprintf(value, sizeof(value), "%d", j); format_and_print(outf, base_level + 4, header, value); - snprintf(header, sizeof(header), "enable-cpu-mask"); - printcpumask(sizeof(value), value, - ctdp_level->core_cpumask_size, - ctdp_level->core_cpumask); - format_and_print(outf, base_level + 4, header, value); - - snprintf(header, sizeof(header), "enable-cpu-list"); - printcpulist(sizeof(value), value, - ctdp_level->core_cpumask_size, - ctdp_level->core_cpumask); - format_and_print(outf, base_level + 4, header, value); + if (ctdp_level->core_cpumask_size) { + snprintf(header, sizeof(header), "enable-cpu-mask"); + printcpumask(sizeof(value), value, + ctdp_level->core_cpumask_size, + ctdp_level->core_cpumask); + format_and_print(outf, base_level + 4, header, value); + + snprintf(header, sizeof(header), "enable-cpu-list"); + printcpulist(sizeof(value), value, + ctdp_level->core_cpumask_size, + ctdp_level->core_cpumask); + format_and_print(outf, base_level + 4, header, value); + } snprintf(header, sizeof(header), "thermal-design-power-ratio"); snprintf(value, sizeof(value), "%d", ctdp_level->tdp_ratio); format_and_print(outf, base_level + 4, header, value); snprintf(header, sizeof(header), "base-frequency(MHz)"); + if (!ctdp_level->sse_p1) + ctdp_level->sse_p1 = ctdp_level->tdp_ratio; snprintf(value, sizeof(value), "%d", - ctdp_level->tdp_ratio * DISP_FREQ_MULTIPLIER); + ctdp_level->sse_p1 * DISP_FREQ_MULTIPLIER); format_and_print(outf, base_level + 4, header, value); + if (ctdp_level->avx2_p1) { + snprintf(header, sizeof(header), "base-frequency-avx2(MHz)"); + snprintf(value, sizeof(value), "%d", + ctdp_level->avx2_p1 * DISP_FREQ_MULTIPLIER); + format_and_print(outf, base_level + 4, header, value); + } + + if (ctdp_level->avx512_p1) { + snprintf(header, sizeof(header), "base-frequency-avx512(MHz)"); + snprintf(value, sizeof(value), "%d", + ctdp_level->avx512_p1 * DISP_FREQ_MULTIPLIER); + format_and_print(outf, base_level + 4, header, value); + } + + if (ctdp_level->uncore_p1) { + snprintf(header, sizeof(header), "uncore-frequency-min(MHz)"); + snprintf(value, sizeof(value), "%d", + ctdp_level->uncore_p1 * DISP_FREQ_MULTIPLIER); + format_and_print(outf, base_level + 4, header, value); + } + + if (ctdp_level->uncore_p0) { + snprintf(header, sizeof(header), "uncore-frequency-max(MHz)"); + snprintf(value, sizeof(value), "%d", + ctdp_level->uncore_p0 * DISP_FREQ_MULTIPLIER); + format_and_print(outf, base_level + 4, header, value); + } + + if (ctdp_level->mem_freq) { + snprintf(header, sizeof(header), "mem-frequency(MHz)"); + snprintf(value, sizeof(value), "%d", + ctdp_level->mem_freq * DISP_FREQ_MULTIPLIER); + format_and_print(outf, base_level + 4, header, value); + } + snprintf(header, sizeof(header), "speed-select-turbo-freq"); if (ctdp_level->fact_support) { @@ -377,13 +418,26 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, snprintf(value, sizeof(value), "unsupported"); format_and_print(outf, base_level + 4, header, value); - snprintf(header, sizeof(header), "thermal-design-power(W)"); - snprintf(value, sizeof(value), "%d", ctdp_level->pkg_tdp); - format_and_print(outf, base_level + 4, header, value); + if (is_clx_n_platform()) { + if (ctdp_level->pbf_support) + _isst_pbf_display_information(cpu, outf, + tdp_level, + &ctdp_level->pbf_info, + base_level + 4); + continue; + } - snprintf(header, sizeof(header), "tjunction-max(C)"); - snprintf(value, sizeof(value), "%d", ctdp_level->t_proc_hot); - format_and_print(outf, base_level + 4, header, value); + if (ctdp_level->pkg_tdp) { + snprintf(header, sizeof(header), "thermal-design-power(W)"); + snprintf(value, sizeof(value), "%d", ctdp_level->pkg_tdp); + format_and_print(outf, base_level + 4, header, value); + } + + if (ctdp_level->t_proc_hot) { + snprintf(header, sizeof(header), "tjunction-max(C)"); + snprintf(value, sizeof(value), "%d", ctdp_level->t_proc_hot); + format_and_print(outf, base_level + 4, header, value); + } snprintf(header, sizeof(header), "turbo-ratio-limits-sse"); format_and_print(outf, base_level + 4, header, NULL); @@ -402,41 +456,41 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, DISP_FREQ_MULTIPLIER); format_and_print(outf, base_level + 6, header, value); } - snprintf(header, sizeof(header), "turbo-ratio-limits-avx"); - format_and_print(outf, base_level + 4, header, NULL); - for (j = 0; j < 8; ++j) { - snprintf(header, sizeof(header), "bucket-%d", j); - format_and_print(outf, base_level + 5, header, NULL); - snprintf(header, sizeof(header), "core-count"); - snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff); - format_and_print(outf, base_level + 6, header, value); + if (ctdp_level->trl_avx_active_cores[0]) { + snprintf(header, sizeof(header), "turbo-ratio-limits-avx2"); + format_and_print(outf, base_level + 4, header, NULL); + for (j = 0; j < 8; ++j) { + snprintf(header, sizeof(header), "bucket-%d", j); + format_and_print(outf, base_level + 5, header, NULL); - snprintf(header, sizeof(header), - "max-turbo-frequency(MHz)"); - snprintf(value, sizeof(value), "%d", - ctdp_level->trl_avx_active_cores[j] * - DISP_FREQ_MULTIPLIER); - format_and_print(outf, base_level + 6, header, value); + snprintf(header, sizeof(header), "core-count"); + snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff); + format_and_print(outf, base_level + 6, header, value); + + snprintf(header, sizeof(header), "max-turbo-frequency(MHz)"); + snprintf(value, sizeof(value), "%d", ctdp_level->trl_avx_active_cores[j] * DISP_FREQ_MULTIPLIER); + format_and_print(outf, base_level + 6, header, value); + } } - snprintf(header, sizeof(header), "turbo-ratio-limits-avx512"); - format_and_print(outf, base_level + 4, header, NULL); - for (j = 0; j < 8; ++j) { - snprintf(header, sizeof(header), "bucket-%d", j); - format_and_print(outf, base_level + 5, header, NULL); + if (ctdp_level->trl_avx_512_active_cores[0]) { + snprintf(header, sizeof(header), "turbo-ratio-limits-avx512"); + format_and_print(outf, base_level + 4, header, NULL); + for (j = 0; j < 8; ++j) { + snprintf(header, sizeof(header), "bucket-%d", j); + format_and_print(outf, base_level + 5, header, NULL); - snprintf(header, sizeof(header), "core-count"); - snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff); - format_and_print(outf, base_level + 6, header, value); + snprintf(header, sizeof(header), "core-count"); + snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff); + format_and_print(outf, base_level + 6, header, value); - snprintf(header, sizeof(header), - "max-turbo-frequency(MHz)"); - snprintf(value, sizeof(value), "%d", - ctdp_level->trl_avx_512_active_cores[j] * - DISP_FREQ_MULTIPLIER); + snprintf(header, sizeof(header), "max-turbo-frequency(MHz)"); + snprintf(value, sizeof(value), "%d", ctdp_level->trl_avx_512_active_cores[j] * DISP_FREQ_MULTIPLIER); format_and_print(outf, base_level + 6, header, value); + } } + if (ctdp_level->pbf_support) _isst_pbf_display_information(cpu, outf, i, &ctdp_level->pbf_info, @@ -509,15 +563,15 @@ void isst_clos_display_information(int cpu, FILE *outf, int clos, format_and_print(outf, 5, header, value); snprintf(header, sizeof(header), "clos-min"); - snprintf(value, sizeof(value), "%d", clos_config->clos_min); + snprintf(value, sizeof(value), "%d MHz", clos_config->clos_min * DISP_FREQ_MULTIPLIER); format_and_print(outf, 5, header, value); snprintf(header, sizeof(header), "clos-max"); - snprintf(value, sizeof(value), "%d", clos_config->clos_max); + snprintf(value, sizeof(value), "%d MHz", clos_config->clos_max * DISP_FREQ_MULTIPLIER); format_and_print(outf, 5, header, value); snprintf(header, sizeof(header), "clos-desired"); - snprintf(value, sizeof(value), "%d", clos_config->clos_desired); + snprintf(value, sizeof(value), "%d MHz", clos_config->clos_desired * DISP_FREQ_MULTIPLIER); format_and_print(outf, 5, header, value); format_and_print(outf, 1, NULL, NULL); diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index d280b27d600d..cdf0f8a6dbbf 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -69,6 +69,8 @@ #define PM_CLOS_OFFSET 0x08 #define PQR_ASSOC_OFFSET 0x20 +#define DISP_FREQ_MULTIPLIER 100 + struct isst_clos_config { int pkg_id; int die_id; @@ -161,6 +163,7 @@ struct isst_pkg_ctdp { extern int get_topo_max_cpus(void); extern int get_cpu_count(int pkg_id, int die_id); +extern int get_core_count(int pkg_id, int die_id); /* Common interfaces */ extern void debug_printf(const char *format, ...); @@ -237,4 +240,6 @@ extern void isst_display_result(int cpu, FILE *outf, char *feature, char *cmd, extern int isst_clos_get_clos_information(int cpu, int *enable, int *type); extern void isst_clos_display_clos_information(int cpu, FILE *outf, int clos_enable, int type); +extern int is_clx_n_platform(void); +extern int get_cpufreq_base_freq(int cpu); #endif diff --git a/tools/testing/selftests/bpf/test_sockmap.c b/tools/testing/selftests/bpf/test_sockmap.c index 3845144e2c91..4a851513c842 100644 --- a/tools/testing/selftests/bpf/test_sockmap.c +++ b/tools/testing/selftests/bpf/test_sockmap.c @@ -240,14 +240,14 @@ static int sockmap_init_sockets(int verbose) addr.sin_port = htons(S1_PORT); err = bind(s1, (struct sockaddr *)&addr, sizeof(addr)); if (err < 0) { - perror("bind s1 failed()\n"); + perror("bind s1 failed()"); return errno; } addr.sin_port = htons(S2_PORT); err = bind(s2, (struct sockaddr *)&addr, sizeof(addr)); if (err < 0) { - perror("bind s2 failed()\n"); + perror("bind s2 failed()"); return errno; } @@ -255,14 +255,14 @@ static int sockmap_init_sockets(int verbose) addr.sin_port = htons(S1_PORT); err = listen(s1, 32); if (err < 0) { - perror("listen s1 failed()\n"); + perror("listen s1 failed()"); return errno; } addr.sin_port = htons(S2_PORT); err = listen(s2, 32); if (err < 0) { - perror("listen s1 failed()\n"); + perror("listen s1 failed()"); return errno; } @@ -270,14 +270,14 @@ static int sockmap_init_sockets(int verbose) addr.sin_port = htons(S1_PORT); err = connect(c1, (struct sockaddr *)&addr, sizeof(addr)); if (err < 0 && errno != EINPROGRESS) { - perror("connect c1 failed()\n"); + perror("connect c1 failed()"); return errno; } addr.sin_port = htons(S2_PORT); err = connect(c2, (struct sockaddr *)&addr, sizeof(addr)); if (err < 0 && errno != EINPROGRESS) { - perror("connect c2 failed()\n"); + perror("connect c2 failed()"); return errno; } else if (err < 0) { err = 0; @@ -286,13 +286,13 @@ static int sockmap_init_sockets(int verbose) /* Accept Connecrtions */ p1 = accept(s1, NULL, NULL); if (p1 < 0) { - perror("accept s1 failed()\n"); + perror("accept s1 failed()"); return errno; } p2 = accept(s2, NULL, NULL); if (p2 < 0) { - perror("accept s1 failed()\n"); + perror("accept s1 failed()"); return errno; } @@ -332,6 +332,10 @@ static int msg_loop_sendpage(int fd, int iov_length, int cnt, int i, fp; file = fopen(".sendpage_tst.tmp", "w+"); + if (!file) { + perror("create file for sendpage"); + return 1; + } for (i = 0; i < iov_length * cnt; i++, k++) fwrite(&k, sizeof(char), 1, file); fflush(file); @@ -339,12 +343,17 @@ static int msg_loop_sendpage(int fd, int iov_length, int cnt, fclose(file); fp = open(".sendpage_tst.tmp", O_RDONLY); + if (fp < 0) { + perror("reopen file for sendpage"); + return 1; + } + clock_gettime(CLOCK_MONOTONIC, &s->start); for (i = 0; i < cnt; i++) { int sent = sendfile(fd, fp, NULL, iov_length); if (!drop && sent < 0) { - perror("send loop error:"); + perror("send loop error"); close(fp); return sent; } else if (drop && sent >= 0) { @@ -463,7 +472,7 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt, int sent = sendmsg(fd, &msg, flags); if (!drop && sent < 0) { - perror("send loop error:"); + perror("send loop error"); goto out_errno; } else if (drop && sent >= 0) { printf("send loop error expected: %i\n", sent); @@ -499,7 +508,7 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt, total_bytes -= txmsg_pop_total; err = clock_gettime(CLOCK_MONOTONIC, &s->start); if (err < 0) - perror("recv start time: "); + perror("recv start time"); while (s->bytes_recvd < total_bytes) { if (txmsg_cork) { timeout.tv_sec = 0; @@ -543,7 +552,7 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt, if (recv < 0) { if (errno != EWOULDBLOCK) { clock_gettime(CLOCK_MONOTONIC, &s->end); - perror("recv failed()\n"); + perror("recv failed()"); goto out_errno; } } @@ -557,7 +566,7 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt, errno = msg_verify_data(&msg, recv, chunk_sz); if (errno) { - perror("data verify msg failed\n"); + perror("data verify msg failed"); goto out_errno; } if (recvp) { @@ -565,7 +574,7 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt, recvp, chunk_sz); if (errno) { - perror("data verify msg_peek failed\n"); + perror("data verify msg_peek failed"); goto out_errno; } } @@ -654,7 +663,7 @@ static int sendmsg_test(struct sockmap_options *opt) err = 0; exit(err ? 1 : 0); } else if (rxpid == -1) { - perror("msg_loop_rx: "); + perror("msg_loop_rx"); return errno; } @@ -681,7 +690,7 @@ static int sendmsg_test(struct sockmap_options *opt) s.bytes_recvd, recvd_Bps, recvd_Bps/giga); exit(err ? 1 : 0); } else if (txpid == -1) { - perror("msg_loop_tx: "); + perror("msg_loop_tx"); return errno; } @@ -715,7 +724,7 @@ static int forever_ping_pong(int rate, struct sockmap_options *opt) /* Ping/Pong data from client to server */ sc = send(c1, buf, sizeof(buf), 0); if (sc < 0) { - perror("send failed()\n"); + perror("send failed()"); return sc; } @@ -748,7 +757,7 @@ static int forever_ping_pong(int rate, struct sockmap_options *opt) rc = recv(i, buf, sizeof(buf), 0); if (rc < 0) { if (errno != EWOULDBLOCK) { - perror("recv failed()\n"); + perror("recv failed()"); return rc; } } @@ -760,7 +769,7 @@ static int forever_ping_pong(int rate, struct sockmap_options *opt) sc = send(i, buf, rc, 0); if (sc < 0) { - perror("send failed()\n"); + perror("send failed()"); return sc; } } diff --git a/tools/testing/selftests/bpf/xdping.c b/tools/testing/selftests/bpf/xdping.c index d60a343b1371..842d9155d36c 100644 --- a/tools/testing/selftests/bpf/xdping.c +++ b/tools/testing/selftests/bpf/xdping.c @@ -45,7 +45,7 @@ static int get_stats(int fd, __u16 count, __u32 raddr) printf("\nXDP RTT data:\n"); if (bpf_map_lookup_elem(fd, &raddr, &pinginfo)) { - perror("bpf_map_lookup elem: "); + perror("bpf_map_lookup elem"); return 1; } diff --git a/tools/testing/selftests/net/forwarding/tc_common.sh b/tools/testing/selftests/net/forwarding/tc_common.sh index d93589bd4d1d..64f652633585 100644 --- a/tools/testing/selftests/net/forwarding/tc_common.sh +++ b/tools/testing/selftests/net/forwarding/tc_common.sh @@ -3,16 +3,42 @@ CHECK_TC="yes" +# Can be overridden by the configuration file. See lib.sh +TC_HIT_TIMEOUT=${TC_HIT_TIMEOUT:=1000} # ms + +__tc_check_packets() +{ + local id=$1 + local handle=$2 + local count=$3 + local operator=$4 + + start_time="$(date -u +%s%3N)" + while true + do + cmd_jq "tc -j -s filter show $id" \ + ".[] | select(.options.handle == $handle) | \ + select(.options.actions[0].stats.packets $operator $count)" \ + &> /dev/null + ret=$? + if [[ $ret -eq 0 ]]; then + return $ret + fi + current_time="$(date -u +%s%3N)" + diff=$(expr $current_time - $start_time) + if [ "$diff" -gt "$TC_HIT_TIMEOUT" ]; then + return 1 + fi + done +} + tc_check_packets() { local id=$1 local handle=$2 local count=$3 - cmd_jq "tc -j -s filter show $id" \ - ".[] | select(.options.handle == $handle) | \ - select(.options.actions[0].stats.packets == $count)" \ - &> /dev/null + __tc_check_packets "$id" "$handle" "$count" "==" } tc_check_packets_hitting() @@ -20,8 +46,5 @@ tc_check_packets_hitting() local id=$1 local handle=$2 - cmd_jq "tc -j -s filter show $id" \ - ".[] | select(.options.handle == $handle) | \ - select(.options.actions[0].stats.packets > 0)" \ - &> /dev/null + __tc_check_packets "$id" "$handle" 0 ">" } diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh index ab367e75f095..d697815d2785 100755 --- a/tools/testing/selftests/net/pmtu.sh +++ b/tools/testing/selftests/net/pmtu.sh @@ -1249,8 +1249,7 @@ test_list_flush_ipv4_exception() { done run_cmd ${ns_a} ping -q -M want -i 0.1 -c 2 -s 1800 "${dst2}" - # Each exception is printed as two lines - if [ "$(${ns_a} ip route list cache | wc -l)" -ne 202 ]; then + if [ "$(${ns_a} ip -oneline route list cache | wc -l)" -ne 101 ]; then err " can't list cached exceptions" fail=1 fi @@ -1300,7 +1299,7 @@ test_list_flush_ipv6_exception() { run_cmd ${ns_a} ping -q -M want -i 0.1 -w 1 -s 1800 "${dst_prefix1}${i}" done run_cmd ${ns_a} ping -q -M want -i 0.1 -w 1 -s 1800 "${dst2}" - if [ "$(${ns_a} ip -6 route list cache | wc -l)" -ne 101 ]; then + if [ "$(${ns_a} ip -oneline -6 route list cache | wc -l)" -ne 101 ]; then err " can't list cached exceptions" fail=1 fi diff --git a/tools/testing/selftests/net/tls.c b/tools/testing/selftests/net/tls.c index 1c8f194d6556..46abcae47dee 100644 --- a/tools/testing/selftests/net/tls.c +++ b/tools/testing/selftests/net/tls.c @@ -268,6 +268,38 @@ TEST_F(tls, sendmsg_single) EXPECT_EQ(memcmp(buf, test_str, send_len), 0); } +#define MAX_FRAGS 64 +#define SEND_LEN 13 +TEST_F(tls, sendmsg_fragmented) +{ + char const *test_str = "test_sendmsg"; + char buf[SEND_LEN * MAX_FRAGS]; + struct iovec vec[MAX_FRAGS]; + struct msghdr msg; + int i, frags; + + for (frags = 1; frags <= MAX_FRAGS; frags++) { + for (i = 0; i < frags; i++) { + vec[i].iov_base = (char *)test_str; + vec[i].iov_len = SEND_LEN; + } + + memset(&msg, 0, sizeof(struct msghdr)); + msg.msg_iov = vec; + msg.msg_iovlen = frags; + + EXPECT_EQ(sendmsg(self->fd, &msg, 0), SEND_LEN * frags); + EXPECT_EQ(recv(self->cfd, buf, SEND_LEN * frags, MSG_WAITALL), + SEND_LEN * frags); + + for (i = 0; i < frags; i++) + EXPECT_EQ(memcmp(buf + SEND_LEN * i, + test_str, SEND_LEN), 0); + } +} +#undef MAX_FRAGS +#undef SEND_LEN + TEST_F(tls, sendmsg_large) { void *mem = malloc(16384); @@ -694,6 +726,34 @@ TEST_F(tls, recv_lowat) EXPECT_EQ(memcmp(send_mem, recv_mem + 10, 5), 0); } +TEST_F(tls, recv_rcvbuf) +{ + char send_mem[4096]; + char recv_mem[4096]; + int rcv_buf = 1024; + + memset(send_mem, 0x1c, sizeof(send_mem)); + + EXPECT_EQ(setsockopt(self->cfd, SOL_SOCKET, SO_RCVBUF, + &rcv_buf, sizeof(rcv_buf)), 0); + + EXPECT_EQ(send(self->fd, send_mem, 512, 0), 512); + memset(recv_mem, 0, sizeof(recv_mem)); + EXPECT_EQ(recv(self->cfd, recv_mem, sizeof(recv_mem), 0), 512); + EXPECT_EQ(memcmp(send_mem, recv_mem, 512), 0); + + if (self->notls) + return; + + EXPECT_EQ(send(self->fd, send_mem, 4096, 0), 4096); + memset(recv_mem, 0, sizeof(recv_mem)); + EXPECT_EQ(recv(self->cfd, recv_mem, sizeof(recv_mem), 0), -1); + EXPECT_EQ(errno, EMSGSIZE); + + EXPECT_EQ(recv(self->cfd, recv_mem, sizeof(recv_mem), 0), -1); + EXPECT_EQ(errno, EMSGSIZE); +} + TEST_F(tls, bidir) { char const *test_str = "test_read"; diff --git a/tools/testing/selftests/powerpc/include/utils.h b/tools/testing/selftests/powerpc/include/utils.h index 0e2b2e6284ac..e089a0c30d9a 100644 --- a/tools/testing/selftests/powerpc/include/utils.h +++ b/tools/testing/selftests/powerpc/include/utils.h @@ -34,6 +34,7 @@ int pick_online_cpu(void); int read_debugfs_file(char *debugfs_file, int *result); int write_debugfs_file(char *debugfs_file, int result); +int read_sysfs_file(char *debugfs_file, char *result, size_t result_size); void set_dscr(unsigned long val); int perf_event_open_counter(unsigned int type, unsigned long config, int group_fd); diff --git a/tools/testing/selftests/powerpc/pmu/ebb/Makefile b/tools/testing/selftests/powerpc/pmu/ebb/Makefile index 23f4caf48ffc..417306353e07 100644 --- a/tools/testing/selftests/powerpc/pmu/ebb/Makefile +++ b/tools/testing/selftests/powerpc/pmu/ebb/Makefile @@ -1,4 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 +include ../../../../../../scripts/Kbuild.include + noarg: $(MAKE) -C ../../ @@ -6,7 +8,10 @@ noarg: CFLAGS += -m64 # Toolchains may build PIE by default which breaks the assembly -LDFLAGS += -no-pie +no-pie-option := $(call try-run, echo 'int main() { return 0; }' | \ + $(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -no-pie -x c - -o "$$TMP", -no-pie) + +LDFLAGS += $(no-pie-option) TEST_GEN_PROGS := reg_access_test event_attributes_test cycles_test \ cycles_with_freeze_test pmc56_overflow_test \ diff --git a/tools/testing/selftests/powerpc/ptrace/perf-hwbreak.c b/tools/testing/selftests/powerpc/ptrace/perf-hwbreak.c index 200337daec42..c1f324afdbf3 100644 --- a/tools/testing/selftests/powerpc/ptrace/perf-hwbreak.c +++ b/tools/testing/selftests/powerpc/ptrace/perf-hwbreak.c @@ -148,6 +148,121 @@ static int runtestsingle(int readwriteflag, int exclude_user, int arraytest) return 0; } +static int runtest_dar_outside(void) +{ + void *target; + volatile __u16 temp16; + volatile __u64 temp64; + struct perf_event_attr attr; + int break_fd; + unsigned long long breaks; + int fail = 0; + size_t res; + + target = malloc(8); + if (!target) { + perror("malloc failed"); + exit(EXIT_FAILURE); + } + + /* setup counters */ + memset(&attr, 0, sizeof(attr)); + attr.disabled = 1; + attr.type = PERF_TYPE_BREAKPOINT; + attr.exclude_kernel = 1; + attr.exclude_hv = 1; + attr.exclude_guest = 1; + attr.bp_type = HW_BREAKPOINT_RW; + /* watch middle half of target array */ + attr.bp_addr = (__u64)(target + 2); + attr.bp_len = 4; + break_fd = sys_perf_event_open(&attr, 0, -1, -1, 0); + if (break_fd < 0) { + free(target); + perror("sys_perf_event_open"); + exit(EXIT_FAILURE); + } + + /* Shouldn't hit. */ + ioctl(break_fd, PERF_EVENT_IOC_RESET); + ioctl(break_fd, PERF_EVENT_IOC_ENABLE); + temp16 = *((__u16 *)target); + *((__u16 *)target) = temp16; + ioctl(break_fd, PERF_EVENT_IOC_DISABLE); + res = read(break_fd, &breaks, sizeof(unsigned long long)); + assert(res == sizeof(unsigned long long)); + if (breaks == 0) { + printf("TESTED: No overlap\n"); + } else { + printf("FAILED: No overlap: %lld != 0\n", breaks); + fail = 1; + } + + /* Hit */ + ioctl(break_fd, PERF_EVENT_IOC_RESET); + ioctl(break_fd, PERF_EVENT_IOC_ENABLE); + temp16 = *((__u16 *)(target + 1)); + *((__u16 *)(target + 1)) = temp16; + ioctl(break_fd, PERF_EVENT_IOC_DISABLE); + res = read(break_fd, &breaks, sizeof(unsigned long long)); + assert(res == sizeof(unsigned long long)); + if (breaks == 2) { + printf("TESTED: Partial overlap\n"); + } else { + printf("FAILED: Partial overlap: %lld != 2\n", breaks); + fail = 1; + } + + /* Hit */ + ioctl(break_fd, PERF_EVENT_IOC_RESET); + ioctl(break_fd, PERF_EVENT_IOC_ENABLE); + temp16 = *((__u16 *)(target + 5)); + *((__u16 *)(target + 5)) = temp16; + ioctl(break_fd, PERF_EVENT_IOC_DISABLE); + res = read(break_fd, &breaks, sizeof(unsigned long long)); + assert(res == sizeof(unsigned long long)); + if (breaks == 2) { + printf("TESTED: Partial overlap\n"); + } else { + printf("FAILED: Partial overlap: %lld != 2\n", breaks); + fail = 1; + } + + /* Shouldn't Hit */ + ioctl(break_fd, PERF_EVENT_IOC_RESET); + ioctl(break_fd, PERF_EVENT_IOC_ENABLE); + temp16 = *((__u16 *)(target + 6)); + *((__u16 *)(target + 6)) = temp16; + ioctl(break_fd, PERF_EVENT_IOC_DISABLE); + res = read(break_fd, &breaks, sizeof(unsigned long long)); + assert(res == sizeof(unsigned long long)); + if (breaks == 0) { + printf("TESTED: No overlap\n"); + } else { + printf("FAILED: No overlap: %lld != 0\n", breaks); + fail = 1; + } + + /* Hit */ + ioctl(break_fd, PERF_EVENT_IOC_RESET); + ioctl(break_fd, PERF_EVENT_IOC_ENABLE); + temp64 = *((__u64 *)target); + *((__u64 *)target) = temp64; + ioctl(break_fd, PERF_EVENT_IOC_DISABLE); + res = read(break_fd, &breaks, sizeof(unsigned long long)); + assert(res == sizeof(unsigned long long)); + if (breaks == 2) { + printf("TESTED: Full overlap\n"); + } else { + printf("FAILED: Full overlap: %lld != 2\n", breaks); + fail = 1; + } + + free(target); + close(break_fd); + return fail; +} + static int runtest(void) { int rwflag; @@ -172,7 +287,9 @@ static int runtest(void) return ret; } } - return 0; + + ret = runtest_dar_outside(); + return ret; } diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c b/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c index 3066d310f32b..7deedbc16b0b 100644 --- a/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c +++ b/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c @@ -22,321 +22,486 @@ #include <sys/wait.h> #include "ptrace.h" -/* Breakpoint access modes */ -enum { - BP_X = 1, - BP_RW = 2, - BP_W = 4, -}; - -static pid_t child_pid; -static struct ppc_debug_info dbginfo; - -static void get_dbginfo(void) -{ - int ret; +#define SPRN_PVR 0x11F +#define PVR_8xx 0x00500000 - ret = ptrace(PPC_PTRACE_GETHWDBGINFO, child_pid, NULL, &dbginfo); - if (ret) { - perror("Can't get breakpoint info\n"); - exit(-1); - } -} +bool is_8xx; -static bool hwbreak_present(void) -{ - return (dbginfo.num_data_bps != 0); -} +/* + * Use volatile on all global var so that compiler doesn't + * optimise their load/stores. Otherwise selftest can fail. + */ +static volatile __u64 glvar; -static bool dawr_present(void) -{ - return !!(dbginfo.features & PPC_DEBUG_FEATURE_DATA_BP_DAWR); -} +#define DAWR_MAX_LEN 512 +static volatile __u8 big_var[DAWR_MAX_LEN] __attribute__((aligned(512))); -static void set_breakpoint_addr(void *addr) -{ - int ret; +#define A_LEN 6 +#define B_LEN 6 +struct gstruct { + __u8 a[A_LEN]; /* double word aligned */ + __u8 b[B_LEN]; /* double word unaligned */ +}; +static volatile struct gstruct gstruct __attribute__((aligned(512))); - ret = ptrace(PTRACE_SET_DEBUGREG, child_pid, 0, addr); - if (ret) { - perror("Can't set breakpoint addr\n"); - exit(-1); - } -} -static int set_hwbreakpoint_addr(void *addr, int range) +static void get_dbginfo(pid_t child_pid, struct ppc_debug_info *dbginfo) { - int ret; - - struct ppc_hw_breakpoint info; - - info.version = 1; - info.trigger_type = PPC_BREAKPOINT_TRIGGER_RW; - info.addr_mode = PPC_BREAKPOINT_MODE_EXACT; - if (range > 0) - info.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE; - info.condition_mode = PPC_BREAKPOINT_CONDITION_NONE; - info.addr = (__u64)addr; - info.addr2 = (__u64)addr + range; - info.condition_value = 0; - - ret = ptrace(PPC_PTRACE_SETHWDEBUG, child_pid, 0, &info); - if (ret < 0) { - perror("Can't set breakpoint\n"); + if (ptrace(PPC_PTRACE_GETHWDBGINFO, child_pid, NULL, dbginfo)) { + perror("Can't get breakpoint info"); exit(-1); } - return ret; } -static int del_hwbreakpoint_addr(int watchpoint_handle) +static bool dawr_present(struct ppc_debug_info *dbginfo) { - int ret; - - ret = ptrace(PPC_PTRACE_DELHWDEBUG, child_pid, 0, watchpoint_handle); - if (ret < 0) { - perror("Can't delete hw breakpoint\n"); - exit(-1); - } - return ret; + return !!(dbginfo->features & PPC_DEBUG_FEATURE_DATA_BP_DAWR); } -#define DAWR_LENGTH_MAX 512 - -/* Dummy variables to test read/write accesses */ -static unsigned long long - dummy_array[DAWR_LENGTH_MAX / sizeof(unsigned long long)] - __attribute__((aligned(512))); -static unsigned long long *dummy_var = dummy_array; - static void write_var(int len) { - long long *plval; - char *pcval; - short *psval; - int *pival; + __u8 *pcvar; + __u16 *psvar; + __u32 *pivar; + __u64 *plvar; switch (len) { case 1: - pcval = (char *)dummy_var; - *pcval = 0xff; + pcvar = (__u8 *)&glvar; + *pcvar = 0xff; break; case 2: - psval = (short *)dummy_var; - *psval = 0xffff; + psvar = (__u16 *)&glvar; + *psvar = 0xffff; break; case 4: - pival = (int *)dummy_var; - *pival = 0xffffffff; + pivar = (__u32 *)&glvar; + *pivar = 0xffffffff; break; case 8: - plval = (long long *)dummy_var; - *plval = 0xffffffffffffffffLL; + plvar = (__u64 *)&glvar; + *plvar = 0xffffffffffffffffLL; break; } } static void read_var(int len) { - char cval __attribute__((unused)); - short sval __attribute__((unused)); - int ival __attribute__((unused)); - long long lval __attribute__((unused)); + __u8 cvar __attribute__((unused)); + __u16 svar __attribute__((unused)); + __u32 ivar __attribute__((unused)); + __u64 lvar __attribute__((unused)); switch (len) { case 1: - cval = *(char *)dummy_var; + cvar = (__u8)glvar; break; case 2: - sval = *(short *)dummy_var; + svar = (__u16)glvar; break; case 4: - ival = *(int *)dummy_var; + ivar = (__u32)glvar; break; case 8: - lval = *(long long *)dummy_var; + lvar = (__u64)glvar; break; } } -/* - * Do the r/w accesses to trigger the breakpoints. And run - * the usual traps. - */ -static void trigger_tests(void) +static void test_workload(void) { - int len, ret; + __u8 cvar __attribute__((unused)); + __u32 ivar __attribute__((unused)); + int len = 0; - ret = ptrace(PTRACE_TRACEME, 0, NULL, 0); - if (ret) { - perror("Can't be traced?\n"); - return; + if (ptrace(PTRACE_TRACEME, 0, NULL, 0)) { + perror("Child can't be traced?"); + exit(-1); } /* Wake up father so that it sets up the first test */ kill(getpid(), SIGUSR1); - /* Test write watchpoints */ - for (len = 1; len <= sizeof(long); len <<= 1) + /* PTRACE_SET_DEBUGREG, WO test */ + for (len = 1; len <= sizeof(glvar); len <<= 1) write_var(len); - /* Test read/write watchpoints (on read accesses) */ - for (len = 1; len <= sizeof(long); len <<= 1) + /* PTRACE_SET_DEBUGREG, RO test */ + for (len = 1; len <= sizeof(glvar); len <<= 1) read_var(len); - /* Test when breakpoint is unset */ - - /* Test write watchpoints */ - for (len = 1; len <= sizeof(long); len <<= 1) - write_var(len); + /* PTRACE_SET_DEBUGREG, RW test */ + for (len = 1; len <= sizeof(glvar); len <<= 1) { + if (rand() % 2) + read_var(len); + else + write_var(len); + } - /* Test read/write watchpoints (on read accesses) */ - for (len = 1; len <= sizeof(long); len <<= 1) - read_var(len); + /* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, WO test */ + write_var(1); + + /* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, RO test */ + read_var(1); + + /* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, RW test */ + if (rand() % 2) + write_var(1); + else + read_var(1); + + /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, WO test */ + gstruct.a[rand() % A_LEN] = 'a'; + + /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, RO test */ + cvar = gstruct.a[rand() % A_LEN]; + + /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, RW test */ + if (rand() % 2) + gstruct.a[rand() % A_LEN] = 'a'; + else + cvar = gstruct.a[rand() % A_LEN]; + + /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, WO test */ + gstruct.b[rand() % B_LEN] = 'b'; + + /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, RO test */ + cvar = gstruct.b[rand() % B_LEN]; + + /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, RW test */ + if (rand() % 2) + gstruct.b[rand() % B_LEN] = 'b'; + else + cvar = gstruct.b[rand() % B_LEN]; + + /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, DAR OUTSIDE, RW test */ + if (rand() % 2) + *((int *)(gstruct.a + 4)) = 10; + else + ivar = *((int *)(gstruct.a + 4)); + + /* PPC_PTRACE_SETHWDEBUG. DAWR_MAX_LEN. RW test */ + if (rand() % 2) + big_var[rand() % DAWR_MAX_LEN] = 'a'; + else + cvar = big_var[rand() % DAWR_MAX_LEN]; } -static void check_success(const char *msg) +static void check_success(pid_t child_pid, const char *name, const char *type, + unsigned long saddr, int len) { - const char *msg2; int status; + siginfo_t siginfo; + unsigned long eaddr = (saddr + len - 1) | 0x7; + + saddr &= ~0x7; /* Wait for the child to SIGTRAP */ wait(&status); - msg2 = "Failed"; + ptrace(PTRACE_GETSIGINFO, child_pid, NULL, &siginfo); - if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { - msg2 = "Child process hit the breakpoint"; + if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGTRAP || + (unsigned long)siginfo.si_addr < saddr || + (unsigned long)siginfo.si_addr > eaddr) { + printf("%s, %s, len: %d: Fail\n", name, type, len); + exit(-1); } - printf("%s Result: [%s]\n", msg, msg2); + printf("%s, %s, len: %d: Ok\n", name, type, len); + + if (!is_8xx) { + /* + * For ptrace registered watchpoint, signal is generated + * before executing load/store. Singlestep the instruction + * and then continue the test. + */ + ptrace(PTRACE_SINGLESTEP, child_pid, NULL, 0); + wait(NULL); + } } -static void launch_watchpoints(char *buf, int mode, int len, - struct ppc_debug_info *dbginfo, bool dawr) +static void ptrace_set_debugreg(pid_t child_pid, unsigned long wp_addr) { - const char *mode_str; - unsigned long data = (unsigned long)(dummy_var); - int wh, range; - - data &= ~0x7UL; - - if (mode == BP_W) { - data |= (1UL << 1); - mode_str = "write"; - } else { - data |= (1UL << 0); - data |= (1UL << 1); - mode_str = "read"; + if (ptrace(PTRACE_SET_DEBUGREG, child_pid, 0, wp_addr)) { + perror("PTRACE_SET_DEBUGREG failed"); + exit(-1); } +} - /* Set DABR_TRANSLATION bit */ - data |= (1UL << 2); - - /* use PTRACE_SET_DEBUGREG breakpoints */ - set_breakpoint_addr((void *)data); - ptrace(PTRACE_CONT, child_pid, NULL, 0); - sprintf(buf, "Test %s watchpoint with len: %d ", mode_str, len); - check_success(buf); - /* Unregister hw brkpoint */ - set_breakpoint_addr(NULL); +static int ptrace_sethwdebug(pid_t child_pid, struct ppc_hw_breakpoint *info) +{ + int wh = ptrace(PPC_PTRACE_SETHWDEBUG, child_pid, 0, info); - data = (data & ~7); /* remove dabr control bits */ + if (wh <= 0) { + perror("PPC_PTRACE_SETHWDEBUG failed"); + exit(-1); + } + return wh; +} - /* use PPC_PTRACE_SETHWDEBUG breakpoint */ - if (!(dbginfo->features & PPC_DEBUG_FEATURE_DATA_BP_RANGE)) - return; /* not supported */ - wh = set_hwbreakpoint_addr((void *)data, 0); - ptrace(PTRACE_CONT, child_pid, NULL, 0); - sprintf(buf, "Test %s watchpoint with len: %d ", mode_str, len); - check_success(buf); - /* Unregister hw brkpoint */ - del_hwbreakpoint_addr(wh); - - /* try a wider range */ - range = 8; - if (dawr) - range = 512 - ((int)data & (DAWR_LENGTH_MAX - 1)); - wh = set_hwbreakpoint_addr((void *)data, range); - ptrace(PTRACE_CONT, child_pid, NULL, 0); - sprintf(buf, "Test %s watchpoint with len: %d ", mode_str, len); - check_success(buf); - /* Unregister hw brkpoint */ - del_hwbreakpoint_addr(wh); +static void ptrace_delhwdebug(pid_t child_pid, int wh) +{ + if (ptrace(PPC_PTRACE_DELHWDEBUG, child_pid, 0, wh) < 0) { + perror("PPC_PTRACE_DELHWDEBUG failed"); + exit(-1); + } } -/* Set the breakpoints and check the child successfully trigger them */ -static int launch_tests(bool dawr) +#define DABR_READ_SHIFT 0 +#define DABR_WRITE_SHIFT 1 +#define DABR_TRANSLATION_SHIFT 2 + +static int test_set_debugreg(pid_t child_pid) { - char buf[1024]; - int len, i, status; + unsigned long wp_addr = (unsigned long)&glvar; + char *name = "PTRACE_SET_DEBUGREG"; + int len; + + /* PTRACE_SET_DEBUGREG, WO test*/ + wp_addr &= ~0x7UL; + wp_addr |= (1UL << DABR_WRITE_SHIFT); + wp_addr |= (1UL << DABR_TRANSLATION_SHIFT); + for (len = 1; len <= sizeof(glvar); len <<= 1) { + ptrace_set_debugreg(child_pid, wp_addr); + ptrace(PTRACE_CONT, child_pid, NULL, 0); + check_success(child_pid, name, "WO", wp_addr, len); + } - struct ppc_debug_info dbginfo; + /* PTRACE_SET_DEBUGREG, RO test */ + wp_addr &= ~0x7UL; + wp_addr |= (1UL << DABR_READ_SHIFT); + wp_addr |= (1UL << DABR_TRANSLATION_SHIFT); + for (len = 1; len <= sizeof(glvar); len <<= 1) { + ptrace_set_debugreg(child_pid, wp_addr); + ptrace(PTRACE_CONT, child_pid, NULL, 0); + check_success(child_pid, name, "RO", wp_addr, len); + } - i = ptrace(PPC_PTRACE_GETHWDBGINFO, child_pid, NULL, &dbginfo); - if (i) { - perror("Can't set breakpoint info\n"); - exit(-1); + /* PTRACE_SET_DEBUGREG, RW test */ + wp_addr &= ~0x7UL; + wp_addr |= (1Ul << DABR_READ_SHIFT); + wp_addr |= (1UL << DABR_WRITE_SHIFT); + wp_addr |= (1UL << DABR_TRANSLATION_SHIFT); + for (len = 1; len <= sizeof(glvar); len <<= 1) { + ptrace_set_debugreg(child_pid, wp_addr); + ptrace(PTRACE_CONT, child_pid, NULL, 0); + check_success(child_pid, name, "RW", wp_addr, len); } - if (!(dbginfo.features & PPC_DEBUG_FEATURE_DATA_BP_RANGE)) - printf("WARNING: Kernel doesn't support PPC_PTRACE_SETHWDEBUG\n"); - /* Write watchpoint */ - for (len = 1; len <= sizeof(long); len <<= 1) - launch_watchpoints(buf, BP_W, len, &dbginfo, dawr); + ptrace_set_debugreg(child_pid, 0); + return 0; +} - /* Read-Write watchpoint */ - for (len = 1; len <= sizeof(long); len <<= 1) - launch_watchpoints(buf, BP_RW, len, &dbginfo, dawr); +static void get_ppc_hw_breakpoint(struct ppc_hw_breakpoint *info, int type, + unsigned long addr, int len) +{ + info->version = 1; + info->trigger_type = type; + info->condition_mode = PPC_BREAKPOINT_CONDITION_NONE; + info->addr = (__u64)addr; + info->addr2 = (__u64)addr + len; + info->condition_value = 0; + if (!len) + info->addr_mode = PPC_BREAKPOINT_MODE_EXACT; + else + info->addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE; +} +static void test_sethwdebug_exact(pid_t child_pid) +{ + struct ppc_hw_breakpoint info; + unsigned long wp_addr = (unsigned long)&glvar; + char *name = "PPC_PTRACE_SETHWDEBUG, MODE_EXACT"; + int len = 1; /* hardcoded in kernel */ + int wh; + + /* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, WO test */ + get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_WRITE, wp_addr, 0); + wh = ptrace_sethwdebug(child_pid, &info); ptrace(PTRACE_CONT, child_pid, NULL, 0); + check_success(child_pid, name, "WO", wp_addr, len); + ptrace_delhwdebug(child_pid, wh); - /* - * Now we have unregistered the breakpoint, access by child - * should not cause SIGTRAP. - */ + /* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, RO test */ + get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_READ, wp_addr, 0); + wh = ptrace_sethwdebug(child_pid, &info); + ptrace(PTRACE_CONT, child_pid, NULL, 0); + check_success(child_pid, name, "RO", wp_addr, len); + ptrace_delhwdebug(child_pid, wh); - wait(&status); + /* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, RW test */ + get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_RW, wp_addr, 0); + wh = ptrace_sethwdebug(child_pid, &info); + ptrace(PTRACE_CONT, child_pid, NULL, 0); + check_success(child_pid, name, "RW", wp_addr, len); + ptrace_delhwdebug(child_pid, wh); +} - if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { - printf("FAIL: Child process hit the breakpoint, which is not expected\n"); - ptrace(PTRACE_CONT, child_pid, NULL, 0); - return TEST_FAIL; - } +static void test_sethwdebug_range_aligned(pid_t child_pid) +{ + struct ppc_hw_breakpoint info; + unsigned long wp_addr; + char *name = "PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED"; + int len; + int wh; + + /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, WO test */ + wp_addr = (unsigned long)&gstruct.a; + len = A_LEN; + get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_WRITE, wp_addr, len); + wh = ptrace_sethwdebug(child_pid, &info); + ptrace(PTRACE_CONT, child_pid, NULL, 0); + check_success(child_pid, name, "WO", wp_addr, len); + ptrace_delhwdebug(child_pid, wh); + + /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, RO test */ + wp_addr = (unsigned long)&gstruct.a; + len = A_LEN; + get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_READ, wp_addr, len); + wh = ptrace_sethwdebug(child_pid, &info); + ptrace(PTRACE_CONT, child_pid, NULL, 0); + check_success(child_pid, name, "RO", wp_addr, len); + ptrace_delhwdebug(child_pid, wh); + + /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, RW test */ + wp_addr = (unsigned long)&gstruct.a; + len = A_LEN; + get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_RW, wp_addr, len); + wh = ptrace_sethwdebug(child_pid, &info); + ptrace(PTRACE_CONT, child_pid, NULL, 0); + check_success(child_pid, name, "RW", wp_addr, len); + ptrace_delhwdebug(child_pid, wh); +} - if (WIFEXITED(status)) - printf("Child exited normally\n"); +static void test_sethwdebug_range_unaligned(pid_t child_pid) +{ + struct ppc_hw_breakpoint info; + unsigned long wp_addr; + char *name = "PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED"; + int len; + int wh; + + /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, WO test */ + wp_addr = (unsigned long)&gstruct.b; + len = B_LEN; + get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_WRITE, wp_addr, len); + wh = ptrace_sethwdebug(child_pid, &info); + ptrace(PTRACE_CONT, child_pid, NULL, 0); + check_success(child_pid, name, "WO", wp_addr, len); + ptrace_delhwdebug(child_pid, wh); + + /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, RO test */ + wp_addr = (unsigned long)&gstruct.b; + len = B_LEN; + get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_READ, wp_addr, len); + wh = ptrace_sethwdebug(child_pid, &info); + ptrace(PTRACE_CONT, child_pid, NULL, 0); + check_success(child_pid, name, "RO", wp_addr, len); + ptrace_delhwdebug(child_pid, wh); + + /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, RW test */ + wp_addr = (unsigned long)&gstruct.b; + len = B_LEN; + get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_RW, wp_addr, len); + wh = ptrace_sethwdebug(child_pid, &info); + ptrace(PTRACE_CONT, child_pid, NULL, 0); + check_success(child_pid, name, "RW", wp_addr, len); + ptrace_delhwdebug(child_pid, wh); - return TEST_PASS; +} + +static void test_sethwdebug_range_unaligned_dar(pid_t child_pid) +{ + struct ppc_hw_breakpoint info; + unsigned long wp_addr; + char *name = "PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, DAR OUTSIDE"; + int len; + int wh; + + /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, DAR OUTSIDE, RW test */ + wp_addr = (unsigned long)&gstruct.b; + len = B_LEN; + get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_WRITE, wp_addr, len); + wh = ptrace_sethwdebug(child_pid, &info); + ptrace(PTRACE_CONT, child_pid, NULL, 0); + check_success(child_pid, name, "RW", wp_addr, len); + ptrace_delhwdebug(child_pid, wh); +} + +static void test_sethwdebug_dawr_max_range(pid_t child_pid) +{ + struct ppc_hw_breakpoint info; + unsigned long wp_addr; + char *name = "PPC_PTRACE_SETHWDEBUG, DAWR_MAX_LEN"; + int len; + int wh; + + /* PPC_PTRACE_SETHWDEBUG, DAWR_MAX_LEN, RW test */ + wp_addr = (unsigned long)big_var; + len = DAWR_MAX_LEN; + get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_RW, wp_addr, len); + wh = ptrace_sethwdebug(child_pid, &info); + ptrace(PTRACE_CONT, child_pid, NULL, 0); + check_success(child_pid, name, "RW", wp_addr, len); + ptrace_delhwdebug(child_pid, wh); +} + +/* Set the breakpoints and check the child successfully trigger them */ +static void +run_tests(pid_t child_pid, struct ppc_debug_info *dbginfo, bool dawr) +{ + test_set_debugreg(child_pid); + if (dbginfo->features & PPC_DEBUG_FEATURE_DATA_BP_RANGE) { + test_sethwdebug_exact(child_pid); + + if (!is_8xx) + test_sethwdebug_range_aligned(child_pid); + if (dawr && !is_8xx) { + test_sethwdebug_range_unaligned(child_pid); + test_sethwdebug_range_unaligned_dar(child_pid); + test_sethwdebug_dawr_max_range(child_pid); + } + } } static int ptrace_hwbreak(void) { - pid_t pid; - int ret; + pid_t child_pid; + struct ppc_debug_info dbginfo; bool dawr; - pid = fork(); - if (!pid) { - trigger_tests(); + child_pid = fork(); + if (!child_pid) { + test_workload(); return 0; } wait(NULL); - child_pid = pid; + get_dbginfo(child_pid, &dbginfo); + SKIP_IF(dbginfo.num_data_bps == 0); - get_dbginfo(); - SKIP_IF(!hwbreak_present()); - dawr = dawr_present(); - - ret = launch_tests(dawr); + dawr = dawr_present(&dbginfo); + run_tests(child_pid, &dbginfo, dawr); + /* Let the child exit first. */ + ptrace(PTRACE_CONT, child_pid, NULL, 0); wait(NULL); - return ret; + /* + * Testcases exits immediately with -1 on any failure. If + * it has reached here, it means all tests were successful. + */ + return TEST_PASS; } int main(int argc, char **argv, char **envp) { + int pvr = 0; + asm __volatile__ ("mfspr %0,%1" : "=r"(pvr) : "i"(SPRN_PVR)); + if (pvr == PVR_8xx) + is_8xx = true; + return test_harness(ptrace_hwbreak, "ptrace-hwbreak"); } diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-tar.c b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-tar.c index 25e23e73c72e..2ecfa1158e2b 100644 --- a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-tar.c +++ b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-tar.c @@ -73,7 +73,7 @@ trans: [sprn_texasr]"i"(SPRN_TEXASR), [tar_1]"i"(TAR_1), [dscr_1]"i"(DSCR_1), [tar_2]"i"(TAR_2), [dscr_2]"i"(DSCR_2), [tar_3]"i"(TAR_3), [dscr_3]"i"(DSCR_3) - : "memory", "r0", "r1", "r3", "r4", "r5", "r6" + : "memory", "r0", "r3", "r4", "r5", "r6", "lr" ); /* TM failed, analyse */ diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-vsx.c b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-vsx.c index f603fe5a445b..6f7fb51f0809 100644 --- a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-vsx.c +++ b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-vsx.c @@ -74,8 +74,8 @@ trans: "3: ;" : [res] "=r" (result), [texasr] "=r" (texasr) : [sprn_texasr] "i" (SPRN_TEXASR) - : "memory", "r0", "r1", "r3", "r4", - "r7", "r8", "r9", "r10", "r11" + : "memory", "r0", "r3", "r4", + "r7", "r8", "r9", "r10", "r11", "lr" ); if (result) { diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-tar.c b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-tar.c index e0d37f07bdeb..46ef378a15ec 100644 --- a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-tar.c +++ b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-tar.c @@ -62,7 +62,7 @@ trans: [sprn_ppr]"i"(SPRN_PPR), [sprn_texasr]"i"(SPRN_TEXASR), [tar_1]"i"(TAR_1), [dscr_1]"i"(DSCR_1), [tar_2]"i"(TAR_2), [dscr_2]"i"(DSCR_2), [cptr1] "b" (&cptr[1]) - : "memory", "r0", "r1", "r3", "r4", "r5", "r6" + : "memory", "r0", "r3", "r4", "r5", "r6" ); /* TM failed, analyse */ diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-vsx.c b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-vsx.c index 8027457b97b7..70ca01234f79 100644 --- a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-vsx.c +++ b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-vsx.c @@ -62,8 +62,8 @@ trans: "3: ;" : [res] "=r" (result), [texasr] "=r" (texasr) : [sprn_texasr] "i" (SPRN_TEXASR), [cptr1] "b" (&cptr[1]) - : "memory", "r0", "r1", "r3", "r4", - "r7", "r8", "r9", "r10", "r11" + : "memory", "r0", "r3", "r4", + "r7", "r8", "r9", "r10", "r11", "lr" ); if (result) { diff --git a/tools/testing/selftests/powerpc/security/Makefile b/tools/testing/selftests/powerpc/security/Makefile index 85861c46b445..eadbbff50be6 100644 --- a/tools/testing/selftests/powerpc/security/Makefile +++ b/tools/testing/selftests/powerpc/security/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0+ -TEST_GEN_PROGS := rfi_flush +TEST_GEN_PROGS := rfi_flush spectre_v2 top_srcdir = ../../../../.. CFLAGS += -I../../../../../usr/include @@ -8,3 +8,6 @@ CFLAGS += -I../../../../../usr/include include ../../lib.mk $(TEST_GEN_PROGS): ../harness.c ../utils.c + +$(OUTPUT)/spectre_v2: CFLAGS += -m64 +$(OUTPUT)/spectre_v2: ../pmu/event.c branch_loops.S diff --git a/tools/testing/selftests/powerpc/security/branch_loops.S b/tools/testing/selftests/powerpc/security/branch_loops.S new file mode 100644 index 000000000000..22e9204e3421 --- /dev/null +++ b/tools/testing/selftests/powerpc/security/branch_loops.S @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* + * Copyright 2019, Michael Ellerman, IBM Corp. + */ + +#include <ppc-asm.h> + + .data + +jump_table: + .long 0x0 + .long (.Lstate_1 - .Lstate_0) + .long (.Lstate_2 - .Lstate_0) + .long (.Lstate_3 - .Lstate_0) + .long (.Lstate_4 - .Lstate_0) + .long (.Lstate_5 - .Lstate_0) + .long (.Lstate_6 - .Lstate_0) + .long (.Lstate_7 - .Lstate_0) + + .text + +#define ITER_SHIFT 31 + +.macro state number + .balign 32 +.Lstate_\number: + .if \number==7 + li r3, 0 + .else + li r3, \number+1 + .endif + b .Lloop +.endm + +FUNC_START(pattern_cache_loop) + li r3, 0 + li r4, 1 + sldi r4, r4, ITER_SHIFT + +.Lloop: cmpdi r4, 0 + beqlr + + addi r4, r4, -1 + + ld r6, jump_table@got(%r2) + sldi r5, r3, 2 + lwax r6, r5, r6 + ld r7, .Lstate_0@got(%r2) + add r6, r6, r7 + mtctr r6 + bctr + + state 0 + state 1 + state 2 + state 3 + state 4 + state 5 + state 6 + state 7 + +FUNC_END(pattern_cache_loop) + + +FUNC_START(indirect_branch_loop) + li r3, 1 + sldi r3, r3, ITER_SHIFT + +1: cmpdi r3, 0 + beqlr + + addi r3, r3, -1 + + ld r4, 2f@got(%r2) + mtctr r4 + bctr + + .balign 32 +2: b 1b + +FUNC_END(indirect_branch_loop) diff --git a/tools/testing/selftests/powerpc/security/spectre_v2.c b/tools/testing/selftests/powerpc/security/spectre_v2.c new file mode 100644 index 000000000000..8c6b982af2a8 --- /dev/null +++ b/tools/testing/selftests/powerpc/security/spectre_v2.c @@ -0,0 +1,218 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* + * Copyright 2018-2019 IBM Corporation. + */ + +#define __SANE_USERSPACE_TYPES__ + +#include <sys/types.h> +#include <stdint.h> +#include <malloc.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <sys/prctl.h> +#include "utils.h" + +#include "../pmu/event.h" + + +extern void pattern_cache_loop(void); +extern void indirect_branch_loop(void); + +static int do_count_loop(struct event *events, bool is_p9, s64 *miss_percent) +{ + u64 pred, mpred; + + prctl(PR_TASK_PERF_EVENTS_ENABLE); + + if (is_p9) + pattern_cache_loop(); + else + indirect_branch_loop(); + + prctl(PR_TASK_PERF_EVENTS_DISABLE); + + event_read(&events[0]); + event_read(&events[1]); + + // We could scale all the events by running/enabled but we're lazy + // As long as the PMU is uncontended they should all run + FAIL_IF(events[0].result.running != events[0].result.enabled); + FAIL_IF(events[1].result.running != events[1].result.enabled); + + pred = events[0].result.value; + mpred = events[1].result.value; + + if (is_p9) { + event_read(&events[2]); + event_read(&events[3]); + FAIL_IF(events[2].result.running != events[2].result.enabled); + FAIL_IF(events[3].result.running != events[3].result.enabled); + + pred += events[2].result.value; + mpred += events[3].result.value; + } + + *miss_percent = 100 * mpred / pred; + + return 0; +} + +static void setup_event(struct event *e, u64 config, char *name) +{ + event_init_named(e, config, name); + + e->attr.disabled = 1; + e->attr.exclude_kernel = 1; + e->attr.exclude_hv = 1; + e->attr.exclude_idle = 1; +} + +enum spectre_v2_state { + VULNERABLE = 0, + UNKNOWN = 1, // Works with FAIL_IF() + NOT_AFFECTED, + BRANCH_SERIALISATION, + COUNT_CACHE_DISABLED, + COUNT_CACHE_FLUSH_SW, + COUNT_CACHE_FLUSH_HW, + BTB_FLUSH, +}; + +static enum spectre_v2_state get_sysfs_state(void) +{ + enum spectre_v2_state state = UNKNOWN; + char buf[256]; + int len; + + memset(buf, 0, sizeof(buf)); + FAIL_IF(read_sysfs_file("devices/system/cpu/vulnerabilities/spectre_v2", buf, sizeof(buf))); + + // Make sure it's NULL terminated + buf[sizeof(buf) - 1] = '\0'; + + // Trim the trailing newline + len = strlen(buf); + FAIL_IF(len < 1); + buf[len - 1] = '\0'; + + printf("sysfs reports: '%s'\n", buf); + + // Order matters + if (strstr(buf, "Vulnerable")) + state = VULNERABLE; + else if (strstr(buf, "Not affected")) + state = NOT_AFFECTED; + else if (strstr(buf, "Indirect branch serialisation (kernel only)")) + state = BRANCH_SERIALISATION; + else if (strstr(buf, "Indirect branch cache disabled")) + state = COUNT_CACHE_DISABLED; + else if (strstr(buf, "Software count cache flush (hardware accelerated)")) + state = COUNT_CACHE_FLUSH_HW; + else if (strstr(buf, "Software count cache flush")) + state = COUNT_CACHE_FLUSH_SW; + else if (strstr(buf, "Branch predictor state flush")) + state = BTB_FLUSH; + + return state; +} + +#define PM_BR_PRED_CCACHE 0x040a4 // P8 + P9 +#define PM_BR_MPRED_CCACHE 0x040ac // P8 + P9 +#define PM_BR_PRED_PCACHE 0x048a0 // P9 only +#define PM_BR_MPRED_PCACHE 0x048b0 // P9 only + +#define SPRN_PVR 287 + +int spectre_v2_test(void) +{ + enum spectre_v2_state state; + struct event events[4]; + s64 miss_percent; + bool is_p9; + + state = get_sysfs_state(); + if (state == UNKNOWN) { + printf("Error: couldn't determine spectre_v2 mitigation state?\n"); + return -1; + } + + memset(events, 0, sizeof(events)); + + setup_event(&events[0], PM_BR_PRED_CCACHE, "PM_BR_PRED_CCACHE"); + setup_event(&events[1], PM_BR_MPRED_CCACHE, "PM_BR_MPRED_CCACHE"); + FAIL_IF(event_open(&events[0])); + FAIL_IF(event_open_with_group(&events[1], events[0].fd) == -1); + + is_p9 = ((mfspr(SPRN_PVR) >> 16) & 0xFFFF) == 0x4e; + + if (is_p9) { + // Count pattern cache too + setup_event(&events[2], PM_BR_PRED_PCACHE, "PM_BR_PRED_PCACHE"); + setup_event(&events[3], PM_BR_MPRED_PCACHE, "PM_BR_MPRED_PCACHE"); + + FAIL_IF(event_open_with_group(&events[2], events[0].fd) == -1); + FAIL_IF(event_open_with_group(&events[3], events[0].fd) == -1); + } + + FAIL_IF(do_count_loop(events, is_p9, &miss_percent)); + + event_report_justified(&events[0], 18, 10); + event_report_justified(&events[1], 18, 10); + event_close(&events[0]); + event_close(&events[1]); + + if (is_p9) { + event_report_justified(&events[2], 18, 10); + event_report_justified(&events[3], 18, 10); + event_close(&events[2]); + event_close(&events[3]); + } + + printf("Miss percent %lld %%\n", miss_percent); + + switch (state) { + case VULNERABLE: + case NOT_AFFECTED: + case COUNT_CACHE_FLUSH_SW: + case COUNT_CACHE_FLUSH_HW: + // These should all not affect userspace branch prediction + if (miss_percent > 15) { + printf("Branch misses > 15%% unexpected in this configuration!\n"); + printf("Possible mis-match between reported & actual mitigation\n"); + return 1; + } + break; + case BRANCH_SERIALISATION: + // This seems to affect userspace branch prediction a bit? + if (miss_percent > 25) { + printf("Branch misses > 25%% unexpected in this configuration!\n"); + printf("Possible mis-match between reported & actual mitigation\n"); + return 1; + } + break; + case COUNT_CACHE_DISABLED: + if (miss_percent < 95) { + printf("Branch misses < 20%% unexpected in this configuration!\n"); + printf("Possible mis-match between reported & actual mitigation\n"); + return 1; + } + break; + case UNKNOWN: + case BTB_FLUSH: + printf("Not sure!\n"); + return 1; + } + + printf("OK - Measured branch prediction rates match reported spectre v2 mitigation.\n"); + + return 0; +} + +int main(int argc, char *argv[]) +{ + return test_harness(spectre_v2_test, "spectre_v2"); +} diff --git a/tools/testing/selftests/powerpc/signal/sigfuz.c b/tools/testing/selftests/powerpc/signal/sigfuz.c index dade00c698c2..08f9afe3b95c 100644 --- a/tools/testing/selftests/powerpc/signal/sigfuz.c +++ b/tools/testing/selftests/powerpc/signal/sigfuz.c @@ -42,7 +42,7 @@ #include "utils.h" /* Selftest defaults */ -#define COUNT_MAX 4000 /* Number of interactions */ +#define COUNT_MAX 600 /* Number of interactions */ #define THREADS 16 /* Number of threads */ /* Arguments options */ diff --git a/tools/testing/selftests/powerpc/tm/tm-signal-sigreturn-nt.c b/tools/testing/selftests/powerpc/tm/tm-signal-sigreturn-nt.c index 56fbf9f6bbf3..07c388147b75 100644 --- a/tools/testing/selftests/powerpc/tm/tm-signal-sigreturn-nt.c +++ b/tools/testing/selftests/powerpc/tm/tm-signal-sigreturn-nt.c @@ -10,10 +10,12 @@ */ #define _GNU_SOURCE +#include <stdio.h> #include <stdlib.h> #include <signal.h> #include "utils.h" +#include "tm.h" void trap_signal_handler(int signo, siginfo_t *si, void *uc) { @@ -29,6 +31,8 @@ int tm_signal_sigreturn_nt(void) { struct sigaction trap_sa; + SKIP_IF(!have_htm()); + trap_sa.sa_flags = SA_SIGINFO; trap_sa.sa_sigaction = trap_signal_handler; diff --git a/tools/testing/selftests/powerpc/utils.c b/tools/testing/selftests/powerpc/utils.c index c02d24835db4..5ee0e98c4896 100644 --- a/tools/testing/selftests/powerpc/utils.c +++ b/tools/testing/selftests/powerpc/utils.c @@ -127,6 +127,26 @@ bool is_ppc64le(void) return strcmp(uts.machine, "ppc64le") == 0; } +int read_sysfs_file(char *fpath, char *result, size_t result_size) +{ + char path[PATH_MAX] = "/sys/"; + int rc = -1, fd; + + strncat(path, fpath, PATH_MAX - strlen(path) - 1); + + if ((fd = open(path, O_RDONLY)) < 0) + return rc; + + rc = read(fd, result, result_size); + + close(fd); + + if (rc < 0) + return rc; + + return 0; +} + int read_debugfs_file(char *debugfs_file, int *result) { int rc = -1, fd; diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index aeb0fc37a654..6944b898bb53 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c @@ -35,6 +35,7 @@ #include <stdbool.h> #include <string.h> #include <time.h> +#include <limits.h> #include <linux/elf.h> #include <sys/uio.h> #include <sys/utsname.h> @@ -43,6 +44,7 @@ #include <sys/times.h> #include <sys/socket.h> #include <sys/ioctl.h> +#include <linux/kcmp.h> #include <unistd.h> #include <sys/syscall.h> @@ -206,6 +208,10 @@ struct seccomp_notif_sizes { #define PTRACE_EVENTMSG_SYSCALL_EXIT 2 #endif +#ifndef SECCOMP_USER_NOTIF_FLAG_CONTINUE +#define SECCOMP_USER_NOTIF_FLAG_CONTINUE 0x00000001 +#endif + #ifndef seccomp int seccomp(unsigned int op, unsigned int flags, void *args) { @@ -3083,7 +3089,7 @@ static int user_trap_syscall(int nr, unsigned int flags) return seccomp(SECCOMP_SET_MODE_FILTER, flags, &prog); } -#define USER_NOTIF_MAGIC 116983961184613L +#define USER_NOTIF_MAGIC INT_MAX TEST(user_notification_basic) { pid_t pid; @@ -3491,6 +3497,108 @@ TEST(seccomp_get_notif_sizes) EXPECT_EQ(sizes.seccomp_notif_resp, sizeof(struct seccomp_notif_resp)); } +static int filecmp(pid_t pid1, pid_t pid2, int fd1, int fd2) +{ +#ifdef __NR_kcmp + return syscall(__NR_kcmp, pid1, pid2, KCMP_FILE, fd1, fd2); +#else + errno = ENOSYS; + return -1; +#endif +} + +TEST(user_notification_continue) +{ + pid_t pid; + long ret; + int status, listener; + struct seccomp_notif req = {}; + struct seccomp_notif_resp resp = {}; + struct pollfd pollfd; + + ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); + ASSERT_EQ(0, ret) { + TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!"); + } + + listener = user_trap_syscall(__NR_dup, SECCOMP_FILTER_FLAG_NEW_LISTENER); + ASSERT_GE(listener, 0); + + pid = fork(); + ASSERT_GE(pid, 0); + + if (pid == 0) { + int dup_fd, pipe_fds[2]; + pid_t self; + + ret = pipe(pipe_fds); + if (ret < 0) + exit(1); + + dup_fd = dup(pipe_fds[0]); + if (dup_fd < 0) + exit(1); + + self = getpid(); + + ret = filecmp(self, self, pipe_fds[0], dup_fd); + if (ret) + exit(2); + + exit(0); + } + + pollfd.fd = listener; + pollfd.events = POLLIN | POLLOUT; + + EXPECT_GT(poll(&pollfd, 1, -1), 0); + EXPECT_EQ(pollfd.revents, POLLIN); + + EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0); + + pollfd.fd = listener; + pollfd.events = POLLIN | POLLOUT; + + EXPECT_GT(poll(&pollfd, 1, -1), 0); + EXPECT_EQ(pollfd.revents, POLLOUT); + + EXPECT_EQ(req.data.nr, __NR_dup); + + resp.id = req.id; + resp.flags = SECCOMP_USER_NOTIF_FLAG_CONTINUE; + + /* + * Verify that setting SECCOMP_USER_NOTIF_FLAG_CONTINUE enforces other + * args be set to 0. + */ + resp.error = 0; + resp.val = USER_NOTIF_MAGIC; + EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), -1); + EXPECT_EQ(errno, EINVAL); + + resp.error = USER_NOTIF_MAGIC; + resp.val = 0; + EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), -1); + EXPECT_EQ(errno, EINVAL); + + resp.error = 0; + resp.val = 0; + EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), 0) { + if (errno == EINVAL) + XFAIL(goto skip, "Kernel does not support SECCOMP_USER_NOTIF_FLAG_CONTINUE"); + } + +skip: + EXPECT_EQ(waitpid(pid, &status, 0), pid); + EXPECT_EQ(true, WIFEXITED(status)); + EXPECT_EQ(0, WEXITSTATUS(status)) { + if (WEXITSTATUS(status) == 2) { + XFAIL(return, "Kernel does not support kcmp() syscall"); + return; + } + } +} + /* * TODO: * - add microbenchmarks diff --git a/tools/testing/selftests/x86/single_step_syscall.c b/tools/testing/selftests/x86/single_step_syscall.c index 50ce6c3dd904..1063328e275c 100644 --- a/tools/testing/selftests/x86/single_step_syscall.c +++ b/tools/testing/selftests/x86/single_step_syscall.c @@ -43,7 +43,19 @@ static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), err(1, "sigaction"); } -static volatile sig_atomic_t sig_traps; +static void clearhandler(int sig) +{ + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_DFL; + sigemptyset(&sa.sa_mask); + if (sigaction(sig, &sa, 0)) + err(1, "sigaction"); +} + +static volatile sig_atomic_t sig_traps, sig_eflags; +sigjmp_buf jmpbuf; +static unsigned char altstack_data[SIGSTKSZ]; #ifdef __x86_64__ # define REG_IP REG_RIP @@ -90,6 +102,25 @@ static void sigtrap(int sig, siginfo_t *info, void *ctx_void) } } +static char const * const signames[] = { + [SIGSEGV] = "SIGSEGV", + [SIGBUS] = "SIBGUS", + [SIGTRAP] = "SIGTRAP", + [SIGILL] = "SIGILL", +}; + +static void print_and_longjmp(int sig, siginfo_t *si, void *ctx_void) +{ + ucontext_t *ctx = ctx_void; + + printf("\tGot %s with RIP=%lx, TF=%ld\n", signames[sig], + (unsigned long)ctx->uc_mcontext.gregs[REG_IP], + (unsigned long)ctx->uc_mcontext.gregs[REG_EFL] & X86_EFLAGS_TF); + + sig_eflags = (unsigned long)ctx->uc_mcontext.gregs[REG_EFL]; + siglongjmp(jmpbuf, 1); +} + static void check_result(void) { unsigned long new_eflags = get_eflags(); @@ -109,6 +140,22 @@ static void check_result(void) sig_traps = 0; } +static void fast_syscall_no_tf(void) +{ + sig_traps = 0; + printf("[RUN]\tFast syscall with TF cleared\n"); + fflush(stdout); /* Force a syscall */ + if (get_eflags() & X86_EFLAGS_TF) { + printf("[FAIL]\tTF is now set\n"); + exit(1); + } + if (sig_traps) { + printf("[FAIL]\tGot SIGTRAP\n"); + exit(1); + } + printf("[OK]\tNothing unexpected happened\n"); +} + int main() { #ifdef CAN_BUILD_32 @@ -163,17 +210,46 @@ int main() check_result(); /* Now make sure that another fast syscall doesn't set TF again. */ - printf("[RUN]\tFast syscall with TF cleared\n"); - fflush(stdout); /* Force a syscall */ - if (get_eflags() & X86_EFLAGS_TF) { - printf("[FAIL]\tTF is now set\n"); - exit(1); + fast_syscall_no_tf(); + + /* + * And do a forced SYSENTER to make sure that this works even if + * fast syscalls don't use SYSENTER. + * + * Invoking SYSENTER directly breaks all the rules. Just handle + * the SIGSEGV. + */ + if (sigsetjmp(jmpbuf, 1) == 0) { + unsigned long nr = SYS_getpid; + printf("[RUN]\tSet TF and check SYSENTER\n"); + stack_t stack = { + .ss_sp = altstack_data, + .ss_size = SIGSTKSZ, + }; + if (sigaltstack(&stack, NULL) != 0) + err(1, "sigaltstack"); + sethandler(SIGSEGV, print_and_longjmp, + SA_RESETHAND | SA_ONSTACK); + sethandler(SIGILL, print_and_longjmp, SA_RESETHAND); + set_eflags(get_eflags() | X86_EFLAGS_TF); + /* Clear EBP first to make sure we segfault cleanly. */ + asm volatile ("xorl %%ebp, %%ebp; SYSENTER" : "+a" (nr) :: "flags", "rcx" +#ifdef __x86_64__ + , "r11" +#endif + ); + + /* We're unreachable here. SYSENTER forgets RIP. */ } - if (sig_traps) { - printf("[FAIL]\tGot SIGTRAP\n"); + clearhandler(SIGSEGV); + clearhandler(SIGILL); + if (!(sig_eflags & X86_EFLAGS_TF)) { + printf("[FAIL]\tTF was cleared\n"); exit(1); } - printf("[OK]\tNothing unexpected happened\n"); + + /* Now make sure that another fast syscall doesn't set TF again. */ + fast_syscall_no_tf(); return 0; } |