Commit 0434dbe3 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'linux_kselftest-next-6.11-rc1' of...

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

Pull kselftest updates from Shuah Khan:

 - change resctrl test to cleanup resctrl_val() and generalize it by
   removing test name specific handling from the function.

 - several clang build failure fixes to framework and tests

 - add tests to verify IFS (In Field Scan) driver functionality

 - cleanups to remove unused variables and document changes

* tag 'linux_kselftest-next-6.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: (33 commits)
  selftests: ifs: verify IFS ARRAY BIST functionality
  selftests: ifs: verify IFS scan test functionality
  selftests: ifs: verify test image loading functionality
  selftests: ifs: verify test interfaces are created by the driver
  selftests/dma:remove unused variable
  selftests/breakpoints:Remove unused variable
  selftests/x86: fix printk warnings reported by clang
  selftests/x86: remove (or use) unused variables and functions
  selftests/x86: avoid -no-pie warnings from clang during compilation
  selftests/x86: build sysret_rip.c with clang
  selftests/x86: build fsgsbase_restore.c with clang
  selftests: x86: test_FISTTP: use fisttps instead of ambiguous fisttp
  selftests/x86: fix Makefile dependencies to work with clang
  selftests/timers: remove unused irqcount variable
  selftests: Add information about TAP conformance in tests
  selftests/resctrl: Remove test name comparing from write_bm_pid_to_resctrl()
  selftests/resctrl: Remove mongrp from CMT test
  selftests/resctrl: Remove mongrp from MBA test
  selftests/resctrl: Convert ctrlgrp & mongrp to pointers
  selftests/resctrl: Make some strings passed to resctrlfs functions const
  ...
parents f8d22a31 bb408dae
......@@ -228,6 +228,13 @@ In general, the rules for selftests are
* Don't cause the top-level "make run_tests" to fail if your feature is
unconfigured.
* The output of tests must conform to the TAP standard to ensure high
testing quality and to capture failures/errors with specific details.
The kselftest.h and kselftest_harness.h headers provide wrappers for
outputting test results. These wrappers should be used for pass,
fail, exit, and skip messages. CI systems can easily parse TAP output
messages to detect test results.
Contributing new tests (details)
================================
......
......@@ -11216,6 +11216,7 @@ R: Tony Luck <tony.luck@intel.com>
S: Maintained
F: drivers/platform/x86/intel/ifs
F: include/trace/events/intel_ifs.h
F: tools/testing/selftests/drivers/platform/x86/intel/ifs/
INTEL INTEGRATED SENSOR HUB DRIVER
M: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
......
......@@ -21,6 +21,7 @@ TARGETS += drivers/net
TARGETS += drivers/net/bonding
TARGETS += drivers/net/team
TARGETS += drivers/net/virtio_net
TARGETS += drivers/platform/x86/intel/ifs
TARGETS += dt
TARGETS += efivarfs
TARGETS += exec
......
......@@ -130,7 +130,6 @@ int run_test(int cpu)
void suspend(void)
{
int power_state_fd;
struct sigevent event = {};
int timerfd;
int err;
struct itimerspec spec = {};
......
......@@ -33,7 +33,6 @@ int main(int argc, char **argv)
int granule = 1;
int cmd = DMA_MAP_BENCHMARK;
char *p;
while ((opt = getopt(argc, argv, "t:s:n:b:d:x:g:")) != -1) {
switch (opt) {
......
# SPDX-License-Identifier: GPL-2.0
# Makefile for ifs(In Field Scan) selftests
TEST_PROGS := test_ifs.sh
include ../../../../../lib.mk
......@@ -38,6 +38,14 @@ else
CLANG_FLAGS += --target=$(notdir $(CROSS_COMPILE:%-=%))
endif # CROSS_COMPILE
# gcc defaults to silence (off) for the following warnings, but clang defaults
# to the opposite. The warnings are not useful for the kernel itself, which is
# why they have remained disabled in gcc for the main kernel build. And it is
# only due to including kernel data structures in the selftests, that we get the
# warnings from clang. Therefore, disable the warnings for clang builds.
CFLAGS += -Wno-address-of-packed-member
CFLAGS += -Wno-gnu-variable-sized-type-not-at-end
CC := $(CLANG) $(CLANG_FLAGS) -fintegrated-as
else
CC := $(CROSS_COMPILE)gcc
......
......@@ -101,12 +101,12 @@ static int get_llc_occu_resctrl(unsigned long *llc_occupancy)
*
* Return: 0 on success, < 0 on error.
*/
static int print_results_cache(const char *filename, int bm_pid, __u64 llc_value)
static int print_results_cache(const char *filename, pid_t bm_pid, __u64 llc_value)
{
FILE *fp;
if (strcmp(filename, "stdio") == 0 || strcmp(filename, "stderr") == 0) {
printf("Pid: %d \t LLC_value: %llu\n", bm_pid, llc_value);
printf("Pid: %d \t LLC_value: %llu\n", (int)bm_pid, llc_value);
} else {
fp = fopen(filename, "a");
if (!fp) {
......@@ -114,7 +114,7 @@ static int print_results_cache(const char *filename, int bm_pid, __u64 llc_value
return -1;
}
fprintf(fp, "Pid: %d \t llc_value: %llu\n", bm_pid, llc_value);
fprintf(fp, "Pid: %d \t llc_value: %llu\n", (int)bm_pid, llc_value);
fclose(fp);
}
......@@ -133,7 +133,7 @@ static int print_results_cache(const char *filename, int bm_pid, __u64 llc_value
* Return: =0 on success. <0 on failure.
*/
int perf_event_measure(int pe_fd, struct perf_event_read *pe_read,
const char *filename, int bm_pid)
const char *filename, pid_t bm_pid)
{
int ret;
......@@ -161,7 +161,7 @@ int perf_event_measure(int pe_fd, struct perf_event_read *pe_read,
*
* Return: =0 on success. <0 on failure.
*/
int measure_llc_resctrl(const char *filename, int bm_pid)
int measure_llc_resctrl(const char *filename, pid_t bm_pid)
{
unsigned long llc_occu_resc = 0;
int ret;
......
......@@ -158,7 +158,6 @@ static int cat_test(const struct resctrl_test *test,
struct resctrl_val_param *param,
size_t span, unsigned long current_mask)
{
char *resctrl_val = param->resctrl_val;
struct perf_event_read pe_read;
struct perf_event_attr pea;
cpu_set_t old_affinity;
......@@ -178,8 +177,7 @@ static int cat_test(const struct resctrl_test *test,
return ret;
/* Write benchmark to specified con_mon grp, mon_grp in resctrl FS*/
ret = write_bm_pid_to_resctrl(bm_pid, param->ctrlgrp, param->mongrp,
resctrl_val);
ret = write_bm_pid_to_resctrl(bm_pid, param->ctrlgrp, param->mongrp);
if (ret)
goto reset_affinity;
......@@ -272,7 +270,6 @@ static int cat_run_test(const struct resctrl_test *test, const struct user_param
start_mask = create_bit_mask(start, n);
struct resctrl_val_param param = {
.resctrl_val = CAT_STR,
.ctrlgrp = "c1",
.filename = RESULT_FILE_NAME,
.num_of_runs = 0,
......
......@@ -16,6 +16,17 @@
#define MAX_DIFF 2000000
#define MAX_DIFF_PERCENT 15
#define CON_MON_LCC_OCCUP_PATH \
"%s/%s/mon_data/mon_L3_%02d/llc_occupancy"
static int cmt_init(const struct resctrl_val_param *param, int domain_id)
{
sprintf(llc_occup_path, CON_MON_LCC_OCCUP_PATH, RESCTRL_PATH,
param->ctrlgrp, domain_id);
return 0;
}
static int cmt_setup(const struct resctrl_test *test,
const struct user_params *uparams,
struct resctrl_val_param *p)
......@@ -29,6 +40,13 @@ static int cmt_setup(const struct resctrl_test *test,
return 0;
}
static int cmt_measure(const struct user_params *uparams,
struct resctrl_val_param *param, pid_t bm_pid)
{
sleep(1);
return measure_llc_resctrl(param->filename, bm_pid);
}
static int show_results_info(unsigned long sum_llc_val, int no_of_bits,
unsigned long cache_span, unsigned long max_diff,
unsigned long max_diff_percent, unsigned long num_of_runs,
......@@ -126,13 +144,13 @@ static int cmt_run_test(const struct resctrl_test *test, const struct user_param
}
struct resctrl_val_param param = {
.resctrl_val = CMT_STR,
.ctrlgrp = "c1",
.mongrp = "m1",
.filename = RESULT_FILE_NAME,
.mask = ~(long_mask << n) & long_mask,
.num_of_runs = 0,
.init = cmt_init,
.setup = cmt_setup,
.measure = cmt_measure,
};
span = cache_portion_size(cache_total_size, param.mask, long_mask);
......
......@@ -17,6 +17,19 @@
#define ALLOCATION_MIN 10
#define ALLOCATION_STEP 10
static int mba_init(const struct resctrl_val_param *param, int domain_id)
{
int ret;
ret = initialize_mem_bw_imc();
if (ret)
return ret;
initialize_mem_bw_resctrl(param, domain_id);
return 0;
}
/*
* Change schemata percentage from 100 to 10%. Write schemata to specified
* con_mon grp, mon_grp in resctrl FS.
......@@ -51,6 +64,12 @@ static int mba_setup(const struct resctrl_test *test,
return 0;
}
static int mba_measure(const struct user_params *uparams,
struct resctrl_val_param *param, pid_t bm_pid)
{
return measure_mem_bw(uparams, param, bm_pid, "reads");
}
static bool show_mba_info(unsigned long *bw_imc, unsigned long *bw_resc)
{
int allocation, runs;
......@@ -145,12 +164,11 @@ static void mba_test_cleanup(void)
static int mba_run_test(const struct resctrl_test *test, const struct user_params *uparams)
{
struct resctrl_val_param param = {
.resctrl_val = MBA_STR,
.ctrlgrp = "c1",
.mongrp = "m1",
.filename = RESULT_FILE_NAME,
.bw_report = "reads",
.setup = mba_setup
.init = mba_init,
.setup = mba_setup,
.measure = mba_measure,
};
int ret;
......
......@@ -86,6 +86,19 @@ static int check_results(size_t span)
return ret;
}
static int mbm_init(const struct resctrl_val_param *param, int domain_id)
{
int ret;
ret = initialize_mem_bw_imc();
if (ret)
return ret;
initialize_mem_bw_resctrl(param, domain_id);
return 0;
}
static int mbm_setup(const struct resctrl_test *test,
const struct user_params *uparams,
struct resctrl_val_param *p)
......@@ -105,6 +118,12 @@ static int mbm_setup(const struct resctrl_test *test,
return ret;
}
static int mbm_measure(const struct user_params *uparams,
struct resctrl_val_param *param, pid_t bm_pid)
{
return measure_mem_bw(uparams, param, bm_pid, "reads");
}
static void mbm_test_cleanup(void)
{
remove(RESULT_FILE_NAME);
......@@ -113,12 +132,11 @@ static void mbm_test_cleanup(void)
static int mbm_run_test(const struct resctrl_test *test, const struct user_params *uparams)
{
struct resctrl_val_param param = {
.resctrl_val = MBM_STR,
.ctrlgrp = "c1",
.mongrp = "m1",
.filename = RESULT_FILE_NAME,
.bw_report = "reads",
.setup = mbm_setup
.init = mbm_init,
.setup = mbm_setup,
.measure = mbm_measure,
};
int ret;
......
......@@ -43,13 +43,6 @@
#define DEFAULT_SPAN (250 * MB)
#define PARENT_EXIT() \
do { \
kill(ppid, SIGKILL); \
umount_resctrlfs(); \
exit(EXIT_FAILURE); \
} while (0)
/*
* user_params: User supplied parameters
* @cpu: CPU number to which the benchmark will be bound to
......@@ -88,24 +81,27 @@ struct resctrl_test {
/*
* resctrl_val_param: resctrl test parameters
* @resctrl_val: Resctrl feature (Eg: mbm, mba.. etc)
* @ctrlgrp: Name of the control monitor group (con_mon grp)
* @mongrp: Name of the monitor group (mon grp)
* @filename: Name of file to which the o/p should be written
* @bw_report: Bandwidth report type (reads vs writes)
* @setup: Call back function to setup test environment
* @init: Callback function to initialize test environment
* @setup: Callback function to setup per test run environment
* @measure: Callback that performs the measurement (a single test)
*/
struct resctrl_val_param {
char *resctrl_val;
char ctrlgrp[64];
char mongrp[64];
const char *ctrlgrp;
const char *mongrp;
char filename[64];
char *bw_report;
unsigned long mask;
int num_of_runs;
int (*init)(const struct resctrl_val_param *param,
int domain_id);
int (*setup)(const struct resctrl_test *test,
const struct user_params *uparams,
struct resctrl_val_param *param);
int (*measure)(const struct user_params *uparams,
struct resctrl_val_param *param,
pid_t bm_pid);
};
struct perf_event_read {
......@@ -115,11 +111,6 @@ struct perf_event_read {
} values[2];
};
#define MBM_STR "mbm"
#define MBA_STR "mba"
#define CMT_STR "cmt"
#define CAT_STR "cat"
/*
* Memory location that consumes values compiler must not optimize away.
* Volatile ensures writes to this location cannot be optimized away by
......@@ -127,8 +118,6 @@ struct perf_event_read {
*/
extern volatile int *value_sink;
extern pid_t bm_pid, ppid;
extern char llc_occup_path[1024];
int get_vendor(void);
......@@ -137,7 +126,7 @@ int filter_dmesg(void);
int get_domain_id(const char *resource, int cpu_no, int *domain_id);
int mount_resctrlfs(void);
int umount_resctrlfs(void);
int validate_bw_report_request(char *bw_report);
const char *get_bw_report_type(const char *bw_report);
bool resctrl_resource_exists(const char *resource);
bool resctrl_mon_feature_exists(const char *resource, const char *feature);
bool resource_info_file_exists(const char *resource, const char *file);
......@@ -145,15 +134,21 @@ bool test_resource_feature_check(const struct resctrl_test *test);
char *fgrep(FILE *inf, const char *str);
int taskset_benchmark(pid_t bm_pid, int cpu_no, cpu_set_t *old_affinity);
int taskset_restore(pid_t bm_pid, cpu_set_t *old_affinity);
int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, const char *resource);
int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp,
char *resctrl_val);
int write_schemata(const char *ctrlgrp, char *schemata, int cpu_no,
const char *resource);
int write_bm_pid_to_resctrl(pid_t bm_pid, const char *ctrlgrp, const char *mongrp);
int perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu,
int group_fd, unsigned long flags);
unsigned char *alloc_buffer(size_t buf_size, int memflush);
void mem_flush(unsigned char *buf, size_t buf_size);
void fill_cache_read(unsigned char *buf, size_t buf_size, bool once);
int run_fill_buf(size_t buf_size, int memflush, int op, bool once);
int initialize_mem_bw_imc(void);
int measure_mem_bw(const struct user_params *uparams,
struct resctrl_val_param *param, pid_t bm_pid,
const char *bw_report);
void initialize_mem_bw_resctrl(const struct resctrl_val_param *param,
int domain_id);
int resctrl_val(const struct resctrl_test *test,
const struct user_params *uparams,
const char * const *benchmark_cmd,
......@@ -174,8 +169,8 @@ void perf_event_initialize_read_format(struct perf_event_read *pe_read);
int perf_open(struct perf_event_attr *pea, pid_t pid, int cpu_no);
int perf_event_reset_enable(int pe_fd);
int perf_event_measure(int pe_fd, struct perf_event_read *pe_read,
const char *filename, int bm_pid);
int measure_llc_resctrl(const char *filename, int bm_pid);
const char *filename, pid_t bm_pid);
int measure_llc_resctrl(const char *filename, pid_t bm_pid);
void show_cache_info(int no_of_bits, __u64 avg_llc_val, size_t cache_span, bool lines);
/*
......
......@@ -456,6 +456,9 @@ int taskset_restore(pid_t bm_pid, cpu_set_t *old_affinity)
* @grp: Full path and name of the group
* @parent_grp: Full path and name of the parent group
*
* Creates a group @grp_name if it does not exist yet. If @grp_name is NULL,
* it is interpreted as the root group which always results in success.
*
* Return: 0 on success, < 0 on error.
*/
static int create_grp(const char *grp_name, char *grp, const char *parent_grp)
......@@ -464,12 +467,7 @@ static int create_grp(const char *grp_name, char *grp, const char *parent_grp)
struct dirent *ep;
DIR *dp;
/*
* At this point, we are guaranteed to have resctrl FS mounted and if
* length of grp_name == 0, it means, user wants to use root con_mon
* grp, so do nothing
*/
if (strlen(grp_name) == 0)
if (!grp_name)
return 0;
/* Check if requested grp exists or not */
......@@ -508,7 +506,7 @@ static int write_pid_to_tasks(char *tasks, pid_t pid)
return -1;
}
if (fprintf(fp, "%d\n", pid) < 0) {
if (fprintf(fp, "%d\n", (int)pid) < 0) {
ksft_print_msg("Failed to write pid to tasks file\n");
fclose(fp);
......@@ -524,7 +522,6 @@ static int write_pid_to_tasks(char *tasks, pid_t pid)
* @bm_pid: PID that should be written
* @ctrlgrp: Name of the control monitor group (con_mon grp)
* @mongrp: Name of the monitor group (mon grp)
* @resctrl_val: Resctrl feature (Eg: mbm, mba.. etc)
*
* If a con_mon grp is requested, create it and write pid to it, otherwise
* write pid to root con_mon grp.
......@@ -534,14 +531,13 @@ static int write_pid_to_tasks(char *tasks, pid_t pid)
*
* Return: 0 on success, < 0 on error.
*/
int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp,
char *resctrl_val)
int write_bm_pid_to_resctrl(pid_t bm_pid, const char *ctrlgrp, const char *mongrp)
{
char controlgroup[128], monitorgroup[512], monitorgroup_p[256];
char tasks[1024];
int ret = 0;
if (strlen(ctrlgrp))
if (ctrlgrp)
sprintf(controlgroup, "%s/%s", RESCTRL_PATH, ctrlgrp);
else
sprintf(controlgroup, "%s", RESCTRL_PATH);
......@@ -555,22 +551,19 @@ int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp,
if (ret)
goto out;
/* Create mon grp and write pid into it for "mbm" and "cmt" test */
if (!strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR)) ||
!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR))) {
if (strlen(mongrp)) {
sprintf(monitorgroup_p, "%s/mon_groups", controlgroup);
sprintf(monitorgroup, "%s/%s", monitorgroup_p, mongrp);
ret = create_grp(mongrp, monitorgroup, monitorgroup_p);
if (ret)
goto out;
sprintf(tasks, "%s/mon_groups/%s/tasks",
controlgroup, mongrp);
ret = write_pid_to_tasks(tasks, bm_pid);
if (ret)
goto out;
}
/* Create monitor group and write pid into if it is used */
if (mongrp) {
sprintf(monitorgroup_p, "%s/mon_groups", controlgroup);
sprintf(monitorgroup, "%s/%s", monitorgroup_p, mongrp);
ret = create_grp(mongrp, monitorgroup, monitorgroup_p);
if (ret)
goto out;
sprintf(tasks, "%s/mon_groups/%s/tasks",
controlgroup, mongrp);
ret = write_pid_to_tasks(tasks, bm_pid);
if (ret)
goto out;
}
out:
......@@ -593,7 +586,8 @@ int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp,
*
* Return: 0 on success, < 0 on error.
*/
int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, const char *resource)
int write_schemata(const char *ctrlgrp, char *schemata, int cpu_no,
const char *resource)
{
char controlgroup[1024], reason[128], schema[1024] = {};
int domain_id, fd, schema_len, ret = 0;
......@@ -611,7 +605,7 @@ int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, const char *resour
goto out;
}
if (strlen(ctrlgrp) != 0)
if (ctrlgrp)
sprintf(controlgroup, "%s/%s/schemata", RESCTRL_PATH, ctrlgrp);
else
sprintf(controlgroup, "%s/schemata", RESCTRL_PATH);
......@@ -837,22 +831,21 @@ int filter_dmesg(void)
return 0;
}
int validate_bw_report_request(char *bw_report)
const char *get_bw_report_type(const char *bw_report)
{
if (strcmp(bw_report, "reads") == 0)
return 0;
return bw_report;
if (strcmp(bw_report, "writes") == 0)
return 0;
return bw_report;
if (strcmp(bw_report, "nt-writes") == 0) {
strcpy(bw_report, "writes");
return 0;
return "writes";
}
if (strcmp(bw_report, "total") == 0)
return 0;
return bw_report;
fprintf(stderr, "Requested iMC B/W report type unavailable\n");
fprintf(stderr, "Requested iMC bandwidth report type unavailable\n");
return -1;
return NULL;
}
int perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu,
......
......@@ -42,11 +42,11 @@ static pid_t gettid(void)
#ifndef PR_SCHED_CORE
#define PR_SCHED_CORE 62
# define PR_SCHED_CORE_GET 0
# define PR_SCHED_CORE_CREATE 1 /* create unique core_sched cookie */
# define PR_SCHED_CORE_SHARE_TO 2 /* push core_sched cookie to pid */
# define PR_SCHED_CORE_SHARE_FROM 3 /* pull core_sched cookie to pid */
# define PR_SCHED_CORE_MAX 4
#define PR_SCHED_CORE_GET 0
#define PR_SCHED_CORE_CREATE 1 /* create unique core_sched cookie */
#define PR_SCHED_CORE_SHARE_TO 2 /* push core_sched cookie to pid */
#define PR_SCHED_CORE_SHARE_FROM 3 /* pull core_sched cookie to pid */
#define PR_SCHED_CORE_MAX 4
#endif
#define MAX_PROCESSES 128
......
......@@ -29,7 +29,7 @@ static const char default_rtc[] = "/dev/rtc0";
int main(int argc, char **argv)
{
int i, fd, retval, irqcount = 0;
int i, fd, retval;
unsigned long tmp, data, old_pie_rate;
const char *rtc = default_rtc;
struct timeval start, end, diff;
......@@ -120,7 +120,6 @@ int main(int argc, char **argv)
fprintf(stderr, " %d",i);
fflush(stderr);
irqcount++;
}
/* Disable periodic interrupts */
......
......@@ -40,6 +40,13 @@ CFLAGS := -O2 -g -std=gnu99 -pthread -Wall $(KHDR_INCLUDES)
# call32_from_64 in thunks.S uses absolute addresses.
ifeq ($(CAN_BUILD_WITH_NOPIE),1)
CFLAGS += -no-pie
ifneq ($(LLVM),)
# clang only wants to see -no-pie during linking. Here, we don't have a separate
# linking stage, so a compiler warning is unavoidable without (wastefully)
# restructuring the Makefile. Avoid this by simply disabling that warning.
CFLAGS += -Wno-unused-command-line-argument
endif
endif
define gen-target-rule-32
......@@ -73,10 +80,10 @@ all_64: $(BINARIES_64)
EXTRA_CLEAN := $(BINARIES_32) $(BINARIES_64)
$(BINARIES_32): $(OUTPUT)/%_32: %.c helpers.h
$(CC) -m32 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl -lm
$(CC) -m32 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $< $(EXTRA_FILES) -lrt -ldl -lm
$(BINARIES_64): $(OUTPUT)/%_64: %.c helpers.h
$(CC) -m64 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl
$(CC) -m64 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $< $(EXTRA_FILES) -lrt -ldl
# x86_64 users should be encouraged to install 32-bit libraries
ifeq ($(CAN_BUILD_I386)$(CAN_BUILD_X86_64),01)
......@@ -100,10 +107,22 @@ warn_32bit_failure:
exit 0;
endif
# Some tests have additional dependencies.
$(OUTPUT)/sysret_ss_attrs_64: thunks.S
$(OUTPUT)/ptrace_syscall_32: raw_syscall_helper_32.S
$(OUTPUT)/test_syscall_vdso_32: thunks_32.S
# Add an additional file to the source file list for a given target, and also
# add a Makefile dependency on that same file. However, do these separately, so
# that the compiler invocation ("$(CC) file1.c file2.S") is not combined with
# the dependencies ("header3.h"), because clang, unlike gcc, will not accept
# header files as an input to the compiler invocation.
define extra-files
$(OUTPUT)/$(1): EXTRA_FILES := $(2)
$(OUTPUT)/$(1): $(2)
endef
$(eval $(call extra-files,sysret_ss_attrs_64,thunks.S))
$(eval $(call extra-files,ptrace_syscall_32,raw_syscall_helper_32.S))
$(eval $(call extra-files,test_syscall_vdso_32,thunks_32.S))
$(eval $(call extra-files,fsgsbase_restore_64,clang_helpers_64.S))
$(eval $(call extra-files,fsgsbase_restore_32,clang_helpers_32.S))
$(eval $(call extra-files,sysret_rip_64,clang_helpers_64.S))
# check_initial_reg_state is special: it needs a custom entry, and it
# needs to be static so that its interpreter doesn't destroy its initial
......
......@@ -39,16 +39,6 @@ struct xsave_buffer {
};
};
static inline uint64_t xgetbv(uint32_t index)
{
uint32_t eax, edx;
asm volatile("xgetbv;"
: "=a" (eax), "=d" (edx)
: "c" (index));
return eax + ((uint64_t)edx << 32);
}
static inline void xsave(struct xsave_buffer *xbuf, uint64_t rfbm)
{
uint32_t rfbm_lo = rfbm;
......@@ -164,12 +154,6 @@ static inline void clear_xstate_header(struct xsave_buffer *buffer)
memset(&buffer->header, 0, sizeof(buffer->header));
}
static inline uint64_t get_xstatebv(struct xsave_buffer *buffer)
{
/* XSTATE_BV is at the beginning of the header: */
return *(uint64_t *)&buffer->header;
}
static inline void set_xstatebv(struct xsave_buffer *buffer, uint64_t bv)
{
/* XSTATE_BV is at the beginning of the header: */
......
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* 32-bit assembly helpers for asm operations that lack support in both gcc and
* clang. For example, clang asm does not support segment prefixes.
*/
.global dereference_seg_base
dereference_seg_base:
mov %fs:(0), %eax
ret
.section .note.GNU-stack,"",%progbits
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* 64-bit assembly helpers for asm operations that lack support in both gcc and
* clang. For example, clang asm does not support segment prefixes.
*/
.global dereference_seg_base
dereference_seg_base:
mov %gs:(0), %rax
ret
.global test_page
.global test_syscall_insn
.pushsection ".text", "ax"
.balign 4096
test_page: .globl test_page
.fill 4094,1,0xcc
test_syscall_insn:
syscall
.ifne . - test_page - 4096
.error "test page is not one page long"
.endif
.popsection
.section .note.GNU-stack,"",%progbits
......@@ -109,11 +109,6 @@ static inline void wrgsbase(unsigned long gsbase)
asm volatile("wrgsbase %0" :: "r" (gsbase) : "memory");
}
static inline void wrfsbase(unsigned long fsbase)
{
asm volatile("wrfsbase %0" :: "r" (fsbase) : "memory");
}
enum which_base { FS, GS };
static unsigned long read_base(enum which_base which)
......@@ -212,7 +207,6 @@ static void mov_0_gs(unsigned long initial_base, bool schedule)
}
static volatile unsigned long remote_base;
static volatile bool remote_hard_zero;
static volatile unsigned int ftx;
/*
......
......@@ -39,12 +39,11 @@
# define SEG "%fs"
#endif
static unsigned int dereference_seg_base(void)
{
int ret;
asm volatile ("mov %" SEG ":(0), %0" : "=rm" (ret));
return ret;
}
/*
* Defined in clang_helpers_[32|64].S, because unlike gcc, clang inline asm does
* not support segmentation prefixes.
*/
unsigned int dereference_seg_base(void);
static void init_seg(void)
{
......
......@@ -487,7 +487,7 @@ static void sigtrap(int sig, siginfo_t *info, void *ctx_void)
greg_t asm_ss = ctx->uc_mcontext.gregs[REG_CX];
if (asm_ss != sig_ss && sig == SIGTRAP) {
/* Sanity check failure. */
printf("[FAIL]\tSIGTRAP: ss = %hx, frame ss = %hx, ax = %llx\n",
printf("[FAIL]\tSIGTRAP: ss = %hx, frame ss = %x, ax = %llx\n",
ss, *ssptr(ctx), (unsigned long long)asm_ss);
nerrs++;
}
......
......@@ -29,7 +29,6 @@ static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
err(1, "sigaction");
}
static volatile sig_atomic_t sig_traps;
static sigjmp_buf jmpbuf;
static volatile sig_atomic_t n_errs;
......
......@@ -22,21 +22,13 @@
#include <sys/mman.h>
#include <assert.h>
asm (
".pushsection \".text\", \"ax\"\n\t"
".balign 4096\n\t"
"test_page: .globl test_page\n\t"
".fill 4094,1,0xcc\n\t"
"test_syscall_insn:\n\t"
"syscall\n\t"
".ifne . - test_page - 4096\n\t"
".error \"test page is not one page long\"\n\t"
".endif\n\t"
".popsection"
);
/*
* These items are in clang_helpers_64.S, in order to avoid clang inline asm
* limitations:
*/
void test_syscall_ins(void);
extern const char test_page[];
static void const *current_test_page_addr = test_page;
static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
......
......@@ -25,7 +25,7 @@ int test(void)
feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
asm volatile ("\n"
" fld1""\n"
" fisttp res16""\n"
" fisttps res16""\n"
" fld1""\n"
" fisttpl res32""\n"
" fld1""\n"
......@@ -45,7 +45,7 @@ int test(void)
feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
asm volatile ("\n"
" fldpi""\n"
" fisttp res16""\n"
" fisttps res16""\n"
" fldpi""\n"
" fisttpl res32""\n"
" fldpi""\n"
......@@ -66,7 +66,7 @@ int test(void)
asm volatile ("\n"
" fldpi""\n"
" fchs""\n"
" fisttp res16""\n"
" fisttps res16""\n"
" fldpi""\n"
" fchs""\n"
" fisttpl res32""\n"
......@@ -88,7 +88,7 @@ int test(void)
feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
asm volatile ("\n"
" fldln2""\n"
" fisttp res16""\n"
" fisttps res16""\n"
" fldln2""\n"
" fisttpl res32""\n"
" fldln2""\n"
......
......@@ -97,11 +97,6 @@ static inline long sys_gtod(struct timeval *tv, struct timezone *tz)
return syscall(SYS_gettimeofday, tv, tz);
}
static inline int sys_clock_gettime(clockid_t id, struct timespec *ts)
{
return syscall(SYS_clock_gettime, id, ts);
}
static inline long sys_time(time_t *t)
{
return syscall(SYS_time, t);
......@@ -252,7 +247,7 @@ static void test_getcpu(int cpu)
if (ret_sys == 0) {
if (cpu_sys != cpu)
ksft_print_msg("syscall reported CPU %hu but should be %d\n",
ksft_print_msg("syscall reported CPU %u but should be %d\n",
cpu_sys, cpu);
have_node = true;
......@@ -270,10 +265,10 @@ static void test_getcpu(int cpu)
if (cpu_vdso != cpu || node_vdso != node) {
if (cpu_vdso != cpu)
ksft_print_msg("vDSO reported CPU %hu but should be %d\n",
ksft_print_msg("vDSO reported CPU %u but should be %d\n",
cpu_vdso, cpu);
if (node_vdso != node)
ksft_print_msg("vDSO reported node %hu but should be %hu\n",
ksft_print_msg("vDSO reported node %u but should be %u\n",
node_vdso, node);
ksft_test_result_fail("Wrong values\n");
} else {
......@@ -295,10 +290,10 @@ static void test_getcpu(int cpu)
if (cpu_vsys != cpu || node_vsys != node) {
if (cpu_vsys != cpu)
ksft_print_msg("vsyscall reported CPU %hu but should be %d\n",
ksft_print_msg("vsyscall reported CPU %u but should be %d\n",
cpu_vsys, cpu);
if (node_vsys != node)
ksft_print_msg("vsyscall reported node %hu but should be %hu\n",
ksft_print_msg("vsyscall reported node %u but should be %u\n",
node_vsys, node);
ksft_test_result_fail("Wrong values\n");
} else {
......
......@@ -92,4 +92,6 @@ int main()
printf("[FAIL]\t!SA_SIGINFO handler was not called\n");
nerrs++;
}
return nerrs;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment