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