linux-kselftest-next-5.19-rc1

This Kselftest update for Linux 5.19-rc1 consists of several fixes,
 cleanups, and enhancements to tests:
 
 - adds mips support for kprobe args string and syntax tests
 - updates to resctrl test to use kselftest framework
 - fixes, cleanups, and enhancements to tests
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEPZKym/RZuOCGeA/kCwJExA0NQxwFAmKL2WUACgkQCwJExA0N
 Qxw3ERAAmmZ3p0ULMeUNiNjsL7zFL0x7LvgutfnXeBmy99QvZif0Zn44c1/Kv3Qc
 Jb/cUNA76u4Z9Z2L3ITeoZbk/s0Vdc4gXtP22O5CnBbQLMv8ptpMCRBPLmrYVmdm
 YIep2hEuqL9IuraRLsvbAWwJm6r7xTeR5IaLf3B7HtY2IjHAdEuX4wklnaap1gt/
 nk1BYMb0i8WAPlpl7leCL+2ZbFzI2tcpap9gTcFVNnsPTI4cS3+88mHopG0pw8cv
 uszj63xOFDhV6sOxtpJDhepBOKbjHMNgxc+wm/4zWdLPVA71dF46CEdLqKZ2gDVt
 rNocmDZUlLv18N2jHm8S6YWjZuDbv3L3FCkA1d8grsDC0khKSkY8wHd9PBgLkZ+a
 gSO7TNU2o8dLj4i+MMgs2x+/iKAftyBWAP5XQURdZHiTJ+BrJTxN9Ph4kwHpzXai
 2Cauk9xIwDJanRI7ArOBcjSnhXY64opHUOBt1h7NIzm/114Qlr9Aj8TKZIAYyqMw
 BgjgOY30nQzSFkG7ASOdQckmUxa5gV6VVFmDt5+p13bisypz8iFWefOL9MvN8sdE
 z7PZChAgi0oYicGOUk1jBlXZfaWb8kmtk8KV2vFMcF4GnvMzlAWaBN7v3vP34afG
 IqQXZHI6//XiedDtLUn9XBdnT0NPFSbhmRYDHwGYGZ6oM4k4pRs=
 =MKRc
 -----END PGP SIGNATURE-----

Merge tag 'linux-kselftest-next-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest

Pull Kselftest updates from Shuah Khan:
 "Several fixes, cleanups, and enhancements to tests:

   - add mips support for kprobe args string and syntax tests

   - updates to resctrl test to use kselftest framework

   - fixes, cleanups, and enhancements to tests"

* tag 'linux-kselftest-next-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest:
  kselftests/ir : Improve readability of modprobe error message
  selftests/resctrl: Fix null pointer dereference on open failed
  selftests/resctrl: Add missing SPDX license to Makefile
  selftests/resctrl: Update README about using kselftest framework to build/run resctrl_tests
  selftests/resctrl: Make resctrl_tests run using kselftest framework
  selftests/resctrl: Fix resctrl_tests' return code to work with selftest framework
  selftests/resctrl: Change the default limited time to 120 seconds
  selftests/resctrl: Kill child process before parent process terminates if SIGTERM is received
  selftests/resctrl: Print a message if the result of MBM&CMT tests is failed on Intel CPU
  selftests/resctrl: Extend CPU vendor detection
  selftests/x86/corrupt_xstate_header: Use provided __cpuid_count() macro
  selftests/x86/amx: Use provided __cpuid_count() macro
  selftests/vm/pkeys: Use provided __cpuid_count() macro
  selftests: Provide local define of __cpuid_count()
  selftests/damon: add damon to selftests root Makefile
  selftests/binderfs: Improve message to provide more info
  selftests: mqueue: drop duplicate min definition
  selftests/ftrace: add mips support for kprobe args syntax tests
  selftests/ftrace: add mips support for kprobe args string tests
This commit is contained in:
Linus Torvalds 2022-05-25 11:30:21 -07:00
commit 1c6d2ead87
19 changed files with 124 additions and 94 deletions

View File

@ -9,6 +9,7 @@ TARGETS += clone3
TARGETS += core TARGETS += core
TARGETS += cpufreq TARGETS += cpufreq
TARGETS += cpu-hotplug TARGETS += cpu-hotplug
TARGETS += damon
TARGETS += drivers/dma-buf TARGETS += drivers/dma-buf
TARGETS += efivarfs TARGETS += efivarfs
TARGETS += exec TARGETS += exec
@ -52,6 +53,7 @@ TARGETS += proc
TARGETS += pstore TARGETS += pstore
TARGETS += ptrace TARGETS += ptrace
TARGETS += openat2 TARGETS += openat2
TARGETS += resctrl
TARGETS += rlimits TARGETS += rlimits
TARGETS += rseq TARGETS += rseq
TARGETS += rtc TARGETS += rtc

View File

@ -412,7 +412,8 @@ TEST(binderfs_stress)
ret = mount(NULL, binderfs_mntpt, "binder", 0, 0); ret = mount(NULL, binderfs_mntpt, "binder", 0, 0);
ASSERT_EQ(ret, 0) { ASSERT_EQ(ret, 0) {
TH_LOG("%s - Failed to mount binderfs", strerror(errno)); TH_LOG("%s - Failed to mount binderfs, check if CONFIG_ANDROID_BINDERFS is enabled in the running kernel",
strerror(errno));
} }
for (int i = 0; i < ARRAY_SIZE(fds); i++) { for (int i = 0; i < ARRAY_SIZE(fds); i++) {

View File

@ -25,6 +25,9 @@ ppc*)
s390*) s390*)
ARG1=%r2 ARG1=%r2
;; ;;
mips*)
ARG1=%r4
;;
*) *)
echo "Please implement other architecture here" echo "Please implement other architecture here"
exit_untested exit_untested

View File

@ -36,6 +36,10 @@ s390*)
GOODREG=%r2 GOODREG=%r2
BADREG=%s2 BADREG=%s2
;; ;;
mips*)
GOODREG=%r4
BADREG=%r12
;;
*) *)
echo "Please implement other architecture here" echo "Please implement other architecture here"
exit_untested exit_untested

View File

@ -10,7 +10,7 @@ if [ $UID != 0 ]; then
fi fi
if ! /sbin/modprobe -q -n rc-loopback; then if ! /sbin/modprobe -q -n rc-loopback; then
echo "ir_loopback: module rc-loopback is not found [SKIP]" echo "ir_loopback: module rc-loopback is not found in /lib/modules/`uname -r` [SKIP]"
exit $ksft_skip exit $ksft_skip
fi fi

View File

@ -53,6 +53,21 @@
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif #endif
/*
* gcc cpuid.h provides __cpuid_count() since v4.4.
* Clang/LLVM cpuid.h provides __cpuid_count() since v3.4.0.
*
* Provide local define for tests needing __cpuid_count() because
* selftests need to work in older environments that do not yet
* have __cpuid_count().
*/
#ifndef __cpuid_count
#define __cpuid_count(level, count, a, b, c, d) \
__asm__ __volatile__ ("cpuid\n\t" \
: "=a" (a), "=b" (b), "=c" (c), "=d" (d) \
: "0" (level), "2" (count))
#endif
/* define kselftest exit codes */ /* define kselftest exit codes */
#define KSFT_PASS 0 #define KSFT_PASS 0
#define KSFT_FAIL 1 #define KSFT_FAIL 1

View File

@ -35,6 +35,7 @@
#include <sys/time.h> #include <sys/time.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/param.h>
#include <mqueue.h> #include <mqueue.h>
#include <popt.h> #include <popt.h>
#include <error.h> #include <error.h>
@ -73,7 +74,6 @@ static char *usage =
char *MAX_MSGS = "/proc/sys/fs/mqueue/msg_max"; char *MAX_MSGS = "/proc/sys/fs/mqueue/msg_max";
char *MAX_MSGSIZE = "/proc/sys/fs/mqueue/msgsize_max"; char *MAX_MSGSIZE = "/proc/sys/fs/mqueue/msgsize_max";
#define min(a, b) ((a) < (b) ? (a) : (b))
#define MAX_CPUS 64 #define MAX_CPUS 64
char *cpu_option_string; char *cpu_option_string;
int cpus_to_pin[MAX_CPUS]; int cpus_to_pin[MAX_CPUS];
@ -560,7 +560,7 @@ int main(int argc, char *argv[])
"require root in order to modify\nsystem settings. " "require root in order to modify\nsystem settings. "
"Exiting.\n"); "Exiting.\n");
cpus_online = min(MAX_CPUS, sysconf(_SC_NPROCESSORS_ONLN)); cpus_online = MIN(MAX_CPUS, sysconf(_SC_NPROCESSORS_ONLN));
cpu_set = CPU_ALLOC(cpus_online); cpu_set = CPU_ALLOC(cpus_online);
if (cpu_set == NULL) { if (cpu_set == NULL) {
perror("CPU_ALLOC()"); perror("CPU_ALLOC()");

View File

@ -1,17 +1,10 @@
CC = $(CROSS_COMPILE)gcc # SPDX-License-Identifier: GPL-2.0
CFLAGS = -g -Wall -O2 -D_FORTIFY_SOURCE=2 CFLAGS = -g -Wall -O2 -D_FORTIFY_SOURCE=2
SRCS=$(wildcard *.c) CFLAGS += $(KHDR_INCLUDES)
OBJS=$(SRCS:.c=.o)
all: resctrl_tests TEST_GEN_PROGS := resctrl_tests
$(OBJS): $(SRCS) include ../lib.mk
$(CC) $(CFLAGS) -c $(SRCS)
resctrl_tests: $(OBJS) $(OUTPUT)/resctrl_tests: $(wildcard *.c)
$(CC) $(CFLAGS) -o $@ $^
.PHONY: clean
clean:
$(RM) $(OBJS) resctrl_tests

View File

@ -12,24 +12,49 @@ Allocation test on Intel RDT hardware. More tests will be added in the future.
And the test suit can be extended to cover AMD QoS and ARM MPAM hardware And the test suit can be extended to cover AMD QoS and ARM MPAM hardware
as well. as well.
resctrl_tests can be run with or without kselftest framework.
WITH KSELFTEST FRAMEWORK
=======================
BUILD BUILD
----- -----
Run "make" to build executable file "resctrl_tests". Build executable file "resctrl_tests" from top level directory of the kernel source:
$ make -C tools/testing/selftests TARGETS=resctrl
RUN RUN
--- ---
To use resctrl_tests, root or sudoer privileges are required. This is because Run resctrl_tests as sudo or root since the test needs to mount resctrl file
the test needs to mount resctrl file system and change contents in the file system and change contents in the file system.
system. Using kselftest framework will run all supported tests within resctrl_tests:
$ sudo make -C tools/testing/selftests TARGETS=resctrl run_tests
More details about kselftest framework can be found in
Documentation/dev-tools/kselftest.rst.
WITHOUT KSELFTEST FRAMEWORK
===========================
BUILD
-----
Build executable file "resctrl_tests" from this directory(tools/testing/selftests/resctrl/):
$ make
RUN
---
Run resctrl_tests as sudo or root since the test needs to mount resctrl file
system and change contents in the file system.
Executing the test without any parameter will run all supported tests: Executing the test without any parameter will run all supported tests:
sudo ./resctrl_tests $ sudo ./resctrl_tests
OVERVIEW OF EXECUTION OVERVIEW OF EXECUTION
--------------------- =====================
A test case has four stages: A test case has four stages:
@ -41,7 +66,7 @@ A test case has four stages:
- teardown: umount resctrl and clear temporary files. - teardown: umount resctrl and clear temporary files.
ARGUMENTS ARGUMENTS
--------- =========
Parameter '-h' shows usage information. Parameter '-h' shows usage information.

View File

@ -89,7 +89,7 @@ static int check_results(struct resctrl_val_param *param)
return show_cache_info(sum_llc_perf_miss, no_of_bits, param->span / 64, return show_cache_info(sum_llc_perf_miss, no_of_bits, param->span / 64,
MAX_DIFF, MAX_DIFF_PERCENT, NUM_OF_RUNS, MAX_DIFF, MAX_DIFF_PERCENT, NUM_OF_RUNS,
!is_amd, false); get_vendor() == ARCH_INTEL, false);
} }
void cat_test_cleanup(void) void cat_test_cleanup(void)

View File

@ -121,8 +121,10 @@ static int fill_cache_read(unsigned char *start_ptr, unsigned char *end_ptr,
/* Consume read result so that reading memory is not optimized out. */ /* Consume read result so that reading memory is not optimized out. */
fp = fopen("/dev/null", "w"); fp = fopen("/dev/null", "w");
if (!fp) if (!fp) {
perror("Unable to write to /dev/null"); perror("Unable to write to /dev/null");
return -1;
}
fprintf(fp, "Sum: %d ", ret); fprintf(fp, "Sum: %d ", ret);
fclose(fp); fclose(fp);

View File

@ -34,6 +34,9 @@
#define L3_MON_PATH "/sys/fs/resctrl/info/L3_MON" #define L3_MON_PATH "/sys/fs/resctrl/info/L3_MON"
#define L3_MON_FEATURES_PATH "/sys/fs/resctrl/info/L3_MON/mon_features" #define L3_MON_FEATURES_PATH "/sys/fs/resctrl/info/L3_MON/mon_features"
#define ARCH_INTEL 1
#define ARCH_AMD 2
#define PARENT_EXIT(err_msg) \ #define PARENT_EXIT(err_msg) \
do { \ do { \
perror(err_msg); \ perror(err_msg); \
@ -75,8 +78,8 @@ struct resctrl_val_param {
extern pid_t bm_pid, ppid; extern pid_t bm_pid, ppid;
extern char llc_occup_path[1024]; extern char llc_occup_path[1024];
extern bool is_amd;
int get_vendor(void);
bool check_resctrlfs_support(void); bool check_resctrlfs_support(void);
int filter_dmesg(void); int filter_dmesg(void);
int remount_resctrlfs(bool mum_resctrlfs); int remount_resctrlfs(bool mum_resctrlfs);

View File

@ -13,25 +13,41 @@
#define BENCHMARK_ARGS 64 #define BENCHMARK_ARGS 64
#define BENCHMARK_ARG_SIZE 64 #define BENCHMARK_ARG_SIZE 64
bool is_amd; static int detect_vendor(void)
void detect_amd(void)
{ {
FILE *inf = fopen("/proc/cpuinfo", "r"); FILE *inf = fopen("/proc/cpuinfo", "r");
int vendor_id = 0;
char *s = NULL;
char *res; char *res;
if (!inf) if (!inf)
return; return vendor_id;
res = fgrep(inf, "vendor_id"); res = fgrep(inf, "vendor_id");
if (res) { if (res)
char *s = strchr(res, ':'); s = strchr(res, ':');
if (s && !strcmp(s, ": GenuineIntel\n"))
vendor_id = ARCH_INTEL;
else if (s && !strcmp(s, ": AuthenticAMD\n"))
vendor_id = ARCH_AMD;
is_amd = s && !strcmp(s, ": AuthenticAMD\n");
free(res);
}
fclose(inf); fclose(inf);
free(res);
return vendor_id;
}
int get_vendor(void)
{
static int vendor = -1;
if (vendor == -1)
vendor = detect_vendor();
if (vendor == 0)
ksft_print_msg("Can not get vendor info...\n");
return vendor;
} }
static void cmd_help(void) static void cmd_help(void)
@ -70,6 +86,8 @@ static void run_mbm_test(bool has_ben, char **benchmark_cmd, int span,
sprintf(benchmark_cmd[5], "%s", MBA_STR); sprintf(benchmark_cmd[5], "%s", MBA_STR);
res = mbm_bw_change(span, cpu_no, bw_report, benchmark_cmd); res = mbm_bw_change(span, cpu_no, bw_report, benchmark_cmd);
ksft_test_result(!res, "MBM: bw change\n"); ksft_test_result(!res, "MBM: bw change\n");
if ((get_vendor() == ARCH_INTEL) && res)
ksft_print_msg("Intel MBM may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n");
mbm_test_cleanup(); mbm_test_cleanup();
} }
@ -106,6 +124,8 @@ static void run_cmt_test(bool has_ben, char **benchmark_cmd, int cpu_no)
sprintf(benchmark_cmd[5], "%s", CMT_STR); sprintf(benchmark_cmd[5], "%s", CMT_STR);
res = cmt_resctrl_val(cpu_no, 5, benchmark_cmd); res = cmt_resctrl_val(cpu_no, 5, benchmark_cmd);
ksft_test_result(!res, "CMT: test\n"); ksft_test_result(!res, "CMT: test\n");
if ((get_vendor() == ARCH_INTEL) && res)
ksft_print_msg("Intel CMT may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n");
cmt_test_cleanup(); cmt_test_cleanup();
} }
@ -205,10 +225,7 @@ int main(int argc, char **argv)
* 2. We execute perf commands * 2. We execute perf commands
*/ */
if (geteuid() != 0) if (geteuid() != 0)
return ksft_exit_fail_msg("Not running as root, abort testing.\n"); return ksft_exit_skip("Not running as root. Skipping...\n");
/* Detect AMD vendor */
detect_amd();
if (has_ben) { if (has_ben) {
/* Extract benchmark command from command line. */ /* Extract benchmark command from command line. */
@ -235,16 +252,16 @@ int main(int argc, char **argv)
sprintf(bm_type, "fill_buf"); sprintf(bm_type, "fill_buf");
if (!check_resctrlfs_support()) if (!check_resctrlfs_support())
return ksft_exit_fail_msg("resctrl FS does not exist\n"); return ksft_exit_skip("resctrl FS does not exist. Enable X86_CPU_RESCTRL config option.\n");
filter_dmesg(); filter_dmesg();
ksft_set_plan(tests ? : 4); ksft_set_plan(tests ? : 4);
if (!is_amd && mbm_test) if ((get_vendor() == ARCH_INTEL) && mbm_test)
run_mbm_test(has_ben, benchmark_cmd, span, cpu_no, bw_report); run_mbm_test(has_ben, benchmark_cmd, span, cpu_no, bw_report);
if (!is_amd && mba_test) if ((get_vendor() == ARCH_INTEL) && mba_test)
run_mba_test(has_ben, benchmark_cmd, span, cpu_no, bw_report); run_mba_test(has_ben, benchmark_cmd, span, cpu_no, bw_report);
if (cmt_test) if (cmt_test)

View File

@ -678,6 +678,7 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
sigemptyset(&sigact.sa_mask); sigemptyset(&sigact.sa_mask);
sigact.sa_flags = SA_SIGINFO; sigact.sa_flags = SA_SIGINFO;
if (sigaction(SIGINT, &sigact, NULL) || if (sigaction(SIGINT, &sigact, NULL) ||
sigaction(SIGTERM, &sigact, NULL) ||
sigaction(SIGHUP, &sigact, NULL)) { sigaction(SIGHUP, &sigact, NULL)) {
perror("# sigaction"); perror("# sigaction");
ret = errno; ret = errno;

View File

@ -106,7 +106,7 @@ int get_resource_id(int cpu_no, int *resource_id)
char phys_pkg_path[1024]; char phys_pkg_path[1024];
FILE *fp; FILE *fp;
if (is_amd) if (get_vendor() == ARCH_AMD)
sprintf(phys_pkg_path, "%s%d/cache/index3/id", sprintf(phys_pkg_path, "%s%d/cache/index3/id",
PHYS_ID_PATH, cpu_no); PHYS_ID_PATH, cpu_no);
else else

View File

@ -0,0 +1,3 @@
# If running time is longer than 120 seconds when new tests are added in
# the future, increase timeout here.
timeout=120

View File

@ -80,19 +80,6 @@ static inline void __write_pkey_reg(u64 pkey_reg)
assert(pkey_reg == __read_pkey_reg()); assert(pkey_reg == __read_pkey_reg());
} }
static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
unsigned int *ecx, unsigned int *edx)
{
/* ecx is often an input as well as an output. */
asm volatile(
"cpuid;"
: "=a" (*eax),
"=b" (*ebx),
"=c" (*ecx),
"=d" (*edx)
: "0" (*eax), "2" (*ecx));
}
/* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx) */ /* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx) */
#define X86_FEATURE_PKU (1<<3) /* Protection Keys for Userspace */ #define X86_FEATURE_PKU (1<<3) /* Protection Keys for Userspace */
#define X86_FEATURE_OSPKE (1<<4) /* OS Protection Keys Enable */ #define X86_FEATURE_OSPKE (1<<4) /* OS Protection Keys Enable */
@ -104,9 +91,7 @@ static inline int cpu_has_pkeys(void)
unsigned int ecx; unsigned int ecx;
unsigned int edx; unsigned int edx;
eax = 0x7; __cpuid_count(0x7, 0x0, eax, ebx, ecx, edx);
ecx = 0x0;
__cpuid(&eax, &ebx, &ecx, &edx);
if (!(ecx & X86_FEATURE_PKU)) { if (!(ecx & X86_FEATURE_PKU)) {
dprintf2("cpu does not have PKU\n"); dprintf2("cpu does not have PKU\n");
@ -142,9 +127,7 @@ int pkey_reg_xstate_offset(void)
/* assume that XSTATE_PKEY is set in XCR0 */ /* assume that XSTATE_PKEY is set in XCR0 */
leaf = XSTATE_PKEY_BIT; leaf = XSTATE_PKEY_BIT;
{ {
eax = XSTATE_CPUID; __cpuid_count(XSTATE_CPUID, leaf, eax, ebx, ecx, edx);
ecx = leaf;
__cpuid(&eax, &ebx, &ecx, &edx);
if (leaf == XSTATE_PKEY_BIT) { if (leaf == XSTATE_PKEY_BIT) {
xstate_offset = ebx; xstate_offset = ebx;

View File

@ -17,6 +17,8 @@
#include <sys/syscall.h> #include <sys/syscall.h>
#include <sys/wait.h> #include <sys/wait.h>
#include "../kselftest.h" /* For __cpuid_count() */
#ifndef __x86_64__ #ifndef __x86_64__
# error This test is 64-bit only # error This test is 64-bit only
#endif #endif
@ -45,13 +47,6 @@ static inline uint64_t xgetbv(uint32_t index)
return eax + ((uint64_t)edx << 32); return eax + ((uint64_t)edx << 32);
} }
static inline void cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
{
asm volatile("cpuid;"
: "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
: "0" (*eax), "2" (*ecx));
}
static inline void xsave(struct xsave_buffer *xbuf, uint64_t rfbm) static inline void xsave(struct xsave_buffer *xbuf, uint64_t rfbm)
{ {
uint32_t rfbm_lo = rfbm; uint32_t rfbm_lo = rfbm;
@ -115,9 +110,7 @@ static inline void check_cpuid_xsave(void)
* support for the XSAVE feature set, including * support for the XSAVE feature set, including
* XGETBV. * XGETBV.
*/ */
eax = 1; __cpuid_count(1, 0, eax, ebx, ecx, edx);
ecx = 0;
cpuid(&eax, &ebx, &ecx, &edx);
if (!(ecx & CPUID_LEAF1_ECX_XSAVE_MASK)) if (!(ecx & CPUID_LEAF1_ECX_XSAVE_MASK))
fatal_error("cpuid: no CPU xsave support"); fatal_error("cpuid: no CPU xsave support");
if (!(ecx & CPUID_LEAF1_ECX_OSXSAVE_MASK)) if (!(ecx & CPUID_LEAF1_ECX_OSXSAVE_MASK))
@ -140,9 +133,8 @@ static void check_cpuid_xtiledata(void)
{ {
uint32_t eax, ebx, ecx, edx; uint32_t eax, ebx, ecx, edx;
eax = CPUID_LEAF_XSTATE; __cpuid_count(CPUID_LEAF_XSTATE, CPUID_SUBLEAF_XSTATE_USER,
ecx = CPUID_SUBLEAF_XSTATE_USER; eax, ebx, ecx, edx);
cpuid(&eax, &ebx, &ecx, &edx);
/* /*
* EBX enumerates the size (in bytes) required by the XSAVE * EBX enumerates the size (in bytes) required by the XSAVE
@ -153,10 +145,8 @@ static void check_cpuid_xtiledata(void)
*/ */
xbuf_size = ebx; xbuf_size = ebx;
eax = CPUID_LEAF_XSTATE; __cpuid_count(CPUID_LEAF_XSTATE, XFEATURE_XTILEDATA,
ecx = XFEATURE_XTILEDATA; eax, ebx, ecx, edx);
cpuid(&eax, &ebx, &ecx, &edx);
/* /*
* eax: XTILEDATA state component size * eax: XTILEDATA state component size
* ebx: XTILEDATA state component offset in user buffer * ebx: XTILEDATA state component offset in user buffer

View File

@ -17,25 +17,13 @@
#include <stdint.h> #include <stdint.h>
#include <sys/wait.h> #include <sys/wait.h>
static inline void __cpuid(unsigned int *eax, unsigned int *ebx, #include "../kselftest.h" /* For __cpuid_count() */
unsigned int *ecx, unsigned int *edx)
{
asm volatile(
"cpuid;"
: "=a" (*eax),
"=b" (*ebx),
"=c" (*ecx),
"=d" (*edx)
: "0" (*eax), "2" (*ecx));
}
static inline int xsave_enabled(void) static inline int xsave_enabled(void)
{ {
unsigned int eax, ebx, ecx, edx; unsigned int eax, ebx, ecx, edx;
eax = 0x1; __cpuid_count(0x1, 0x0, eax, ebx, ecx, edx);
ecx = 0x0;
__cpuid(&eax, &ebx, &ecx, &edx);
/* Is CR4.OSXSAVE enabled ? */ /* Is CR4.OSXSAVE enabled ? */
return ecx & (1U << 27); return ecx & (1U << 27);