xref: /freebsd/tools/test/stress2/misc/rdgsbase.sh (revision 4d846d260e2b9a3d4d0a701462568268cbfe7a5b)
18a272653SPeter Holm#!/bin/sh
28a272653SPeter Holm
38a272653SPeter Holm#
4*4d846d26SWarner Losh# SPDX-License-Identifier: BSD-2-Clause
58a272653SPeter Holm#
68a272653SPeter Holm# Copyright (c) 2017 Konstantin Belousov <kib@FreeBSD.org>
78a272653SPeter Holm#
88a272653SPeter Holm# Redistribution and use in source and binary forms, with or without
98a272653SPeter Holm# modification, are permitted provided that the following conditions
108a272653SPeter Holm# are met:
118a272653SPeter Holm# 1. Redistributions of source code must retain the above copyright
128a272653SPeter Holm#    notice, this list of conditions and the following disclaimer.
138a272653SPeter Holm# 2. Redistributions in binary form must reproduce the above copyright
148a272653SPeter Holm#    notice, this list of conditions and the following disclaimer in the
158a272653SPeter Holm#    documentation and/or other materials provided with the distribution.
168a272653SPeter Holm#
178a272653SPeter Holm# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
188a272653SPeter Holm# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
198a272653SPeter Holm# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
208a272653SPeter Holm# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
218a272653SPeter Holm# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
228a272653SPeter Holm# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
238a272653SPeter Holm# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
248a272653SPeter Holm# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
258a272653SPeter Holm# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
268a272653SPeter Holm# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
278a272653SPeter Holm# SUCH DAMAGE.
288a272653SPeter Holm#
298a272653SPeter Holm
308a272653SPeter Holm# Test scenario for "D12023: Make WRFSBASE and WRGSBASE functional."
318a272653SPeter Holm
328a272653SPeter Holm[ `uname -m` = "amd64" ] || exit 0
338a272653SPeter Holm
348a272653SPeter Holm. ../default.cfg
358a272653SPeter Holm
368a272653SPeter Holmcat > /tmp/rdgsbase.c <<EOF
378a272653SPeter Holm/*
388a272653SPeter HolmBelow is the updated version of the test program.  It is probably most
398a272653SPeter Holmuseful to run it in parallel with the normal stress jobs.  Please note
408a272653SPeter Holmthat the program starts two CPU-intensive threads per core, so the
418a272653SPeter Holmwhole test load would be run 4x slower.
428a272653SPeter Holm
438a272653SPeter HolmAlso, it is very useful to try to run hwpmc measurements in parallel, at
448a272653SPeter Holmleast for some time.  E.g.,
458a272653SPeter Holm	pmcstat -S instructions -T
468a272653SPeter Holmin a terminal in parallel with other activities is enough.  I do not need
478a272653SPeter Holmany numbers from hwpmc, just the fact that the driver causes the series of
488a272653SPeter HolmNMI to adjust the load for testing.
498a272653SPeter Holm*/
508a272653SPeter Holm
518a272653SPeter Holm/* $Id: rdgsbase.c,v 1.9 2017/08/13 16:22:01 kostik Exp kostik $ */
528a272653SPeter Holm
538a272653SPeter Holm#include <sys/param.h>
548a272653SPeter Holm#include <sys/sysctl.h>
558a272653SPeter Holm#include <err.h>
568a272653SPeter Holm#include <pthread.h>
578a272653SPeter Holm#include <signal.h>
588a272653SPeter Holm#include <stdio.h>
598a272653SPeter Holm#include <stdlib.h>
608a272653SPeter Holm#include <unistd.h>
618a272653SPeter Holm#include <machine/sysarch.h>
628a272653SPeter Holm#include <machine/specialreg.h>
638a272653SPeter Holm#include <machine/cpufunc.h>
648a272653SPeter Holm
658a272653SPeter Holmvoid
668a272653SPeter Holmhand(int i __unused) {  /* handler */
678a272653SPeter Holm	_exit(0);
688a272653SPeter Holm}
698a272653SPeter Holm
708a272653SPeter Holmstatic void *
718a272653SPeter Holmrungs(void *arg __unused)
728a272653SPeter Holm{
738a272653SPeter Holm	volatile char x[1024];
748a272653SPeter Holm	unsigned i;
758a272653SPeter Holm	uint64_t y, oldbase;
768a272653SPeter Holm
778a272653SPeter Holm	oldbase = rdgsbase();
788a272653SPeter Holm	for (i = 0;;) {
798a272653SPeter Holm		wrgsbase((uintptr_t)&x[i]);
808a272653SPeter Holm		if (rdgsbase() != (uintptr_t)&x[i]) {
818a272653SPeter Holm			wrgsbase(oldbase);
828a272653SPeter Holm			printf("bug1 %lx %lx\n", rdgsbase(), (uintptr_t)&x[i]);
838a272653SPeter Holm			exit(1);
848a272653SPeter Holm		}
858a272653SPeter Holm		sysarch(AMD64_GET_GSBASE, &y);
868a272653SPeter Holm		if (y != (uintptr_t)&x[i]) {
878a272653SPeter Holm			wrgsbase(oldbase);
888a272653SPeter Holm			printf("bug2 %lx %lx\n", y, (uintptr_t)&x[i]);
898a272653SPeter Holm			exit(1);
908a272653SPeter Holm		}
918a272653SPeter Holm		i++;
928a272653SPeter Holm		if (i >= nitems(x))
938a272653SPeter Holm			i = 0;
948a272653SPeter Holm	}
958a272653SPeter Holm	return (NULL);
968a272653SPeter Holm}
978a272653SPeter Holm
988a272653SPeter Holmstatic void *
998a272653SPeter Holmrunfs(void *arg __unused)
1008a272653SPeter Holm{
1018a272653SPeter Holm	volatile char x[1024];
1028a272653SPeter Holm	unsigned i;
1038a272653SPeter Holm	uint64_t y, oldbase;
1048a272653SPeter Holm
1058a272653SPeter Holm	oldbase = rdfsbase();
1068a272653SPeter Holm	for (i = 0;;) {
1078a272653SPeter Holm		wrfsbase((uintptr_t)&x[i]);
1088a272653SPeter Holm		if (rdfsbase() != (uintptr_t)&x[i]) {
1098a272653SPeter Holm			wrfsbase(oldbase);
1108a272653SPeter Holm			printf("bug3 %lx %lx\n", rdfsbase(), (uintptr_t)&x[i]);
1118a272653SPeter Holm			exit(1);
1128a272653SPeter Holm		}
1138a272653SPeter Holm		sysarch(AMD64_GET_FSBASE, &y);
1148a272653SPeter Holm		if (y != (uintptr_t)&x[i]) {
1158a272653SPeter Holm			wrfsbase(oldbase);
1168a272653SPeter Holm			printf("bug4 %lx %lx\n", y, (uintptr_t)&x[i]);
1178a272653SPeter Holm			exit(1);
1188a272653SPeter Holm		}
1198a272653SPeter Holm		i++;
1208a272653SPeter Holm		if (i > nitems(x))
1218a272653SPeter Holm			i = 0;
1228a272653SPeter Holm	}
1238a272653SPeter Holm	return (NULL);
1248a272653SPeter Holm}
1258a272653SPeter Holm
1268a272653SPeter Holmstatic void
1278a272653SPeter Holmstart(int nthreads)
1288a272653SPeter Holm{
1298a272653SPeter Holm	pthread_t thrs[nthreads * 2];
1308a272653SPeter Holm	int error, i;
1318a272653SPeter Holm
1328a272653SPeter Holm	for (i = 0; i < nthreads; i++) {
1338a272653SPeter Holm		error = pthread_create(&thrs[i], NULL, rungs, NULL);
1348a272653SPeter Holm		if (error != 0)
1358a272653SPeter Holm			errc(1, error, "pthread_create");
1368a272653SPeter Holm	}
1378a272653SPeter Holm	for (; i < 2 * nthreads; i++) {
1388a272653SPeter Holm		error = pthread_create(&thrs[i], NULL, runfs, NULL);
1398a272653SPeter Holm		if (error != 0)
1408a272653SPeter Holm			errc(1, error, "pthread_create");
1418a272653SPeter Holm	}
1428a272653SPeter Holm}
1438a272653SPeter Holm
1448a272653SPeter Holmint
1458a272653SPeter Holmmain(void)
1468a272653SPeter Holm{
1478a272653SPeter Holm	static const int mib[2] = {CTL_HW, HW_NCPU};
1488a272653SPeter Holm	int error, nthreads;
1498a272653SPeter Holm	u_int p[4];
1508a272653SPeter Holm	size_t len;
1518a272653SPeter Holm
1528a272653SPeter Holm	do_cpuid(0, p);
1538a272653SPeter Holm	if (p[0] < 0x7) {
1548a272653SPeter Holm		fprintf(stderr, "CPU does not support extended functions\n");
1558a272653SPeter Holm		return (1);
1568a272653SPeter Holm	}
1578a272653SPeter Holm	cpuid_count(0x7, 0x0, p);
1588a272653SPeter Holm	if ((p[1] & CPUID_STDEXT_FSGSBASE) == 0) {
1598a272653SPeter Holm		fprintf(stderr, "CPU does not support RDGSBASE\n");
1608a272653SPeter Holm		return (0);
1618a272653SPeter Holm	}
1628a272653SPeter Holm
1638a272653SPeter Holm	len = sizeof(nthreads);
1648a272653SPeter Holm	error = sysctl(mib, nitems(mib), &nthreads, &len, NULL, 0);
1658a272653SPeter Holm	if (error == -1)
1668a272653SPeter Holm		err(1, "sysctl hw.ncpu");
1678a272653SPeter Holm	signal(SIGALRM, hand);
1688a272653SPeter Holm	alarm(10);
1698a272653SPeter Holm	start(nthreads);
1708a272653SPeter Holm	for (;;)
1718a272653SPeter Holm		pause();
1728a272653SPeter Holm}
1738a272653SPeter HolmEOF
1748a272653SPeter Holm
1758a272653SPeter Holmmycc -o /tmp/rdgsbase /tmp/rdgsbase.c -lpthread || exit 1
1768a272653SPeter Holmrm /tmp/rdgsbase.c
1778a272653SPeter Holm
1788a272653SPeter Holm(cd /tmp; /tmp/rdgsbase)
1798a272653SPeter Holms=$?
1808a272653SPeter Holm
1818a272653SPeter Holmrm -f /tmp/rdgsbase /tmp/rdgsbase.core
1828a272653SPeter Holmexit $s
183