summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/power/cpupower/utils/cpufreq-set.c3
-rw-r--r--tools/power/cpupower/utils/cpuidle-set.c4
-rw-r--r--tools/power/cpupower/utils/cpupower.c8
-rw-r--r--tools/power/cpupower/utils/helpers/helpers.h12
-rw-r--r--tools/power/cpupower/utils/helpers/misc.c64
-rw-r--r--tools/power/pm-graph/README4
-rwxr-xr-xtools/power/pm-graph/sleepgraph.py387
-rw-r--r--tools/power/x86/intel-speed-select/isst-config.c8
-rw-r--r--tools/power/x86/intel-speed-select/isst-core.c2
-rw-r--r--tools/power/x86/intel-speed-select/isst.h1
-rw-r--r--tools/testing/kunit/kunit_kernel.py24
-rw-r--r--tools/testing/kunit/kunit_parser.py7
-rw-r--r--tools/testing/scatterlist/main.c64
-rw-r--r--tools/testing/selftests/Makefile1
-rw-r--r--tools/testing/selftests/cgroup/cgroup_util.c4
-rw-r--r--tools/testing/selftests/clone3/Makefile2
-rw-r--r--tools/testing/selftests/core/close_range_test.c74
-rw-r--r--tools/testing/selftests/gpio/Makefile25
-rw-r--r--tools/testing/selftests/intel_pstate/aperf.c22
-rw-r--r--tools/testing/selftests/lkdtm/tests.txt2
-rw-r--r--tools/testing/selftests/memfd/fuse_test.c2
-rw-r--r--tools/testing/selftests/memfd/memfd_test.c2
-rwxr-xr-xtools/testing/selftests/net/mptcp/simult_flows.sh6
-rw-r--r--tools/testing/selftests/openat2/openat2_test.c8
-rw-r--r--tools/testing/selftests/powerpc/eeh/Makefile2
-rw-r--r--tools/testing/selftests/powerpc/eeh/settings1
-rw-r--r--tools/testing/selftests/powerpc/mm/bad_accesses.c2
-rw-r--r--tools/testing/selftests/powerpc/nx-gzip/.gitignore3
-rw-r--r--tools/testing/selftests/powerpc/security/.gitignore1
-rw-r--r--tools/testing/selftests/powerpc/signal/.gitignore1
-rw-r--r--tools/testing/selftests/powerpc/syscalls/.gitignore1
-rw-r--r--tools/testing/selftests/rseq/param_test.c4
-rwxr-xr-xtools/testing/selftests/run_kselftest.sh2
-rw-r--r--tools/testing/selftests/seccomp/config1
-rw-r--r--tools/testing/selftests/seccomp/seccomp_benchmark.c151
-rw-r--r--tools/testing/selftests/seccomp/settings2
-rw-r--r--tools/testing/selftests/vDSO/Makefile16
-rw-r--r--tools/testing/selftests/vDSO/vdso_config.h92
-rw-r--r--tools/testing/selftests/vDSO/vdso_test_abi.c244
-rw-r--r--tools/testing/selftests/vDSO/vdso_test_clock_getres.c124
-rw-r--r--tools/testing/selftests/vDSO/vdso_test_correctness.c (renamed from tools/testing/selftests/x86/test_vdso.c)115
-rw-r--r--tools/testing/selftests/vm/userfaultfd.c4
-rw-r--r--tools/testing/selftests/x86/Makefile2
43 files changed, 1228 insertions, 276 deletions
diff --git a/tools/power/cpupower/utils/cpufreq-set.c b/tools/power/cpupower/utils/cpufreq-set.c
index 7b2164e07057..c5e60a39cfa6 100644
--- a/tools/power/cpupower/utils/cpufreq-set.c
+++ b/tools/power/cpupower/utils/cpufreq-set.c
@@ -315,6 +315,7 @@ int cmd_freq_set(int argc, char **argv)
}
}
+ get_cpustate();
/* loop over CPUs */
for (cpu = bitmask_first(cpus_chosen);
@@ -332,5 +333,7 @@ int cmd_freq_set(int argc, char **argv)
}
}
+ print_offline_cpus();
+
return 0;
}
diff --git a/tools/power/cpupower/utils/cpuidle-set.c b/tools/power/cpupower/utils/cpuidle-set.c
index 569f268f4c7f..46158928f9ad 100644
--- a/tools/power/cpupower/utils/cpuidle-set.c
+++ b/tools/power/cpupower/utils/cpuidle-set.c
@@ -95,6 +95,8 @@ int cmd_idle_set(int argc, char **argv)
exit(EXIT_FAILURE);
}
+ get_cpustate();
+
/* Default is: set all CPUs */
if (bitmask_isallclear(cpus_chosen))
bitmask_setall(cpus_chosen);
@@ -181,5 +183,7 @@ int cmd_idle_set(int argc, char **argv)
break;
}
}
+
+ print_offline_cpus();
return EXIT_SUCCESS;
}
diff --git a/tools/power/cpupower/utils/cpupower.c b/tools/power/cpupower/utils/cpupower.c
index 8e3d08042825..8ac3304a9957 100644
--- a/tools/power/cpupower/utils/cpupower.c
+++ b/tools/power/cpupower/utils/cpupower.c
@@ -34,6 +34,8 @@ int run_as_root;
int base_cpu;
/* Affected cpus chosen by -c/--cpu param */
struct bitmask *cpus_chosen;
+struct bitmask *online_cpus;
+struct bitmask *offline_cpus;
#ifdef DEBUG
int be_verbose;
@@ -178,6 +180,8 @@ int main(int argc, const char *argv[])
char pathname[32];
cpus_chosen = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF));
+ online_cpus = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF));
+ offline_cpus = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF));
argc--;
argv += 1;
@@ -230,6 +234,10 @@ int main(int argc, const char *argv[])
ret = p->main(argc, argv);
if (cpus_chosen)
bitmask_free(cpus_chosen);
+ if (online_cpus)
+ bitmask_free(online_cpus);
+ if (offline_cpus)
+ bitmask_free(offline_cpus);
return ret;
}
print_help();
diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h
index 37dac161f3fe..0642e60a6ce1 100644
--- a/tools/power/cpupower/utils/helpers/helpers.h
+++ b/tools/power/cpupower/utils/helpers/helpers.h
@@ -94,6 +94,8 @@ struct cpupower_cpu_info {
*/
extern int get_cpu_info(struct cpupower_cpu_info *cpu_info);
extern struct cpupower_cpu_info cpupower_cpu_info;
+
+
/* cpuid and cpuinfo helpers **************************/
/* X86 ONLY ****************************************/
@@ -171,4 +173,14 @@ static inline unsigned int cpuid_ecx(unsigned int op) { return 0; };
static inline unsigned int cpuid_edx(unsigned int op) { return 0; };
#endif /* defined(__i386__) || defined(__x86_64__) */
+/*
+ * CPU State related functions
+ */
+extern struct bitmask *online_cpus;
+extern struct bitmask *offline_cpus;
+
+void get_cpustate(void);
+void print_online_cpus(void);
+void print_offline_cpus(void);
+
#endif /* __CPUPOWERUTILS_HELPERS__ */
diff --git a/tools/power/cpupower/utils/helpers/misc.c b/tools/power/cpupower/utils/helpers/misc.c
index e8f8f643a627..650b9a9a6584 100644
--- a/tools/power/cpupower/utils/helpers/misc.c
+++ b/tools/power/cpupower/utils/helpers/misc.c
@@ -4,11 +4,11 @@
#include <errno.h>
#include <stdlib.h>
-#if defined(__i386__) || defined(__x86_64__)
-
#include "helpers/helpers.h"
#include "helpers/sysfs.h"
+#if defined(__i386__) || defined(__x86_64__)
+
#include "cpupower_intern.h"
#define MSR_AMD_HWCR 0xc0010015
@@ -89,3 +89,63 @@ int cpupower_intel_set_perf_bias(unsigned int cpu, unsigned int val)
}
#endif /* #if defined(__i386__) || defined(__x86_64__) */
+
+/* get_cpustate
+ *
+ * Gather the information of all online CPUs into bitmask struct
+ */
+void get_cpustate(void)
+{
+ unsigned int cpu = 0;
+
+ bitmask_clearall(online_cpus);
+ bitmask_clearall(offline_cpus);
+
+ for (cpu = bitmask_first(cpus_chosen);
+ cpu <= bitmask_last(cpus_chosen); cpu++) {
+
+ if (cpupower_is_cpu_online(cpu) == 1)
+ bitmask_setbit(online_cpus, cpu);
+ else
+ bitmask_setbit(offline_cpus, cpu);
+
+ continue;
+ }
+}
+
+/* print_online_cpus
+ *
+ * Print the CPU numbers of all CPUs that are online currently
+ */
+void print_online_cpus(void)
+{
+ int str_len = 0;
+ char *online_cpus_str = NULL;
+
+ str_len = online_cpus->size * 5;
+ online_cpus_str = (void *)malloc(sizeof(char) * str_len);
+
+ if (!bitmask_isallclear(online_cpus)) {
+ bitmask_displaylist(online_cpus_str, str_len, online_cpus);
+ printf(_("Following CPUs are online:\n%s\n"), online_cpus_str);
+ }
+}
+
+/* print_offline_cpus
+ *
+ * Print the CPU numbers of all CPUs that are offline currently
+ */
+void print_offline_cpus(void)
+{
+ int str_len = 0;
+ char *offline_cpus_str = NULL;
+
+ str_len = offline_cpus->size * 5;
+ offline_cpus_str = (void *)malloc(sizeof(char) * str_len);
+
+ if (!bitmask_isallclear(offline_cpus)) {
+ bitmask_displaylist(offline_cpus_str, str_len, offline_cpus);
+ printf(_("Following CPUs are offline:\n%s\n"), offline_cpus_str);
+ printf(_("cpupower set operation was not performed on them\n"));
+ }
+}
diff --git a/tools/power/pm-graph/README b/tools/power/pm-graph/README
index 89d0a7dab4bc..da468bd510ca 100644
--- a/tools/power/pm-graph/README
+++ b/tools/power/pm-graph/README
@@ -6,7 +6,7 @@
|_| |___/ |_|
pm-graph: suspend/resume/boot timing analysis tools
- Version: 5.7
+ Version: 5.8
Author: Todd Brandt <todd.e.brandt@intel.com>
Home Page: https://01.org/pm-graph
@@ -61,7 +61,7 @@
- runs with python2 or python3, choice is made by /usr/bin/python link
- python
- python-configparser (for python2 sleepgraph)
- - python-requests (for googlesheet.py)
+ - python-requests (for stresstester.py)
- linux-tools-common (for turbostat usage in sleepgraph)
Ubuntu:
diff --git a/tools/power/pm-graph/sleepgraph.py b/tools/power/pm-graph/sleepgraph.py
index 1bc36a1db14f..81f4b8abbdf7 100755
--- a/tools/power/pm-graph/sleepgraph.py
+++ b/tools/power/pm-graph/sleepgraph.py
@@ -81,7 +81,7 @@ def ascii(text):
# store system values and test parameters
class SystemValues:
title = 'SleepGraph'
- version = '5.7'
+ version = '5.8'
ansi = False
rs = 0
display = ''
@@ -92,8 +92,9 @@ class SystemValues:
testlog = True
dmesglog = True
ftracelog = False
+ acpidebug = True
tstat = True
- mindevlen = 0.0
+ mindevlen = 0.0001
mincglen = 0.0
cgphase = ''
cgtest = -1
@@ -115,6 +116,7 @@ class SystemValues:
fpdtpath = '/sys/firmware/acpi/tables/FPDT'
epath = '/sys/kernel/debug/tracing/events/power/'
pmdpath = '/sys/power/pm_debug_messages'
+ acpipath='/sys/module/acpi/parameters/debug_level'
traceevents = [
'suspend_resume',
'wakeup_source_activate',
@@ -162,16 +164,16 @@ class SystemValues:
devdump = False
mixedphaseheight = True
devprops = dict()
+ cfgdef = dict()
platinfo = []
predelay = 0
postdelay = 0
- pmdebug = ''
tmstart = 'SUSPEND START %Y%m%d-%H:%M:%S.%f'
tmend = 'RESUME COMPLETE %Y%m%d-%H:%M:%S.%f'
tracefuncs = {
'sys_sync': {},
'ksys_sync': {},
- 'pm_notifier_call_chain_robust': {},
+ '__pm_notifier_call_chain': {},
'pm_prepare_console': {},
'pm_notifier_call_chain': {},
'freeze_processes': {},
@@ -490,9 +492,9 @@ class SystemValues:
call('echo 0 > %s/wakealarm' % self.rtcpath, shell=True)
def initdmesg(self):
# get the latest time stamp from the dmesg log
- fp = Popen('dmesg', stdout=PIPE).stdout
+ lines = Popen('dmesg', stdout=PIPE).stdout.readlines()
ktime = '0'
- for line in fp:
+ for line in reversed(lines):
line = ascii(line).replace('\r\n', '')
idx = line.find('[')
if idx > 1:
@@ -500,7 +502,7 @@ class SystemValues:
m = re.match('[ \t]*(\[ *)(?P<ktime>[0-9\.]*)(\]) (?P<msg>.*)', line)
if(m):
ktime = m.group('ktime')
- fp.close()
+ break
self.dmesgstart = float(ktime)
def getdmesg(self, testdata):
op = self.writeDatafileHeader(self.dmesgfile, testdata)
@@ -715,8 +717,6 @@ class SystemValues:
self.fsetVal('0', 'events/kprobes/enable')
self.fsetVal('', 'kprobe_events')
self.fsetVal('1024', 'buffer_size_kb')
- if self.pmdebug:
- self.setVal(self.pmdebug, self.pmdpath)
def setupAllKprobes(self):
for name in self.tracefuncs:
self.defaultKprobe(name, self.tracefuncs[name])
@@ -740,11 +740,7 @@ class SystemValues:
# turn trace off
self.fsetVal('0', 'tracing_on')
self.cleanupFtrace()
- # pm debug messages
- pv = self.getVal(self.pmdpath)
- if pv != '1':
- self.setVal('1', self.pmdpath)
- self.pmdebug = pv
+ self.testVal(self.pmdpath, 'basic', '1')
# set the trace clock to global
self.fsetVal('global', 'trace_clock')
self.fsetVal('nop', 'current_tracer')
@@ -900,6 +896,14 @@ class SystemValues:
if isgz:
return gzip.open(filename, mode+'t')
return open(filename, mode)
+ def putlog(self, filename, text):
+ with self.openlog(filename, 'a') as fp:
+ fp.write(text)
+ fp.close()
+ def dlog(self, text):
+ self.putlog(self.dmesgfile, '# %s\n' % text)
+ def flog(self, text):
+ self.putlog(self.ftracefile, text)
def b64unzip(self, data):
try:
out = codecs.decode(base64.b64decode(data), 'zlib').decode()
@@ -992,9 +996,7 @@ class SystemValues:
# add a line for each of these commands with their outputs
for name, cmdline, info in cmdafter:
footer += '# platform-%s: %s | %s\n' % (name, cmdline, self.b64zip(info))
-
- with self.openlog(self.ftracefile, 'a') as fp:
- fp.write(footer)
+ self.flog(footer)
return True
def commonPrefix(self, list):
if len(list) < 2:
@@ -1034,6 +1036,7 @@ class SystemValues:
cmdline, cmdpath = ' '.join(cargs[2:]), self.getExec(cargs[2])
if not cmdpath or (begin and not delta):
continue
+ self.dlog('[%s]' % cmdline)
try:
fp = Popen([cmdpath]+cargs[3:], stdout=PIPE, stderr=PIPE).stdout
info = ascii(fp.read()).strip()
@@ -1060,6 +1063,29 @@ class SystemValues:
else:
out.append((name, cmdline, '\tnothing' if not info else info))
return out
+ def testVal(self, file, fmt='basic', value=''):
+ if file == 'restoreall':
+ for f in self.cfgdef:
+ if os.path.exists(f):
+ fp = open(f, 'w')
+ fp.write(self.cfgdef[f])
+ fp.close()
+ self.cfgdef = dict()
+ elif value and os.path.exists(file):
+ fp = open(file, 'r+')
+ if fmt == 'radio':
+ m = re.match('.*\[(?P<v>.*)\].*', fp.read())
+ if m:
+ self.cfgdef[file] = m.group('v')
+ elif fmt == 'acpi':
+ line = fp.read().strip().split('\n')[-1]
+ m = re.match('.* (?P<v>[0-9A-Fx]*) .*', line)
+ if m:
+ self.cfgdef[file] = m.group('v')
+ else:
+ self.cfgdef[file] = fp.read().strip()
+ fp.write(value)
+ fp.close()
def haveTurbostat(self):
if not self.tstat:
return False
@@ -1201,6 +1227,57 @@ class SystemValues:
self.multitest[sz] *= 1440
elif unit == 'h':
self.multitest[sz] *= 60
+ def displayControl(self, cmd):
+ xset, ret = 'timeout 10 xset -d :0.0 {0}', 0
+ if self.sudouser:
+ xset = 'sudo -u %s %s' % (self.sudouser, xset)
+ if cmd == 'init':
+ ret = call(xset.format('dpms 0 0 0'), shell=True)
+ if not ret:
+ ret = call(xset.format('s off'), shell=True)
+ elif cmd == 'reset':
+ ret = call(xset.format('s reset'), shell=True)
+ elif cmd in ['on', 'off', 'standby', 'suspend']:
+ b4 = self.displayControl('stat')
+ ret = call(xset.format('dpms force %s' % cmd), shell=True)
+ if not ret:
+ curr = self.displayControl('stat')
+ self.vprint('Display Switched: %s -> %s' % (b4, curr))
+ if curr != cmd:
+ self.vprint('WARNING: Display failed to change to %s' % cmd)
+ if ret:
+ self.vprint('WARNING: Display failed to change to %s with xset' % cmd)
+ return ret
+ elif cmd == 'stat':
+ fp = Popen(xset.format('q').split(' '), stdout=PIPE).stdout
+ ret = 'unknown'
+ for line in fp:
+ m = re.match('[\s]*Monitor is (?P<m>.*)', ascii(line))
+ if(m and len(m.group('m')) >= 2):
+ out = m.group('m').lower()
+ ret = out[3:] if out[0:2] == 'in' else out
+ break
+ fp.close()
+ return ret
+ def setRuntimeSuspend(self, before=True):
+ if before:
+ # runtime suspend disable or enable
+ if self.rs > 0:
+ self.rstgt, self.rsval, self.rsdir = 'on', 'auto', 'enabled'
+ else:
+ self.rstgt, self.rsval, self.rsdir = 'auto', 'on', 'disabled'
+ pprint('CONFIGURING RUNTIME SUSPEND...')
+ self.rslist = deviceInfo(self.rstgt)
+ for i in self.rslist:
+ self.setVal(self.rsval, i)
+ pprint('runtime suspend %s on all devices (%d changed)' % (self.rsdir, len(self.rslist)))
+ pprint('waiting 5 seconds...')
+ time.sleep(5)
+ else:
+ # runtime suspend re-enable or re-disable
+ for i in self.rslist:
+ self.setVal(self.rstgt, i)
+ pprint('runtime suspend settings restored on %d devices' % len(self.rslist))
sysvals = SystemValues()
switchvalues = ['enable', 'disable', 'on', 'off', 'true', 'false', '1', '0']
@@ -1640,15 +1717,20 @@ class Data:
if 'resume_machine' in phase and 'suspend_machine' in lp:
tS, tR = self.dmesg[lp]['end'], self.dmesg[phase]['start']
tL = tR - tS
- if tL > 0:
- left = True if tR > tZero else False
- self.trimTime(tS, tL, left)
- if 'trying' in self.dmesg[lp] and self.dmesg[lp]['trying'] >= 0.001:
- tTry = round(self.dmesg[lp]['trying'] * 1000)
- text = '%.0f (-%.0f waking)' % (tL * 1000, tTry)
+ if tL <= 0:
+ continue
+ left = True if tR > tZero else False
+ self.trimTime(tS, tL, left)
+ if 'waking' in self.dmesg[lp]:
+ tCnt = self.dmesg[lp]['waking'][0]
+ if self.dmesg[lp]['waking'][1] >= 0.001:
+ tTry = '-%.0f' % (round(self.dmesg[lp]['waking'][1] * 1000))
else:
- text = '%.0f' % (tL * 1000)
- self.tLow.append(text)
+ tTry = '-%.3f' % (self.dmesg[lp]['waking'][1] * 1000)
+ text = '%.0f (%s ms waking %d times)' % (tL * 1000, tTry, tCnt)
+ else:
+ text = '%.0f' % (tL * 1000)
+ self.tLow.append(text)
lp = phase
def getMemTime(self):
if not self.hwstart or not self.hwend:
@@ -1921,7 +2003,7 @@ class Data:
for dev in list:
length = (list[dev]['end'] - list[dev]['start']) * 1000
width = widfmt % (((list[dev]['end']-list[dev]['start'])*100)/tTotal)
- if width != '0.000000' and length >= mindevlen:
+ if length >= mindevlen:
devlist.append(dev)
self.tdevlist[phase] = devlist
def addHorizontalDivider(self, devname, devend):
@@ -3316,9 +3398,10 @@ def parseTraceLog(live=False):
# trim out s2idle loops, track time trying to freeze
llp = data.lastPhase(2)
if llp.startswith('suspend_machine'):
- if 'trying' not in data.dmesg[llp]:
- data.dmesg[llp]['trying'] = 0
- data.dmesg[llp]['trying'] += \
+ if 'waking' not in data.dmesg[llp]:
+ data.dmesg[llp]['waking'] = [0, 0.0]
+ data.dmesg[llp]['waking'][0] += 1
+ data.dmesg[llp]['waking'][1] += \
t.time - data.dmesg[lp]['start']
data.currphase = ''
del data.dmesg[lp]
@@ -4555,7 +4638,7 @@ def createHTML(testruns, testfail):
# draw the devices for this phase
phaselist = data.dmesg[b]['list']
for d in sorted(data.tdevlist[b]):
- dname = d if '[' not in d else d.split('[')[0]
+ dname = d if ('[' not in d or 'CPU' in d) else d.split('[')[0]
name, dev = dname, phaselist[d]
drv = xtraclass = xtrainfo = xtrastyle = ''
if 'htmlclass' in dev:
@@ -5194,156 +5277,146 @@ def addScriptCode(hf, testruns):
'</script>\n'
hf.write(script_code);
-def setRuntimeSuspend(before=True):
- global sysvals
- sv = sysvals
- if sv.rs == 0:
- return
- if before:
- # runtime suspend disable or enable
- if sv.rs > 0:
- sv.rstgt, sv.rsval, sv.rsdir = 'on', 'auto', 'enabled'
- else:
- sv.rstgt, sv.rsval, sv.rsdir = 'auto', 'on', 'disabled'
- pprint('CONFIGURING RUNTIME SUSPEND...')
- sv.rslist = deviceInfo(sv.rstgt)
- for i in sv.rslist:
- sv.setVal(sv.rsval, i)
- pprint('runtime suspend %s on all devices (%d changed)' % (sv.rsdir, len(sv.rslist)))
- pprint('waiting 5 seconds...')
- time.sleep(5)
- else:
- # runtime suspend re-enable or re-disable
- for i in sv.rslist:
- sv.setVal(sv.rstgt, i)
- pprint('runtime suspend settings restored on %d devices' % len(sv.rslist))
-
# Function: executeSuspend
# Description:
# Execute system suspend through the sysfs interface, then copy the output
# dmesg and ftrace files to the test output directory.
def executeSuspend(quiet=False):
- pm = ProcessMonitor()
- tp = sysvals.tpath
- if sysvals.wifi:
- wifi = sysvals.checkWifi()
+ sv, tp, pm = sysvals, sysvals.tpath, ProcessMonitor()
+ if sv.wifi:
+ wifi = sv.checkWifi()
+ sv.dlog('wifi check, connected device is "%s"' % wifi)
testdata = []
# run these commands to prepare the system for suspend
- if sysvals.display:
+ if sv.display:
if not quiet:
- pprint('SET DISPLAY TO %s' % sysvals.display.upper())
- displayControl(sysvals.display)
+ pprint('SET DISPLAY TO %s' % sv.display.upper())
+ ret = sv.displayControl(sv.display)
+ sv.dlog('xset display %s, ret = %d' % (sv.display, ret))
time.sleep(1)
- if sysvals.sync:
+ if sv.sync:
if not quiet:
pprint('SYNCING FILESYSTEMS')
+ sv.dlog('syncing filesystems')
call('sync', shell=True)
- # mark the start point in the kernel ring buffer just as we start
- sysvals.initdmesg()
+ sv.dlog('read dmesg')
+ sv.initdmesg()
# start ftrace
- if(sysvals.usecallgraph or sysvals.usetraceevents):
+ if(sv.usecallgraph or sv.usetraceevents):
if not quiet:
pprint('START TRACING')
- sysvals.fsetVal('1', 'tracing_on')
- if sysvals.useprocmon:
+ sv.dlog('start ftrace tracing')
+ sv.fsetVal('1', 'tracing_on')
+ if sv.useprocmon:
+ sv.dlog('start the process monitor')
pm.start()
- sysvals.cmdinfo(True)
+ sv.dlog('run the cmdinfo list before')
+ sv.cmdinfo(True)
# execute however many s/r runs requested
- for count in range(1,sysvals.execcount+1):
+ for count in range(1,sv.execcount+1):
# x2delay in between test runs
- if(count > 1 and sysvals.x2delay > 0):
- sysvals.fsetVal('WAIT %d' % sysvals.x2delay, 'trace_marker')
- time.sleep(sysvals.x2delay/1000.0)
- sysvals.fsetVal('WAIT END', 'trace_marker')
+ if(count > 1 and sv.x2delay > 0):
+ sv.fsetVal('WAIT %d' % sv.x2delay, 'trace_marker')
+ time.sleep(sv.x2delay/1000.0)
+ sv.fsetVal('WAIT END', 'trace_marker')
# start message
- if sysvals.testcommand != '':
+ if sv.testcommand != '':
pprint('COMMAND START')
else:
- if(sysvals.rtcwake):
+ if(sv.rtcwake):
pprint('SUSPEND START')
else:
pprint('SUSPEND START (press a key to resume)')
# set rtcwake
- if(sysvals.rtcwake):
+ if(sv.rtcwake):
if not quiet:
- pprint('will issue an rtcwake in %d seconds' % sysvals.rtcwaketime)
- sysvals.rtcWakeAlarmOn()
+ pprint('will issue an rtcwake in %d seconds' % sv.rtcwaketime)
+ sv.dlog('enable RTC wake alarm')
+ sv.rtcWakeAlarmOn()
# start of suspend trace marker
- if(sysvals.usecallgraph or sysvals.usetraceevents):
- sysvals.fsetVal(datetime.now().strftime(sysvals.tmstart), 'trace_marker')
+ if(sv.usecallgraph or sv.usetraceevents):
+ sv.fsetVal(datetime.now().strftime(sv.tmstart), 'trace_marker')
# predelay delay
- if(count == 1 and sysvals.predelay > 0):
- sysvals.fsetVal('WAIT %d' % sysvals.predelay, 'trace_marker')
- time.sleep(sysvals.predelay/1000.0)
- sysvals.fsetVal('WAIT END', 'trace_marker')
+ if(count == 1 and sv.predelay > 0):
+ sv.fsetVal('WAIT %d' % sv.predelay, 'trace_marker')
+ time.sleep(sv.predelay/1000.0)
+ sv.fsetVal('WAIT END', 'trace_marker')
# initiate suspend or command
+ sv.dlog('system executing a suspend')
tdata = {'error': ''}
- if sysvals.testcommand != '':
- res = call(sysvals.testcommand+' 2>&1', shell=True);
+ if sv.testcommand != '':
+ res = call(sv.testcommand+' 2>&1', shell=True);
if res != 0:
tdata['error'] = 'cmd returned %d' % res
else:
- mode = sysvals.suspendmode
- if sysvals.memmode and os.path.exists(sysvals.mempowerfile):
+ mode = sv.suspendmode
+ if sv.memmode and os.path.exists(sv.mempowerfile):
mode = 'mem'
- pf = open(sysvals.mempowerfile, 'w')
- pf.write(sysvals.memmode)
- pf.close()
- if sysvals.diskmode and os.path.exists(sysvals.diskpowerfile):
+ sv.testVal(sv.mempowerfile, 'radio', sv.memmode)
+ if sv.diskmode and os.path.exists(sv.diskpowerfile):
mode = 'disk'
- pf = open(sysvals.diskpowerfile, 'w')
- pf.write(sysvals.diskmode)
- pf.close()
- if mode == 'freeze' and sysvals.haveTurbostat():
+ sv.testVal(sv.diskpowerfile, 'radio', sv.diskmode)
+ if sv.acpidebug:
+ sv.testVal(sv.acpipath, 'acpi', '0xe')
+ if mode == 'freeze' and sv.haveTurbostat():
# execution will pause here
- turbo = sysvals.turbostat()
+ turbo = sv.turbostat()
if turbo:
tdata['turbo'] = turbo
else:
- pf = open(sysvals.powerfile, 'w')
+ pf = open(sv.powerfile, 'w')
pf.write(mode)
# execution will pause here
try:
pf.close()
except Exception as e:
tdata['error'] = str(e)
- if(sysvals.rtcwake):
- sysvals.rtcWakeAlarmOff()
+ sv.dlog('system returned from resume')
+ # reset everything
+ sv.testVal('restoreall')
+ if(sv.rtcwake):
+ sv.dlog('disable RTC wake alarm')
+ sv.rtcWakeAlarmOff()
# postdelay delay
- if(count == sysvals.execcount and sysvals.postdelay > 0):
- sysvals.fsetVal('WAIT %d' % sysvals.postdelay, 'trace_marker')
- time.sleep(sysvals.postdelay/1000.0)
- sysvals.fsetVal('WAIT END', 'trace_marker')
+ if(count == sv.execcount and sv.postdelay > 0):
+ sv.fsetVal('WAIT %d' % sv.postdelay, 'trace_marker')
+ time.sleep(sv.postdelay/1000.0)
+ sv.fsetVal('WAIT END', 'trace_marker')
# return from suspend
pprint('RESUME COMPLETE')
- if(sysvals.usecallgraph or sysvals.usetraceevents):
- sysvals.fsetVal(datetime.now().strftime(sysvals.tmend), 'trace_marker')
- if sysvals.wifi and wifi:
- tdata['wifi'] = sysvals.pollWifi(wifi)
- if(sysvals.suspendmode == 'mem' or sysvals.suspendmode == 'command'):
+ if(sv.usecallgraph or sv.usetraceevents):
+ sv.fsetVal(datetime.now().strftime(sv.tmend), 'trace_marker')
+ if sv.wifi and wifi:
+ tdata['wifi'] = sv.pollWifi(wifi)
+ sv.dlog('wifi check, %s' % tdata['wifi'])
+ if(sv.suspendmode == 'mem' or sv.suspendmode == 'command'):
+ sv.dlog('read the ACPI FPDT')
tdata['fw'] = getFPDT(False)
testdata.append(tdata)
- cmdafter = sysvals.cmdinfo(False)
+ sv.dlog('run the cmdinfo list after')
+ cmdafter = sv.cmdinfo(False)
# stop ftrace
- if(sysvals.usecallgraph or sysvals.usetraceevents):
- if sysvals.useprocmon:
+ if(sv.usecallgraph or sv.usetraceevents):
+ if sv.useprocmon:
+ sv.dlog('stop the process monitor')
pm.stop()
- sysvals.fsetVal('0', 'tracing_on')
+ sv.fsetVal('0', 'tracing_on')
# grab a copy of the dmesg output
if not quiet:
pprint('CAPTURING DMESG')
- sysvals.getdmesg(testdata)
+ sysvals.dlog('EXECUTION TRACE END')
+ sv.getdmesg(testdata)
# grab a copy of the ftrace output
- if(sysvals.usecallgraph or sysvals.usetraceevents):
+ if(sv.usecallgraph or sv.usetraceevents):
if not quiet:
pprint('CAPTURING TRACE')
- op = sysvals.writeDatafileHeader(sysvals.ftracefile, testdata)
+ op = sv.writeDatafileHeader(sv.ftracefile, testdata)
fp = open(tp+'trace', 'r')
for line in fp:
op.write(line)
op.close()
- sysvals.fsetVal('', 'trace')
- sysvals.platforminfo(cmdafter)
+ sv.fsetVal('', 'trace')
+ sv.platforminfo(cmdafter)
def readFile(file):
if os.path.islink(file):
@@ -5586,39 +5659,6 @@ def dmidecode(mempath, fatal=False):
count += 1
return out
-def displayControl(cmd):
- xset, ret = 'timeout 10 xset -d :0.0 {0}', 0
- if sysvals.sudouser:
- xset = 'sudo -u %s %s' % (sysvals.sudouser, xset)
- if cmd == 'init':
- ret = call(xset.format('dpms 0 0 0'), shell=True)
- if not ret:
- ret = call(xset.format('s off'), shell=True)
- elif cmd == 'reset':
- ret = call(xset.format('s reset'), shell=True)
- elif cmd in ['on', 'off', 'standby', 'suspend']:
- b4 = displayControl('stat')
- ret = call(xset.format('dpms force %s' % cmd), shell=True)
- if not ret:
- curr = displayControl('stat')
- sysvals.vprint('Display Switched: %s -> %s' % (b4, curr))
- if curr != cmd:
- sysvals.vprint('WARNING: Display failed to change to %s' % cmd)
- if ret:
- sysvals.vprint('WARNING: Display failed to change to %s with xset' % cmd)
- return ret
- elif cmd == 'stat':
- fp = Popen(xset.format('q').split(' '), stdout=PIPE).stdout
- ret = 'unknown'
- for line in fp:
- m = re.match('[\s]*Monitor is (?P<m>.*)', ascii(line))
- if(m and len(m.group('m')) >= 2):
- out = m.group('m').lower()
- ret = out[3:] if out[0:2] == 'in' else out
- break
- fp.close()
- return ret
-
# Function: getFPDT
# Description:
# Read the acpi bios tables and pull out FPDT, the firmware data
@@ -6001,8 +6041,19 @@ def rerunTest(htmlfile=''):
# execute a suspend/resume, gather the logs, and generate the output
def runTest(n=0, quiet=False):
# prepare for the test
- sysvals.initFtrace(quiet)
sysvals.initTestOutput('suspend')
+ op = sysvals.writeDatafileHeader(sysvals.dmesgfile, [])
+ op.write('# EXECUTION TRACE START\n')
+ op.close()
+ if n <= 1:
+ if sysvals.rs != 0:
+ sysvals.dlog('%sabling runtime suspend' % ('en' if sysvals.rs > 0 else 'dis'))
+ sysvals.setRuntimeSuspend(True)
+ if sysvals.display:
+ ret = sysvals.displayControl('init')
+ sysvals.dlog('xset display init, ret = %d' % ret)
+ sysvals.dlog('initialize ftrace')
+ sysvals.initFtrace(quiet)
# execute the test
executeSuspend(quiet)
@@ -6098,8 +6149,16 @@ def data_from_html(file, outpath, issues, fulldetail=False):
if wifi:
extra['wifi'] = wifi
low = find_in_html(html, 'freeze time: <b>', ' ms</b>')
- if low and 'waking' in low:
- issue = 'FREEZEWAKE'
+ for lowstr in ['waking', '+']:
+ if not low:
+ break
+ if lowstr not in low:
+ continue
+ if lowstr == '+':
+ issue = 'S2LOOPx%d' % len(low.split('+'))
+ else:
+ m = re.match('.*waking *(?P<n>[0-9]*) *times.*', low)
+ issue = 'S2WAKEx%s' % m.group('n') if m else 'S2WAKExNaN'
match = [i for i in issues if i['match'] == issue]
if len(match) > 0:
match[0]['count'] += 1
@@ -6605,6 +6664,11 @@ if __name__ == '__main__':
val = next(args)
except:
doError('-info requires one string argument', True)
+ elif(arg == '-desc'):
+ try:
+ val = next(args)
+ except:
+ doError('-desc requires one string argument', True)
elif(arg == '-rs'):
try:
val = next(args)
@@ -6814,9 +6878,9 @@ if __name__ == '__main__':
runSummary(sysvals.outdir, True, genhtml)
elif(cmd in ['xon', 'xoff', 'xstandby', 'xsuspend', 'xinit', 'xreset']):
sysvals.verbose = True
- ret = displayControl(cmd[1:])
+ ret = sysvals.displayControl(cmd[1:])
elif(cmd == 'xstat'):
- pprint('Display Status: %s' % displayControl('stat').upper())
+ pprint('Display Status: %s' % sysvals.displayControl('stat').upper())
elif(cmd == 'wificheck'):
dev = sysvals.checkWifi()
if dev:
@@ -6854,12 +6918,8 @@ if __name__ == '__main__':
if mode.startswith('disk-'):
sysvals.diskmode = mode.split('-', 1)[-1]
sysvals.suspendmode = 'disk'
-
sysvals.systemInfo(dmidecode(sysvals.mempath))
- setRuntimeSuspend(True)
- if sysvals.display:
- displayControl('init')
failcnt, ret = 0, 0
if sysvals.multitest['run']:
# run multiple tests in a separate subdirectory
@@ -6900,7 +6960,10 @@ if __name__ == '__main__':
sysvals.testdir = sysvals.outdir
# run the test in the current directory
ret = runTest()
+
+ # reset to default values after testing
if sysvals.display:
- displayControl('reset')
- setRuntimeSuspend(False)
+ sysvals.displayControl('reset')
+ if sysvals.rs != 0:
+ sysvals.setRuntimeSuspend(False)
sys.exit(ret)
diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c
index cd089a505859..5390158cdb40 100644
--- a/tools/power/x86/intel-speed-select/isst-config.c
+++ b/tools/power/x86/intel-speed-select/isst-config.c
@@ -15,7 +15,7 @@ struct process_cmd_struct {
int arg;
};
-static const char *version_str = "v1.6";
+static const char *version_str = "v1.7";
static const int supported_api_ver = 1;
static struct isst_if_platform_info isst_platform_info;
static char *progname;
@@ -328,8 +328,12 @@ int get_physical_die_id(int cpu)
int core_id, pkg_id, die_id;
ret = get_stored_topology_info(cpu, &core_id, &pkg_id, &die_id);
- if (!ret)
+ if (!ret) {
+ if (die_id < 0)
+ die_id = 0;
+
return die_id;
+ }
}
if (ret < 0)
diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c
index 1d7ecb54352e..8afd23407522 100644
--- a/tools/power/x86/intel-speed-select/isst-core.c
+++ b/tools/power/x86/intel-speed-select/isst-core.c
@@ -804,7 +804,7 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev)
return ret;
}
- if (!pkg_dev->enabled) {
+ if (!pkg_dev->enabled && is_skx_based_platform()) {
int freq;
freq = get_cpufreq_base_freq(cpu);
diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h
index 29715e9c2e06..60db0bb084d5 100644
--- a/tools/power/x86/intel-speed-select/isst.h
+++ b/tools/power/x86/intel-speed-select/isst.h
@@ -255,4 +255,5 @@ extern int is_clx_n_platform(void);
extern int get_cpufreq_base_freq(int cpu);
extern int isst_read_pm_config(int cpu, int *cp_state, int *cp_cap);
extern void isst_display_error_info_message(int error, char *msg, int arg_valid, int arg);
+extern int is_skx_based_platform(void);
#endif
diff --git a/tools/testing/kunit/kunit_kernel.py b/tools/testing/kunit/kunit_kernel.py
index 2e3cc0fac726..57c1724b7e5d 100644
--- a/tools/testing/kunit/kunit_kernel.py
+++ b/tools/testing/kunit/kunit_kernel.py
@@ -23,6 +23,11 @@ DEFAULT_KUNITCONFIG_PATH = 'arch/um/configs/kunit_defconfig'
BROKEN_ALLCONFIG_PATH = 'tools/testing/kunit/configs/broken_on_uml.config'
OUTFILE_PATH = 'test.log'
+def get_file_path(build_dir, default):
+ if build_dir:
+ default = os.path.join(build_dir, default)
+ return default
+
class ConfigError(Exception):
"""Represents an error trying to configure the Linux kernel."""
@@ -97,9 +102,7 @@ class LinuxSourceTreeOperations(object):
def linux_bin(self, params, timeout, build_dir):
"""Runs the Linux UML binary. Must be named 'linux'."""
- linux_bin = './linux'
- if build_dir:
- linux_bin = os.path.join(build_dir, 'linux')
+ linux_bin = get_file_path(build_dir, 'linux')
outfile = get_outfile_path(build_dir)
with open(outfile, 'w') as output:
process = subprocess.Popen([linux_bin] + params,
@@ -108,22 +111,13 @@ class LinuxSourceTreeOperations(object):
process.wait(timeout)
def get_kconfig_path(build_dir):
- kconfig_path = KCONFIG_PATH
- if build_dir:
- kconfig_path = os.path.join(build_dir, KCONFIG_PATH)
- return kconfig_path
+ return get_file_path(build_dir, KCONFIG_PATH)
def get_kunitconfig_path(build_dir):
- kunitconfig_path = KUNITCONFIG_PATH
- if build_dir:
- kunitconfig_path = os.path.join(build_dir, KUNITCONFIG_PATH)
- return kunitconfig_path
+ return get_file_path(build_dir, KUNITCONFIG_PATH)
def get_outfile_path(build_dir):
- outfile_path = OUTFILE_PATH
- if build_dir:
- outfile_path = os.path.join(build_dir, OUTFILE_PATH)
- return outfile_path
+ return get_file_path(build_dir, OUTFILE_PATH)
class LinuxSourceTree(object):
"""Represents a Linux kernel source tree with KUnit tests."""
diff --git a/tools/testing/kunit/kunit_parser.py b/tools/testing/kunit/kunit_parser.py
index bbfe1b4e4c1c..6614ec4d0898 100644
--- a/tools/testing/kunit/kunit_parser.py
+++ b/tools/testing/kunit/kunit_parser.py
@@ -135,8 +135,8 @@ def parse_ok_not_ok_test_case(lines: List[str], test_case: TestCase) -> bool:
else:
return False
-SUBTEST_DIAGNOSTIC = re.compile(r'^[\s]+# .*?: (.*)$')
-DIAGNOSTIC_CRASH_MESSAGE = 'kunit test case crashed!'
+SUBTEST_DIAGNOSTIC = re.compile(r'^[\s]+# (.*)$')
+DIAGNOSTIC_CRASH_MESSAGE = re.compile(r'^[\s]+# .*?: kunit test case crashed!$')
def parse_diagnostic(lines: List[str], test_case: TestCase) -> bool:
save_non_diagnositic(lines, test_case)
@@ -146,7 +146,8 @@ def parse_diagnostic(lines: List[str], test_case: TestCase) -> bool:
match = SUBTEST_DIAGNOSTIC.match(line)
if match:
test_case.log.append(lines.pop(0))
- if match.group(1) == DIAGNOSTIC_CRASH_MESSAGE:
+ crash_match = DIAGNOSTIC_CRASH_MESSAGE.match(line)
+ if crash_match:
test_case.status = TestStatus.TEST_CRASHED
return True
else:
diff --git a/tools/testing/scatterlist/main.c b/tools/testing/scatterlist/main.c
index 8a577c95496e..71c960dcd8a4 100644
--- a/tools/testing/scatterlist/main.c
+++ b/tools/testing/scatterlist/main.c
@@ -9,6 +9,7 @@ struct test {
int alloc_ret;
unsigned num_pages;
unsigned *pfn;
+ unsigned *pfn_app;
unsigned size;
unsigned int max_seg;
unsigned int expected_segments;
@@ -52,31 +53,39 @@ int main(void)
{
const unsigned int sgmax = UINT_MAX;
struct test *test, tests[] = {
- { -EINVAL, 1, pfn(0), PAGE_SIZE, 0, 1 },
- { 0, 1, pfn(0), PAGE_SIZE, PAGE_SIZE + 1, 1 },
- { 0, 1, pfn(0), PAGE_SIZE, sgmax + 1, 1 },
- { 0, 1, pfn(0), PAGE_SIZE, sgmax, 1 },
- { 0, 1, pfn(0), 1, sgmax, 1 },
- { 0, 2, pfn(0, 1), 2 * PAGE_SIZE, sgmax, 1 },
- { 0, 2, pfn(1, 0), 2 * PAGE_SIZE, sgmax, 2 },
- { 0, 3, pfn(0, 1, 2), 3 * PAGE_SIZE, sgmax, 1 },
- { 0, 3, pfn(0, 2, 1), 3 * PAGE_SIZE, sgmax, 3 },
- { 0, 3, pfn(0, 1, 3), 3 * PAGE_SIZE, sgmax, 2 },
- { 0, 3, pfn(1, 2, 4), 3 * PAGE_SIZE, sgmax, 2 },
- { 0, 3, pfn(1, 3, 4), 3 * PAGE_SIZE, sgmax, 2 },
- { 0, 4, pfn(0, 1, 3, 4), 4 * PAGE_SIZE, sgmax, 2 },
- { 0, 5, pfn(0, 1, 3, 4, 5), 5 * PAGE_SIZE, sgmax, 2 },
- { 0, 5, pfn(0, 1, 3, 4, 6), 5 * PAGE_SIZE, sgmax, 3 },
- { 0, 5, pfn(0, 1, 2, 3, 4), 5 * PAGE_SIZE, sgmax, 1 },
- { 0, 5, pfn(0, 1, 2, 3, 4), 5 * PAGE_SIZE, 2 * PAGE_SIZE, 3 },
- { 0, 6, pfn(0, 1, 2, 3, 4, 5), 6 * PAGE_SIZE, 2 * PAGE_SIZE, 3 },
- { 0, 6, pfn(0, 2, 3, 4, 5, 6), 6 * PAGE_SIZE, 2 * PAGE_SIZE, 4 },
- { 0, 6, pfn(0, 1, 3, 4, 5, 6), 6 * PAGE_SIZE, 2 * PAGE_SIZE, 3 },
- { 0, 0, NULL, 0, 0, 0 },
+ { -EINVAL, 1, pfn(0), NULL, PAGE_SIZE, 0, 1 },
+ { 0, 1, pfn(0), NULL, PAGE_SIZE, PAGE_SIZE + 1, 1 },
+ { 0, 1, pfn(0), NULL, PAGE_SIZE, sgmax + 1, 1 },
+ { 0, 1, pfn(0), NULL, PAGE_SIZE, sgmax, 1 },
+ { 0, 1, pfn(0), NULL, 1, sgmax, 1 },
+ { 0, 2, pfn(0, 1), NULL, 2 * PAGE_SIZE, sgmax, 1 },
+ { 0, 2, pfn(1, 0), NULL, 2 * PAGE_SIZE, sgmax, 2 },
+ { 0, 3, pfn(0, 1, 2), NULL, 3 * PAGE_SIZE, sgmax, 1 },
+ { 0, 3, pfn(0, 1, 2), NULL, 3 * PAGE_SIZE, sgmax, 1 },
+ { 0, 3, pfn(0, 1, 2), pfn(3, 4, 5), 3 * PAGE_SIZE, sgmax, 1 },
+ { 0, 3, pfn(0, 1, 2), pfn(4, 5, 6), 3 * PAGE_SIZE, sgmax, 2 },
+ { 0, 3, pfn(0, 2, 1), NULL, 3 * PAGE_SIZE, sgmax, 3 },
+ { 0, 3, pfn(0, 1, 3), NULL, 3 * PAGE_SIZE, sgmax, 2 },
+ { 0, 3, pfn(1, 2, 4), NULL, 3 * PAGE_SIZE, sgmax, 2 },
+ { 0, 3, pfn(1, 3, 4), NULL, 3 * PAGE_SIZE, sgmax, 2 },
+ { 0, 4, pfn(0, 1, 3, 4), NULL, 4 * PAGE_SIZE, sgmax, 2 },
+ { 0, 5, pfn(0, 1, 3, 4, 5), NULL, 5 * PAGE_SIZE, sgmax, 2 },
+ { 0, 5, pfn(0, 1, 3, 4, 6), NULL, 5 * PAGE_SIZE, sgmax, 3 },
+ { 0, 5, pfn(0, 1, 2, 3, 4), NULL, 5 * PAGE_SIZE, sgmax, 1 },
+ { 0, 5, pfn(0, 1, 2, 3, 4), NULL, 5 * PAGE_SIZE, 2 * PAGE_SIZE,
+ 3 },
+ { 0, 6, pfn(0, 1, 2, 3, 4, 5), NULL, 6 * PAGE_SIZE,
+ 2 * PAGE_SIZE, 3 },
+ { 0, 6, pfn(0, 2, 3, 4, 5, 6), NULL, 6 * PAGE_SIZE,
+ 2 * PAGE_SIZE, 4 },
+ { 0, 6, pfn(0, 1, 3, 4, 5, 6), pfn(7, 8, 9, 10, 11, 12),
+ 6 * PAGE_SIZE, 12 * PAGE_SIZE, 2 },
+ { 0, 0, NULL, NULL, 0, 0, 0 },
};
unsigned int i;
for (i = 0, test = tests; test->expected_segments; test++, i++) {
+ int left_pages = test->pfn_app ? test->num_pages : 0;
struct page *pages[MAX_PAGES];
struct sg_table st;
struct scatterlist *sg;
@@ -84,14 +93,23 @@ int main(void)
set_pages(pages, test->pfn, test->num_pages);
sg = __sg_alloc_table_from_pages(&st, pages, test->num_pages, 0,
- test->size, test->max_seg, NULL, 0, GFP_KERNEL);
+ test->size, test->max_seg, NULL, left_pages, GFP_KERNEL);
assert(PTR_ERR_OR_ZERO(sg) == test->alloc_ret);
if (test->alloc_ret)
continue;
+ if (test->pfn_app) {
+ set_pages(pages, test->pfn_app, test->num_pages);
+ sg = __sg_alloc_table_from_pages(&st, pages, test->num_pages, 0,
+ test->size, test->max_seg, sg, 0, GFP_KERNEL);
+
+ assert(PTR_ERR_OR_ZERO(sg) == test->alloc_ret);
+ }
+
VALIDATE(st.nents == test->expected_segments, &st, test);
- VALIDATE(st.orig_nents == test->expected_segments, &st, test);
+ if (!test->pfn_app)
+ VALIDATE(st.orig_nents == test->expected_segments, &st, test);
sg_free_table(&st);
}
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index c917f9f2446c..afbab4aeef3c 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -66,6 +66,7 @@ endif
TARGETS += tmpfs
TARGETS += tpm2
TARGETS += user
+TARGETS += vDSO
TARGETS += vm
TARGETS += x86
TARGETS += zram
diff --git a/tools/testing/selftests/cgroup/cgroup_util.c b/tools/testing/selftests/cgroup/cgroup_util.c
index 05853b0b8831..027014662fb2 100644
--- a/tools/testing/selftests/cgroup/cgroup_util.c
+++ b/tools/testing/selftests/cgroup/cgroup_util.c
@@ -337,13 +337,13 @@ pid_t clone_into_cgroup(int cgroup_fd)
#ifdef CLONE_ARGS_SIZE_VER2
pid_t pid;
- struct clone_args args = {
+ struct __clone_args args = {
.flags = CLONE_INTO_CGROUP,
.exit_signal = SIGCHLD,
.cgroup = cgroup_fd,
};
- pid = sys_clone3(&args, sizeof(struct clone_args));
+ pid = sys_clone3(&args, sizeof(struct __clone_args));
/*
* Verify that this is a genuine test failure:
* ENOSYS -> clone3() not available
diff --git a/tools/testing/selftests/clone3/Makefile b/tools/testing/selftests/clone3/Makefile
index ef7564cb7abe..79b19a2863a0 100644
--- a/tools/testing/selftests/clone3/Makefile
+++ b/tools/testing/selftests/clone3/Makefile
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
-CFLAGS += -g -I../../../../usr/include/
+CFLAGS += -g -std=gnu99 -I../../../../usr/include/
LDLIBS += -lcap
TEST_GEN_PROGS := clone3 clone3_clear_sighand clone3_set_tid \
diff --git a/tools/testing/selftests/core/close_range_test.c b/tools/testing/selftests/core/close_range_test.c
index 575b391ddc78..87e16d65d9d7 100644
--- a/tools/testing/selftests/core/close_range_test.c
+++ b/tools/testing/selftests/core/close_range_test.c
@@ -11,6 +11,7 @@
#include <string.h>
#include <syscall.h>
#include <unistd.h>
+#include <sys/resource.h>
#include "../kselftest_harness.h"
#include "../clone3/clone3_selftests.h"
@@ -23,6 +24,10 @@
#define CLOSE_RANGE_UNSHARE (1U << 1)
#endif
+#ifndef CLOSE_RANGE_CLOEXEC
+#define CLOSE_RANGE_CLOEXEC (1U << 2)
+#endif
+
static inline int sys_close_range(unsigned int fd, unsigned int max_fd,
unsigned int flags)
{
@@ -224,4 +229,73 @@ TEST(close_range_unshare_capped)
EXPECT_EQ(0, WEXITSTATUS(status));
}
+TEST(close_range_cloexec)
+{
+ int i, ret;
+ int open_fds[101];
+ struct rlimit rlimit;
+
+ for (i = 0; i < ARRAY_SIZE(open_fds); i++) {
+ int fd;
+
+ fd = open("/dev/null", O_RDONLY);
+ ASSERT_GE(fd, 0) {
+ if (errno == ENOENT)
+ XFAIL(return, "Skipping test since /dev/null does not exist");
+ }
+
+ open_fds[i] = fd;
+ }
+
+ ret = sys_close_range(1000, 1000, CLOSE_RANGE_CLOEXEC);
+ if (ret < 0) {
+ if (errno == ENOSYS)
+ XFAIL(return, "close_range() syscall not supported");
+ if (errno == EINVAL)
+ XFAIL(return, "close_range() doesn't support CLOSE_RANGE_CLOEXEC");
+ }
+
+ /* Ensure the FD_CLOEXEC bit is set also with a resource limit in place. */
+ ASSERT_EQ(0, getrlimit(RLIMIT_NOFILE, &rlimit));
+ rlimit.rlim_cur = 25;
+ ASSERT_EQ(0, setrlimit(RLIMIT_NOFILE, &rlimit));
+
+ /* Set close-on-exec for two ranges: [0-50] and [75-100]. */
+ ret = sys_close_range(open_fds[0], open_fds[50], CLOSE_RANGE_CLOEXEC);
+ ASSERT_EQ(0, ret);
+ ret = sys_close_range(open_fds[75], open_fds[100], CLOSE_RANGE_CLOEXEC);
+ ASSERT_EQ(0, ret);
+
+ for (i = 0; i <= 50; i++) {
+ int flags = fcntl(open_fds[i], F_GETFD);
+
+ EXPECT_GT(flags, -1);
+ EXPECT_EQ(flags & FD_CLOEXEC, FD_CLOEXEC);
+ }
+
+ for (i = 51; i <= 74; i++) {
+ int flags = fcntl(open_fds[i], F_GETFD);
+
+ EXPECT_GT(flags, -1);
+ EXPECT_EQ(flags & FD_CLOEXEC, 0);
+ }
+
+ for (i = 75; i <= 100; i++) {
+ int flags = fcntl(open_fds[i], F_GETFD);
+
+ EXPECT_GT(flags, -1);
+ EXPECT_EQ(flags & FD_CLOEXEC, FD_CLOEXEC);
+ }
+
+ /* Test a common pattern. */
+ ret = sys_close_range(3, UINT_MAX, CLOSE_RANGE_CLOEXEC);
+ for (i = 0; i <= 100; i++) {
+ int flags = fcntl(open_fds[i], F_GETFD);
+
+ EXPECT_GT(flags, -1);
+ EXPECT_EQ(flags & FD_CLOEXEC, FD_CLOEXEC);
+ }
+}
+
+
TEST_HARNESS_MAIN
diff --git a/tools/testing/selftests/gpio/Makefile b/tools/testing/selftests/gpio/Makefile
index 32bdc978a711..41582fe485ee 100644
--- a/tools/testing/selftests/gpio/Makefile
+++ b/tools/testing/selftests/gpio/Makefile
@@ -11,22 +11,21 @@ LDLIBS += $(VAR_LDLIBS)
TEST_PROGS := gpio-mockup.sh
TEST_FILES := gpio-mockup-sysfs.sh
-TEST_PROGS_EXTENDED := gpio-mockup-chardev
+TEST_GEN_PROGS_EXTENDED := gpio-mockup-chardev
-GPIODIR := $(realpath ../../../gpio)
-GPIOOBJ := gpio-utils.o
+KSFT_KHDR_INSTALL := 1
+include ../lib.mk
-all: $(TEST_PROGS_EXTENDED)
+GPIODIR := $(realpath ../../../gpio)
+GPIOOUT := $(OUTPUT)/tools-gpio/
+GPIOOBJ := $(GPIOOUT)/gpio-utils.o
-override define CLEAN
- $(RM) $(TEST_PROGS_EXTENDED)
- $(MAKE) -C $(GPIODIR) OUTPUT=$(GPIODIR)/ clean
-endef
+CLEAN += ; $(RM) -rf $(GPIOOUT)
-KSFT_KHDR_INSTALL := 1
-include ../lib.mk
+$(TEST_GEN_PROGS_EXTENDED): $(GPIOOBJ)
-$(TEST_PROGS_EXTENDED): $(GPIODIR)/$(GPIOOBJ)
+$(GPIOOUT):
+ mkdir -p $@
-$(GPIODIR)/$(GPIOOBJ):
- $(MAKE) OUTPUT=$(GPIODIR)/ -C $(GPIODIR)
+$(GPIOOBJ): $(GPIOOUT)
+ $(MAKE) OUTPUT=$(GPIOOUT) -C $(GPIODIR)
diff --git a/tools/testing/selftests/intel_pstate/aperf.c b/tools/testing/selftests/intel_pstate/aperf.c
index f6cd03a87493..a8acf3996973 100644
--- a/tools/testing/selftests/intel_pstate/aperf.c
+++ b/tools/testing/selftests/intel_pstate/aperf.c
@@ -10,8 +10,12 @@
#include <sched.h>
#include <errno.h>
#include <string.h>
+#include <time.h>
#include "../kselftest.h"
+#define MSEC_PER_SEC 1000L
+#define NSEC_PER_MSEC 1000000L
+
void usage(char *name) {
printf ("Usage: %s cpunum\n", name);
}
@@ -22,7 +26,7 @@ int main(int argc, char **argv) {
long long tsc, old_tsc, new_tsc;
long long aperf, old_aperf, new_aperf;
long long mperf, old_mperf, new_mperf;
- struct timeb before, after;
+ struct timespec before, after;
long long int start, finish, total;
cpu_set_t cpuset;
@@ -55,7 +59,10 @@ int main(int argc, char **argv) {
return 1;
}
- ftime(&before);
+ if (clock_gettime(CLOCK_MONOTONIC, &before) < 0) {
+ perror("clock_gettime");
+ return 1;
+ }
pread(fd, &old_tsc, sizeof(old_tsc), 0x10);
pread(fd, &old_aperf, sizeof(old_mperf), 0xe7);
pread(fd, &old_mperf, sizeof(old_aperf), 0xe8);
@@ -64,7 +71,10 @@ int main(int argc, char **argv) {
sqrt(i);
}
- ftime(&after);
+ if (clock_gettime(CLOCK_MONOTONIC, &after) < 0) {
+ perror("clock_gettime");
+ return 1;
+ }
pread(fd, &new_tsc, sizeof(new_tsc), 0x10);
pread(fd, &new_aperf, sizeof(new_mperf), 0xe7);
pread(fd, &new_mperf, sizeof(new_aperf), 0xe8);
@@ -73,11 +83,11 @@ int main(int argc, char **argv) {
aperf = new_aperf-old_aperf;
mperf = new_mperf-old_mperf;
- start = before.time*1000 + before.millitm;
- finish = after.time*1000 + after.millitm;
+ start = before.tv_sec*MSEC_PER_SEC + before.tv_nsec/NSEC_PER_MSEC;
+ finish = after.tv_sec*MSEC_PER_SEC + after.tv_nsec/NSEC_PER_MSEC;
total = finish - start;
- printf("runTime: %4.2f\n", 1.0*total/1000);
+ printf("runTime: %4.2f\n", 1.0*total/MSEC_PER_SEC);
printf("freq: %7.0f\n", tsc / (1.0*aperf / (1.0 * mperf)) / total);
return 0;
}
diff --git a/tools/testing/selftests/lkdtm/tests.txt b/tools/testing/selftests/lkdtm/tests.txt
index 74a8d329a72c..11ef159be0fd 100644
--- a/tools/testing/selftests/lkdtm/tests.txt
+++ b/tools/testing/selftests/lkdtm/tests.txt
@@ -68,3 +68,5 @@ USERCOPY_STACK_BEYOND
USERCOPY_KERNEL
STACKLEAK_ERASING OK: the rest of the thread stack is properly erased
CFI_FORWARD_PROTO
+FORTIFIED_STRSCPY
+PPC_SLB_MULTIHIT Recovered
diff --git a/tools/testing/selftests/memfd/fuse_test.c b/tools/testing/selftests/memfd/fuse_test.c
index b018e835737d..be675002f918 100644
--- a/tools/testing/selftests/memfd/fuse_test.c
+++ b/tools/testing/selftests/memfd/fuse_test.c
@@ -20,7 +20,7 @@
#include <inttypes.h>
#include <limits.h>
#include <linux/falloc.h>
-#include <linux/fcntl.h>
+#include <fcntl.h>
#include <linux/memfd.h>
#include <sched.h>
#include <stdio.h>
diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/selftests/memfd/memfd_test.c
index 334a7eea2004..74baab83fec3 100644
--- a/tools/testing/selftests/memfd/memfd_test.c
+++ b/tools/testing/selftests/memfd/memfd_test.c
@@ -6,7 +6,7 @@
#include <inttypes.h>
#include <limits.h>
#include <linux/falloc.h>
-#include <linux/fcntl.h>
+#include <fcntl.h>
#include <linux/memfd.h>
#include <sched.h>
#include <stdio.h>
diff --git a/tools/testing/selftests/net/mptcp/simult_flows.sh b/tools/testing/selftests/net/mptcp/simult_flows.sh
index 2f649b431456..f039ee57eb3c 100755
--- a/tools/testing/selftests/net/mptcp/simult_flows.sh
+++ b/tools/testing/selftests/net/mptcp/simult_flows.sh
@@ -287,7 +287,7 @@ run_test 10 10 0 0 "balanced bwidth"
run_test 10 10 1 50 "balanced bwidth with unbalanced delay"
# we still need some additional infrastructure to pass the following test-cases
-# run_test 30 10 0 0 "unbalanced bwidth"
-# run_test 30 10 1 50 "unbalanced bwidth with unbalanced delay"
-# run_test 30 10 50 1 "unbalanced bwidth with opposed, unbalanced delay"
+run_test 30 10 0 0 "unbalanced bwidth"
+run_test 30 10 1 50 "unbalanced bwidth with unbalanced delay"
+run_test 30 10 50 1 "unbalanced bwidth with opposed, unbalanced delay"
exit $ret
diff --git a/tools/testing/selftests/openat2/openat2_test.c b/tools/testing/selftests/openat2/openat2_test.c
index b386367c606b..381d874cce99 100644
--- a/tools/testing/selftests/openat2/openat2_test.c
+++ b/tools/testing/selftests/openat2/openat2_test.c
@@ -155,7 +155,7 @@ struct flag_test {
int err;
};
-#define NUM_OPENAT2_FLAG_TESTS 23
+#define NUM_OPENAT2_FLAG_TESTS 24
void test_openat2_flags(void)
{
@@ -210,6 +210,12 @@ void test_openat2_flags(void)
.how.flags = O_TMPFILE | O_RDWR,
.how.mode = 0x0000A00000000000ULL, .err = -EINVAL },
+ /* ->resolve flags must not conflict. */
+ { .name = "incompatible resolve flags (BENEATH | IN_ROOT)",
+ .how.flags = O_RDONLY,
+ .how.resolve = RESOLVE_BENEATH | RESOLVE_IN_ROOT,
+ .err = -EINVAL },
+
/* ->resolve must only contain RESOLVE_* flags. */
{ .name = "invalid how.resolve and O_RDONLY",
.how.flags = O_RDONLY,
diff --git a/tools/testing/selftests/powerpc/eeh/Makefile b/tools/testing/selftests/powerpc/eeh/Makefile
index b397babd569b..ae963eb2dc5b 100644
--- a/tools/testing/selftests/powerpc/eeh/Makefile
+++ b/tools/testing/selftests/powerpc/eeh/Makefile
@@ -3,7 +3,7 @@ noarg:
$(MAKE) -C ../
TEST_PROGS := eeh-basic.sh
-TEST_FILES := eeh-functions.sh
+TEST_FILES := eeh-functions.sh settings
top_srcdir = ../../../../..
include ../../lib.mk
diff --git a/tools/testing/selftests/powerpc/eeh/settings b/tools/testing/selftests/powerpc/eeh/settings
new file mode 100644
index 000000000000..694d70710ff0
--- /dev/null
+++ b/tools/testing/selftests/powerpc/eeh/settings
@@ -0,0 +1 @@
+timeout=300
diff --git a/tools/testing/selftests/powerpc/mm/bad_accesses.c b/tools/testing/selftests/powerpc/mm/bad_accesses.c
index fd747b2ffcfc..65d2148b05dc 100644
--- a/tools/testing/selftests/powerpc/mm/bad_accesses.c
+++ b/tools/testing/selftests/powerpc/mm/bad_accesses.c
@@ -38,7 +38,7 @@ static void segv_handler(int n, siginfo_t *info, void *ctxt_v)
int bad_access(char *p, bool write)
{
- char x;
+ char x = 0;
fault_code = 0;
fault_addr = 0;
diff --git a/tools/testing/selftests/powerpc/nx-gzip/.gitignore b/tools/testing/selftests/powerpc/nx-gzip/.gitignore
new file mode 100644
index 000000000000..886d522d52df
--- /dev/null
+++ b/tools/testing/selftests/powerpc/nx-gzip/.gitignore
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+gunz_test
+gzfht_test
diff --git a/tools/testing/selftests/powerpc/security/.gitignore b/tools/testing/selftests/powerpc/security/.gitignore
index 4257a1f156bb..93614b125ded 100644
--- a/tools/testing/selftests/powerpc/security/.gitignore
+++ b/tools/testing/selftests/powerpc/security/.gitignore
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
rfi_flush
entry_flush
+spectre_v2
diff --git a/tools/testing/selftests/powerpc/signal/.gitignore b/tools/testing/selftests/powerpc/signal/.gitignore
index 405b5364044c..ce3375cd8e73 100644
--- a/tools/testing/selftests/powerpc/signal/.gitignore
+++ b/tools/testing/selftests/powerpc/signal/.gitignore
@@ -3,3 +3,4 @@ signal
signal_tm
sigfuz
sigreturn_vdso
+sig_sc_double_restart
diff --git a/tools/testing/selftests/powerpc/syscalls/.gitignore b/tools/testing/selftests/powerpc/syscalls/.gitignore
index b00cab225476..a1e19ccdef84 100644
--- a/tools/testing/selftests/powerpc/syscalls/.gitignore
+++ b/tools/testing/selftests/powerpc/syscalls/.gitignore
@@ -1,2 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
ipc_unmuxed
+rtas_filter
diff --git a/tools/testing/selftests/rseq/param_test.c b/tools/testing/selftests/rseq/param_test.c
index 384589095864..699ad5f93c34 100644
--- a/tools/testing/selftests/rseq/param_test.c
+++ b/tools/testing/selftests/rseq/param_test.c
@@ -1133,6 +1133,8 @@ static int set_signal_handler(void)
return ret;
}
+/* Test MEMBARRIER_CMD_PRIVATE_RESTART_RSEQ_ON_CPU membarrier command. */
+#ifdef RSEQ_ARCH_HAS_OFFSET_DEREF_ADDV
struct test_membarrier_thread_args {
int stop;
intptr_t percpu_list_ptr;
@@ -1286,8 +1288,6 @@ void *test_membarrier_manager_thread(void *arg)
return NULL;
}
-/* Test MEMBARRIER_CMD_PRIVATE_RESTART_RSEQ_ON_CPU membarrier command. */
-#ifdef RSEQ_ARCH_HAS_OFFSET_DEREF_ADDV
void test_membarrier(void)
{
const int num_threads = opt_threads;
diff --git a/tools/testing/selftests/run_kselftest.sh b/tools/testing/selftests/run_kselftest.sh
index 609a4ef9300e..97165a83df63 100755
--- a/tools/testing/selftests/run_kselftest.sh
+++ b/tools/testing/selftests/run_kselftest.sh
@@ -48,7 +48,7 @@ while true; do
-l | --list)
echo "$available"
exit 0 ;;
- -n | --dry-run)
+ -d | --dry-run)
dryrun="echo"
shift ;;
-h | --help)
diff --git a/tools/testing/selftests/seccomp/config b/tools/testing/selftests/seccomp/config
index 64c19d8eba79..ad431a5178fb 100644
--- a/tools/testing/selftests/seccomp/config
+++ b/tools/testing/selftests/seccomp/config
@@ -1,3 +1,4 @@
+CONFIG_PID_NS=y
CONFIG_SECCOMP=y
CONFIG_SECCOMP_FILTER=y
CONFIG_USER_NS=y
diff --git a/tools/testing/selftests/seccomp/seccomp_benchmark.c b/tools/testing/selftests/seccomp/seccomp_benchmark.c
index 91f5a89cadac..fcc806585266 100644
--- a/tools/testing/selftests/seccomp/seccomp_benchmark.c
+++ b/tools/testing/selftests/seccomp/seccomp_benchmark.c
@@ -4,12 +4,16 @@
*/
#define _GNU_SOURCE
#include <assert.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <linux/filter.h>
#include <linux/seccomp.h>
+#include <sys/param.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
#include <sys/types.h>
@@ -70,18 +74,74 @@ unsigned long long calibrate(void)
return samples * seconds;
}
+bool approx(int i_one, int i_two)
+{
+ double one = i_one, one_bump = one * 0.01;
+ double two = i_two, two_bump = two * 0.01;
+
+ one_bump = one + MAX(one_bump, 2.0);
+ two_bump = two + MAX(two_bump, 2.0);
+
+ /* Equal to, or within 1% or 2 digits */
+ if (one == two ||
+ (one > two && one <= two_bump) ||
+ (two > one && two <= one_bump))
+ return true;
+ return false;
+}
+
+bool le(int i_one, int i_two)
+{
+ if (i_one <= i_two)
+ return true;
+ return false;
+}
+
+long compare(const char *name_one, const char *name_eval, const char *name_two,
+ unsigned long long one, bool (*eval)(int, int), unsigned long long two)
+{
+ bool good;
+
+ printf("\t%s %s %s (%lld %s %lld): ", name_one, name_eval, name_two,
+ (long long)one, name_eval, (long long)two);
+ if (one > INT_MAX) {
+ printf("Miscalculation! Measurement went negative: %lld\n", (long long)one);
+ return 1;
+ }
+ if (two > INT_MAX) {
+ printf("Miscalculation! Measurement went negative: %lld\n", (long long)two);
+ return 1;
+ }
+
+ good = eval(one, two);
+ printf("%s\n", good ? "✔️" : "❌");
+
+ return good ? 0 : 1;
+}
+
int main(int argc, char *argv[])
{
+ struct sock_filter bitmap_filter[] = {
+ BPF_STMT(BPF_LD|BPF_W|BPF_ABS, offsetof(struct seccomp_data, nr)),
+ BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+ };
+ struct sock_fprog bitmap_prog = {
+ .len = (unsigned short)ARRAY_SIZE(bitmap_filter),
+ .filter = bitmap_filter,
+ };
struct sock_filter filter[] = {
+ BPF_STMT(BPF_LD|BPF_W|BPF_ABS, offsetof(struct seccomp_data, args[0])),
BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
};
struct sock_fprog prog = {
.len = (unsigned short)ARRAY_SIZE(filter),
.filter = filter,
};
- long ret;
- unsigned long long samples;
- unsigned long long native, filter1, filter2;
+
+ long ret, bits;
+ unsigned long long samples, calc;
+ unsigned long long native, filter1, filter2, bitmap1, bitmap2;
+ unsigned long long entry, per_filter1, per_filter2;
printf("Current BPF sysctl settings:\n");
system("sysctl net.core.bpf_jit_enable");
@@ -101,35 +161,82 @@ int main(int argc, char *argv[])
ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
assert(ret == 0);
- /* One filter */
- ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
+ /* One filter resulting in a bitmap */
+ ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &bitmap_prog);
assert(ret == 0);
- filter1 = timing(CLOCK_PROCESS_CPUTIME_ID, samples) / samples;
- printf("getpid RET_ALLOW 1 filter: %llu ns\n", filter1);
+ bitmap1 = timing(CLOCK_PROCESS_CPUTIME_ID, samples) / samples;
+ printf("getpid RET_ALLOW 1 filter (bitmap): %llu ns\n", bitmap1);
+
+ /* Second filter resulting in a bitmap */
+ ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &bitmap_prog);
+ assert(ret == 0);
- if (filter1 == native)
- printf("No overhead measured!? Try running again with more samples.\n");
+ bitmap2 = timing(CLOCK_PROCESS_CPUTIME_ID, samples) / samples;
+ printf("getpid RET_ALLOW 2 filters (bitmap): %llu ns\n", bitmap2);
- /* Two filters */
+ /* Third filter, can no longer be converted to bitmap */
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
assert(ret == 0);
- filter2 = timing(CLOCK_PROCESS_CPUTIME_ID, samples) / samples;
- printf("getpid RET_ALLOW 2 filters: %llu ns\n", filter2);
-
- /* Calculations */
- printf("Estimated total seccomp overhead for 1 filter: %llu ns\n",
- filter1 - native);
+ filter1 = timing(CLOCK_PROCESS_CPUTIME_ID, samples) / samples;
+ printf("getpid RET_ALLOW 3 filters (full): %llu ns\n", filter1);
- printf("Estimated total seccomp overhead for 2 filters: %llu ns\n",
- filter2 - native);
+ /* Fourth filter, can not be converted to bitmap because of filter 3 */
+ ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &bitmap_prog);
+ assert(ret == 0);
- printf("Estimated seccomp per-filter overhead: %llu ns\n",
- filter2 - filter1);
+ filter2 = timing(CLOCK_PROCESS_CPUTIME_ID, samples) / samples;
+ printf("getpid RET_ALLOW 4 filters (full): %llu ns\n", filter2);
+
+ /* Estimations */
+#define ESTIMATE(fmt, var, what) do { \
+ var = (what); \
+ printf("Estimated " fmt ": %llu ns\n", var); \
+ if (var > INT_MAX) \
+ goto more_samples; \
+ } while (0)
+
+ ESTIMATE("total seccomp overhead for 1 bitmapped filter", calc,
+ bitmap1 - native);
+ ESTIMATE("total seccomp overhead for 2 bitmapped filters", calc,
+ bitmap2 - native);
+ ESTIMATE("total seccomp overhead for 3 full filters", calc,
+ filter1 - native);
+ ESTIMATE("total seccomp overhead for 4 full filters", calc,
+ filter2 - native);
+ ESTIMATE("seccomp entry overhead", entry,
+ bitmap1 - native - (bitmap2 - bitmap1));
+ ESTIMATE("seccomp per-filter overhead (last 2 diff)", per_filter1,
+ filter2 - filter1);
+ ESTIMATE("seccomp per-filter overhead (filters / 4)", per_filter2,
+ (filter2 - native - entry) / 4);
+
+ printf("Expectations:\n");
+ ret |= compare("native", "≤", "1 bitmap", native, le, bitmap1);
+ bits = compare("native", "≤", "1 filter", native, le, filter1);
+ if (bits)
+ goto more_samples;
+
+ ret |= compare("per-filter (last 2 diff)", "≈", "per-filter (filters / 4)",
+ per_filter1, approx, per_filter2);
+
+ bits = compare("1 bitmapped", "≈", "2 bitmapped",
+ bitmap1 - native, approx, bitmap2 - native);
+ if (bits) {
+ printf("Skipping constant action bitmap expectations: they appear unsupported.\n");
+ goto out;
+ }
- printf("Estimated seccomp entry overhead: %llu ns\n",
- filter1 - native - (filter2 - filter1));
+ ret |= compare("entry", "≈", "1 bitmapped", entry, approx, bitmap1 - native);
+ ret |= compare("entry", "≈", "2 bitmapped", entry, approx, bitmap2 - native);
+ ret |= compare("native + entry + (per filter * 4)", "≈", "4 filters total",
+ entry + (per_filter1 * 4) + native, approx, filter2);
+ if (ret == 0)
+ goto out;
+more_samples:
+ printf("Saw unexpected benchmark result. Try running again with more samples?\n");
+out:
return 0;
}
diff --git a/tools/testing/selftests/seccomp/settings b/tools/testing/selftests/seccomp/settings
index ba4d85f74cd6..6091b45d226b 100644
--- a/tools/testing/selftests/seccomp/settings
+++ b/tools/testing/selftests/seccomp/settings
@@ -1 +1 @@
-timeout=90
+timeout=120
diff --git a/tools/testing/selftests/vDSO/Makefile b/tools/testing/selftests/vDSO/Makefile
index 0069f2f83f86..d53a4d8008f9 100644
--- a/tools/testing/selftests/vDSO/Makefile
+++ b/tools/testing/selftests/vDSO/Makefile
@@ -5,13 +5,16 @@ uname_M := $(shell uname -m 2>/dev/null || echo not)
ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
TEST_GEN_PROGS := $(OUTPUT)/vdso_test_gettimeofday $(OUTPUT)/vdso_test_getcpu
-ifeq ($(ARCH),x86)
+TEST_GEN_PROGS += $(OUTPUT)/vdso_test_abi
+TEST_GEN_PROGS += $(OUTPUT)/vdso_test_clock_getres
+ifeq ($(ARCH),$(filter $(ARCH),x86 x86_64))
TEST_GEN_PROGS += $(OUTPUT)/vdso_standalone_test_x86
endif
+TEST_GEN_PROGS += $(OUTPUT)/vdso_test_correctness
-ifndef CROSS_COMPILE
CFLAGS := -std=gnu99
CFLAGS_vdso_standalone_test_x86 := -nostdlib -fno-asynchronous-unwind-tables -fno-stack-protector
+LDFLAGS_vdso_test_correctness := -ldl
ifeq ($(CONFIG_X86_32),y)
LDLIBS += -lgcc_s
endif
@@ -19,9 +22,14 @@ endif
all: $(TEST_GEN_PROGS)
$(OUTPUT)/vdso_test_gettimeofday: parse_vdso.c vdso_test_gettimeofday.c
$(OUTPUT)/vdso_test_getcpu: parse_vdso.c vdso_test_getcpu.c
+$(OUTPUT)/vdso_test_abi: parse_vdso.c vdso_test_abi.c
+$(OUTPUT)/vdso_test_clock_getres: vdso_test_clock_getres.c
$(OUTPUT)/vdso_standalone_test_x86: vdso_standalone_test_x86.c parse_vdso.c
$(CC) $(CFLAGS) $(CFLAGS_vdso_standalone_test_x86) \
vdso_standalone_test_x86.c parse_vdso.c \
-o $@
-
-endif
+$(OUTPUT)/vdso_test_correctness: vdso_test_correctness.c
+ $(CC) $(CFLAGS) \
+ vdso_test_correctness.c \
+ -o $@ \
+ $(LDFLAGS_vdso_test_correctness)
diff --git a/tools/testing/selftests/vDSO/vdso_config.h b/tools/testing/selftests/vDSO/vdso_config.h
new file mode 100644
index 000000000000..6a6fe8d4ff55
--- /dev/null
+++ b/tools/testing/selftests/vDSO/vdso_config.h
@@ -0,0 +1,92 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * vdso_config.h: Configuration options for vDSO tests.
+ * Copyright (c) 2019 Arm Ltd.
+ */
+#ifndef __VDSO_CONFIG_H__
+#define __VDSO_CONFIG_H__
+
+/*
+ * Each architecture exports its vDSO implementation with different names
+ * and a different version from the others, so we need to handle it as a
+ * special case.
+ */
+#if defined(__arm__)
+#define VDSO_VERSION 0
+#define VDSO_NAMES 1
+#define VDSO_32BIT 1
+#elif defined(__aarch64__)
+#define VDSO_VERSION 3
+#define VDSO_NAMES 0
+#elif defined(__powerpc__)
+#define VDSO_VERSION 1
+#define VDSO_NAMES 0
+#define VDSO_32BIT 1
+#elif defined(__powerpc64__)
+#define VDSO_VERSION 1
+#define VDSO_NAMES 0
+#elif defined (__s390__)
+#define VDSO_VERSION 2
+#define VDSO_NAMES 0
+#define VDSO_32BIT 1
+#elif defined (__s390X__)
+#define VDSO_VERSION 2
+#define VDSO_NAMES 0
+#elif defined(__mips__)
+#define VDSO_VERSION 0
+#define VDSO_NAMES 1
+#define VDSO_32BIT 1
+#elif defined(__sparc__)
+#define VDSO_VERSION 0
+#define VDSO_NAMES 1
+#define VDSO_32BIT 1
+#elif defined(__i386__)
+#define VDSO_VERSION 0
+#define VDSO_NAMES 1
+#define VDSO_32BIT 1
+#elif defined(__x86_64__)
+#define VDSO_VERSION 0
+#define VDSO_NAMES 1
+#elif defined(__riscv__)
+#define VDSO_VERSION 5
+#define VDSO_NAMES 1
+#define VDSO_32BIT 1
+#else /* nds32 */
+#define VDSO_VERSION 4
+#define VDSO_NAMES 1
+#define VDSO_32BIT 1
+#endif
+
+static const char *versions[6] = {
+ "LINUX_2.6",
+ "LINUX_2.6.15",
+ "LINUX_2.6.29",
+ "LINUX_2.6.39",
+ "LINUX_4",
+ "LINUX_4.15",
+};
+
+static const char *names[2][6] = {
+ {
+ "__kernel_gettimeofday",
+ "__kernel_clock_gettime",
+ "__kernel_time",
+ "__kernel_clock_getres",
+ "__kernel_getcpu",
+#if defined(VDSO_32BIT)
+ "__kernel_clock_gettime64",
+#endif
+ },
+ {
+ "__vdso_gettimeofday",
+ "__vdso_clock_gettime",
+ "__vdso_time",
+ "__vdso_clock_getres",
+ "__vdso_getcpu",
+#if defined(VDSO_32BIT)
+ "__vdso_clock_gettime64",
+#endif
+ },
+};
+
+#endif /* __VDSO_CONFIG_H__ */
diff --git a/tools/testing/selftests/vDSO/vdso_test_abi.c b/tools/testing/selftests/vDSO/vdso_test_abi.c
new file mode 100644
index 000000000000..3d603f1394af
--- /dev/null
+++ b/tools/testing/selftests/vDSO/vdso_test_abi.c
@@ -0,0 +1,244 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * vdso_full_test.c: Sample code to test all the timers.
+ * Copyright (c) 2019 Arm Ltd.
+ *
+ * Compile with:
+ * gcc -std=gnu99 vdso_full_test.c parse_vdso.c
+ *
+ */
+
+#include <stdint.h>
+#include <elf.h>
+#include <stdio.h>
+#include <time.h>
+#include <sys/auxv.h>
+#include <sys/time.h>
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#include "../kselftest.h"
+#include "vdso_config.h"
+
+extern void *vdso_sym(const char *version, const char *name);
+extern void vdso_init_from_sysinfo_ehdr(uintptr_t base);
+extern void vdso_init_from_auxv(void *auxv);
+
+static const char *version;
+static const char **name;
+
+typedef long (*vdso_gettimeofday_t)(struct timeval *tv, struct timezone *tz);
+typedef long (*vdso_clock_gettime_t)(clockid_t clk_id, struct timespec *ts);
+typedef long (*vdso_clock_getres_t)(clockid_t clk_id, struct timespec *ts);
+typedef time_t (*vdso_time_t)(time_t *t);
+
+static int vdso_test_gettimeofday(void)
+{
+ /* Find gettimeofday. */
+ vdso_gettimeofday_t vdso_gettimeofday =
+ (vdso_gettimeofday_t)vdso_sym(version, name[0]);
+
+ if (!vdso_gettimeofday) {
+ printf("Could not find %s\n", name[0]);
+ return KSFT_SKIP;
+ }
+
+ struct timeval tv;
+ long ret = vdso_gettimeofday(&tv, 0);
+
+ if (ret == 0) {
+ printf("The time is %lld.%06lld\n",
+ (long long)tv.tv_sec, (long long)tv.tv_usec);
+ } else {
+ printf("%s failed\n", name[0]);
+ return KSFT_FAIL;
+ }
+
+ return KSFT_PASS;
+}
+
+static int vdso_test_clock_gettime(clockid_t clk_id)
+{
+ /* Find clock_gettime. */
+ vdso_clock_gettime_t vdso_clock_gettime =
+ (vdso_clock_gettime_t)vdso_sym(version, name[1]);
+
+ if (!vdso_clock_gettime) {
+ printf("Could not find %s\n", name[1]);
+ return KSFT_SKIP;
+ }
+
+ struct timespec ts;
+ long ret = vdso_clock_gettime(clk_id, &ts);
+
+ if (ret == 0) {
+ printf("The time is %lld.%06lld\n",
+ (long long)ts.tv_sec, (long long)ts.tv_nsec);
+ } else {
+ printf("%s failed\n", name[1]);
+ return KSFT_FAIL;
+ }
+
+ return KSFT_PASS;
+}
+
+static int vdso_test_time(void)
+{
+ /* Find time. */
+ vdso_time_t vdso_time =
+ (vdso_time_t)vdso_sym(version, name[2]);
+
+ if (!vdso_time) {
+ printf("Could not find %s\n", name[2]);
+ return KSFT_SKIP;
+ }
+
+ long ret = vdso_time(NULL);
+
+ if (ret > 0) {
+ printf("The time in hours since January 1, 1970 is %lld\n",
+ (long long)(ret / 3600));
+ } else {
+ printf("%s failed\n", name[2]);
+ return KSFT_FAIL;
+ }
+
+ return KSFT_PASS;
+}
+
+static int vdso_test_clock_getres(clockid_t clk_id)
+{
+ /* Find clock_getres. */
+ vdso_clock_getres_t vdso_clock_getres =
+ (vdso_clock_getres_t)vdso_sym(version, name[3]);
+
+ if (!vdso_clock_getres) {
+ printf("Could not find %s\n", name[3]);
+ return KSFT_SKIP;
+ }
+
+ struct timespec ts, sys_ts;
+ long ret = vdso_clock_getres(clk_id, &ts);
+
+ if (ret == 0) {
+ printf("The resolution is %lld %lld\n",
+ (long long)ts.tv_sec, (long long)ts.tv_nsec);
+ } else {
+ printf("%s failed\n", name[3]);
+ return KSFT_FAIL;
+ }
+
+ ret = syscall(SYS_clock_getres, clk_id, &sys_ts);
+
+ if ((sys_ts.tv_sec != ts.tv_sec) || (sys_ts.tv_nsec != ts.tv_nsec)) {
+ printf("%s failed\n", name[3]);
+ return KSFT_FAIL;
+ }
+
+ return KSFT_PASS;
+}
+
+const char *vdso_clock_name[12] = {
+ "CLOCK_REALTIME",
+ "CLOCK_MONOTONIC",
+ "CLOCK_PROCESS_CPUTIME_ID",
+ "CLOCK_THREAD_CPUTIME_ID",
+ "CLOCK_MONOTONIC_RAW",
+ "CLOCK_REALTIME_COARSE",
+ "CLOCK_MONOTONIC_COARSE",
+ "CLOCK_BOOTTIME",
+ "CLOCK_REALTIME_ALARM",
+ "CLOCK_BOOTTIME_ALARM",
+ "CLOCK_SGI_CYCLE",
+ "CLOCK_TAI",
+};
+
+/*
+ * This function calls vdso_test_clock_gettime and vdso_test_clock_getres
+ * with different values for clock_id.
+ */
+static inline int vdso_test_clock(clockid_t clock_id)
+{
+ int ret0, ret1;
+
+ ret0 = vdso_test_clock_gettime(clock_id);
+ /* A skipped test is considered passed */
+ if (ret0 == KSFT_SKIP)
+ ret0 = KSFT_PASS;
+
+ ret1 = vdso_test_clock_getres(clock_id);
+ /* A skipped test is considered passed */
+ if (ret1 == KSFT_SKIP)
+ ret1 = KSFT_PASS;
+
+ ret0 += ret1;
+
+ printf("clock_id: %s", vdso_clock_name[clock_id]);
+
+ if (ret0 > 0)
+ printf(" [FAIL]\n");
+ else
+ printf(" [PASS]\n");
+
+ return ret0;
+}
+
+int main(int argc, char **argv)
+{
+ unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
+ int ret;
+
+ if (!sysinfo_ehdr) {
+ printf("AT_SYSINFO_EHDR is not present!\n");
+ return KSFT_SKIP;
+ }
+
+ version = versions[VDSO_VERSION];
+ name = (const char **)&names[VDSO_NAMES];
+
+ printf("[vDSO kselftest] VDSO_VERSION: %s\n", version);
+
+ vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR));
+
+ ret = vdso_test_gettimeofday();
+
+#if _POSIX_TIMERS > 0
+
+#ifdef CLOCK_REALTIME
+ ret += vdso_test_clock(CLOCK_REALTIME);
+#endif
+
+#ifdef CLOCK_BOOTTIME
+ ret += vdso_test_clock(CLOCK_BOOTTIME);
+#endif
+
+#ifdef CLOCK_TAI
+ ret += vdso_test_clock(CLOCK_TAI);
+#endif
+
+#ifdef CLOCK_REALTIME_COARSE
+ ret += vdso_test_clock(CLOCK_REALTIME_COARSE);
+#endif
+
+#ifdef CLOCK_MONOTONIC
+ ret += vdso_test_clock(CLOCK_MONOTONIC);
+#endif
+
+#ifdef CLOCK_MONOTONIC_RAW
+ ret += vdso_test_clock(CLOCK_MONOTONIC_RAW);
+#endif
+
+#ifdef CLOCK_MONOTONIC_COARSE
+ ret += vdso_test_clock(CLOCK_MONOTONIC_COARSE);
+#endif
+
+#endif
+
+ ret += vdso_test_time();
+
+ if (ret > 0)
+ return KSFT_FAIL;
+
+ return KSFT_PASS;
+}
diff --git a/tools/testing/selftests/vDSO/vdso_test_clock_getres.c b/tools/testing/selftests/vDSO/vdso_test_clock_getres.c
new file mode 100644
index 000000000000..15dcee16ff72
--- /dev/null
+++ b/tools/testing/selftests/vDSO/vdso_test_clock_getres.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+/*
+ * vdso_clock_getres.c: Sample code to test clock_getres.
+ * Copyright (c) 2019 Arm Ltd.
+ *
+ * Compile with:
+ * gcc -std=gnu99 vdso_clock_getres.c
+ *
+ * Tested on ARM, ARM64, MIPS32, x86 (32-bit and 64-bit),
+ * Power (32-bit and 64-bit), S390x (32-bit and 64-bit).
+ * Might work on other architectures.
+ */
+
+#define _GNU_SOURCE
+#include <elf.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/auxv.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#include "../kselftest.h"
+
+static long syscall_clock_getres(clockid_t _clkid, struct timespec *_ts)
+{
+ long ret;
+
+ ret = syscall(SYS_clock_getres, _clkid, _ts);
+
+ return ret;
+}
+
+const char *vdso_clock_name[12] = {
+ "CLOCK_REALTIME",
+ "CLOCK_MONOTONIC",
+ "CLOCK_PROCESS_CPUTIME_ID",
+ "CLOCK_THREAD_CPUTIME_ID",
+ "CLOCK_MONOTONIC_RAW",
+ "CLOCK_REALTIME_COARSE",
+ "CLOCK_MONOTONIC_COARSE",
+ "CLOCK_BOOTTIME",
+ "CLOCK_REALTIME_ALARM",
+ "CLOCK_BOOTTIME_ALARM",
+ "CLOCK_SGI_CYCLE",
+ "CLOCK_TAI",
+};
+
+/*
+ * This function calls clock_getres in vdso and by system call
+ * with different values for clock_id.
+ *
+ * Example of output:
+ *
+ * clock_id: CLOCK_REALTIME [PASS]
+ * clock_id: CLOCK_BOOTTIME [PASS]
+ * clock_id: CLOCK_TAI [PASS]
+ * clock_id: CLOCK_REALTIME_COARSE [PASS]
+ * clock_id: CLOCK_MONOTONIC [PASS]
+ * clock_id: CLOCK_MONOTONIC_RAW [PASS]
+ * clock_id: CLOCK_MONOTONIC_COARSE [PASS]
+ */
+static inline int vdso_test_clock(unsigned int clock_id)
+{
+ struct timespec x, y;
+
+ printf("clock_id: %s", vdso_clock_name[clock_id]);
+ clock_getres(clock_id, &x);
+ syscall_clock_getres(clock_id, &y);
+
+ if ((x.tv_sec != y.tv_sec) || (x.tv_nsec != y.tv_nsec)) {
+ printf(" [FAIL]\n");
+ return KSFT_FAIL;
+ }
+
+ printf(" [PASS]\n");
+ return KSFT_PASS;
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+#if _POSIX_TIMERS > 0
+
+#ifdef CLOCK_REALTIME
+ ret = vdso_test_clock(CLOCK_REALTIME);
+#endif
+
+#ifdef CLOCK_BOOTTIME
+ ret += vdso_test_clock(CLOCK_BOOTTIME);
+#endif
+
+#ifdef CLOCK_TAI
+ ret += vdso_test_clock(CLOCK_TAI);
+#endif
+
+#ifdef CLOCK_REALTIME_COARSE
+ ret += vdso_test_clock(CLOCK_REALTIME_COARSE);
+#endif
+
+#ifdef CLOCK_MONOTONIC
+ ret += vdso_test_clock(CLOCK_MONOTONIC);
+#endif
+
+#ifdef CLOCK_MONOTONIC_RAW
+ ret += vdso_test_clock(CLOCK_MONOTONIC_RAW);
+#endif
+
+#ifdef CLOCK_MONOTONIC_COARSE
+ ret += vdso_test_clock(CLOCK_MONOTONIC_COARSE);
+#endif
+
+#endif
+ if (ret > 0)
+ return KSFT_FAIL;
+
+ return KSFT_PASS;
+}
diff --git a/tools/testing/selftests/x86/test_vdso.c b/tools/testing/selftests/vDSO/vdso_test_correctness.c
index 42052db0f870..5029ef9b228c 100644
--- a/tools/testing/selftests/x86/test_vdso.c
+++ b/tools/testing/selftests/vDSO/vdso_test_correctness.c
@@ -19,6 +19,10 @@
#include <stdbool.h>
#include <limits.h>
+#include "vdso_config.h"
+
+static const char **name;
+
#ifndef SYS_getcpu
# ifdef __x86_64__
# define SYS_getcpu 309
@@ -27,6 +31,17 @@
# endif
#endif
+#ifndef __NR_clock_gettime64
+#define __NR_clock_gettime64 403
+#endif
+
+#ifndef __kernel_timespec
+struct __kernel_timespec {
+ long long tv_sec;
+ long long tv_nsec;
+};
+#endif
+
/* max length of lines in /proc/self/maps - anything longer is skipped here */
#define MAPS_LINE_LEN 128
@@ -36,6 +51,10 @@ typedef int (*vgettime_t)(clockid_t, struct timespec *);
vgettime_t vdso_clock_gettime;
+typedef int (*vgettime64_t)(clockid_t, struct __kernel_timespec *);
+
+vgettime64_t vdso_clock_gettime64;
+
typedef long (*vgtod_t)(struct timeval *tv, struct timezone *tz);
vgtod_t vdso_gettimeofday;
@@ -99,17 +118,23 @@ static void fill_function_pointers()
return;
}
- vdso_getcpu = (getcpu_t)dlsym(vdso, "__vdso_getcpu");
+ vdso_getcpu = (getcpu_t)dlsym(vdso, name[4]);
if (!vdso_getcpu)
printf("Warning: failed to find getcpu in vDSO\n");
vgetcpu = (getcpu_t) vsyscall_getcpu();
- vdso_clock_gettime = (vgettime_t)dlsym(vdso, "__vdso_clock_gettime");
+ vdso_clock_gettime = (vgettime_t)dlsym(vdso, name[1]);
if (!vdso_clock_gettime)
printf("Warning: failed to find clock_gettime in vDSO\n");
- vdso_gettimeofday = (vgtod_t)dlsym(vdso, "__vdso_gettimeofday");
+#if defined(VDSO_32BIT)
+ vdso_clock_gettime64 = (vgettime64_t)dlsym(vdso, name[5]);
+ if (!vdso_clock_gettime64)
+ printf("Warning: failed to find clock_gettime64 in vDSO\n");
+#endif
+
+ vdso_gettimeofday = (vgtod_t)dlsym(vdso, name[0]);
if (!vdso_gettimeofday)
printf("Warning: failed to find gettimeofday in vDSO\n");
@@ -126,6 +151,11 @@ static inline int sys_clock_gettime(clockid_t id, struct timespec *ts)
return syscall(__NR_clock_gettime, id, ts);
}
+static inline int sys_clock_gettime64(clockid_t id, struct __kernel_timespec *ts)
+{
+ return syscall(__NR_clock_gettime64, id, ts);
+}
+
static inline int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
{
return syscall(__NR_gettimeofday, tv, tz);
@@ -191,6 +221,15 @@ static bool ts_leq(const struct timespec *a, const struct timespec *b)
return a->tv_nsec <= b->tv_nsec;
}
+static bool ts64_leq(const struct __kernel_timespec *a,
+ const struct __kernel_timespec *b)
+{
+ if (a->tv_sec != b->tv_sec)
+ return a->tv_sec < b->tv_sec;
+ else
+ return a->tv_nsec <= b->tv_nsec;
+}
+
static bool tv_leq(const struct timeval *a, const struct timeval *b)
{
if (a->tv_sec != b->tv_sec)
@@ -254,7 +293,10 @@ static void test_one_clock_gettime(int clock, const char *name)
if (!ts_leq(&start, &vdso) || !ts_leq(&vdso, &end)) {
printf("[FAIL]\tTimes are out of sequence\n");
nerrs++;
+ return;
}
+
+ printf("[OK]\tTest Passed.\n");
}
static void test_clock_gettime(void)
@@ -275,6 +317,70 @@ static void test_clock_gettime(void)
test_one_clock_gettime(INT_MAX, "invalid");
}
+static void test_one_clock_gettime64(int clock, const char *name)
+{
+ struct __kernel_timespec start, vdso, end;
+ int vdso_ret, end_ret;
+
+ printf("[RUN]\tTesting clock_gettime64 for clock %s (%d)...\n", name, clock);
+
+ if (sys_clock_gettime64(clock, &start) < 0) {
+ if (errno == EINVAL) {
+ vdso_ret = vdso_clock_gettime64(clock, &vdso);
+ if (vdso_ret == -EINVAL) {
+ printf("[OK]\tNo such clock.\n");
+ } else {
+ printf("[FAIL]\tNo such clock, but __vdso_clock_gettime64 returned %d\n", vdso_ret);
+ nerrs++;
+ }
+ } else {
+ printf("[WARN]\t clock_gettime64(%d) syscall returned error %d\n", clock, errno);
+ }
+ return;
+ }
+
+ vdso_ret = vdso_clock_gettime64(clock, &vdso);
+ end_ret = sys_clock_gettime64(clock, &end);
+
+ if (vdso_ret != 0 || end_ret != 0) {
+ printf("[FAIL]\tvDSO returned %d, syscall errno=%d\n",
+ vdso_ret, errno);
+ nerrs++;
+ return;
+ }
+
+ printf("\t%llu.%09ld %llu.%09ld %llu.%09ld\n",
+ (unsigned long long)start.tv_sec, start.tv_nsec,
+ (unsigned long long)vdso.tv_sec, vdso.tv_nsec,
+ (unsigned long long)end.tv_sec, end.tv_nsec);
+
+ if (!ts64_leq(&start, &vdso) || !ts64_leq(&vdso, &end)) {
+ printf("[FAIL]\tTimes are out of sequence\n");
+ nerrs++;
+ return;
+ }
+
+ printf("[OK]\tTest Passed.\n");
+}
+
+static void test_clock_gettime64(void)
+{
+ if (!vdso_clock_gettime64) {
+ printf("[SKIP]\tNo vDSO, so skipping clock_gettime64() tests\n");
+ return;
+ }
+
+ for (int clock = 0; clock < sizeof(clocknames) / sizeof(clocknames[0]);
+ clock++) {
+ test_one_clock_gettime64(clock, clocknames[clock]);
+ }
+
+ /* Also test some invalid clock ids */
+ test_one_clock_gettime64(-1, "invalid");
+ test_one_clock_gettime64(INT_MIN, "invalid");
+ test_one_clock_gettime64(INT_MAX, "invalid");
+}
+
static void test_gettimeofday(void)
{
struct timeval start, vdso, end;
@@ -327,9 +433,12 @@ static void test_gettimeofday(void)
int main(int argc, char **argv)
{
+ name = (const char **)&names[VDSO_NAMES];
+
fill_function_pointers();
test_clock_gettime();
+ test_clock_gettime64();
test_gettimeofday();
/*
diff --git a/tools/testing/selftests/vm/userfaultfd.c b/tools/testing/selftests/vm/userfaultfd.c
index 9d8650d4ba5a..92b8ec423201 100644
--- a/tools/testing/selftests/vm/userfaultfd.c
+++ b/tools/testing/selftests/vm/userfaultfd.c
@@ -906,7 +906,7 @@ static int faulting_process(int signal_test)
count_verify[nr]);
}
/*
- * Trigger write protection if there is by writting
+ * Trigger write protection if there is by writing
* the same value back.
*/
*area_count(area_dst, nr) = count;
@@ -934,7 +934,7 @@ static int faulting_process(int signal_test)
count_verify[nr]); exit(1);
}
/*
- * Trigger write protection if there is by writting
+ * Trigger write protection if there is by writing
* the same value back.
*/
*area_count(area_dst, nr) = count;
diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile
index 6703c7906b71..333980375bc7 100644
--- a/tools/testing/selftests/x86/Makefile
+++ b/tools/testing/selftests/x86/Makefile
@@ -12,7 +12,7 @@ CAN_BUILD_WITH_NOPIE := $(shell ./check_cc.sh $(CC) trivial_program.c -no-pie)
TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt test_mremap_vdso \
check_initial_reg_state sigreturn iopl ioperm \
- test_vdso test_vsyscall mov_ss_trap \
+ test_vsyscall mov_ss_trap \
syscall_arg_fault fsgsbase_restore
TARGETS_C_32BIT_ONLY := entry_from_vm86 test_syscall_vdso unwind_vdso \
test_FCMOV test_FCOMI test_FISTTP \