Skip to content

Instantly share code, notes, and snippets.

@kostikbel
Created August 18, 2017 11:48
Show Gist options
  • Save kostikbel/23f6b30e72e6bc8738196fc6c7e2e39c to your computer and use it in GitHub Desktop.
Save kostikbel/23f6b30e72e6bc8738196fc6c7e2e39c to your computer and use it in GitHub Desktop.
/* $Id: rdgsbase.c,v 1.9 2017/08/13 16:22:01 kostik Exp kostik $ */
#include <sys/param.h>
#include <sys/sysctl.h>
#include <err.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <machine/sysarch.h>
static inline uint64_t
rdgsbase(void)
{
uint64_t x;
__asm __volatile("rdgsbase %0" : "=r" (x));
return (x);
}
static inline void
wrgsbase(uint64_t x)
{
__asm __volatile("wrgsbase %0" : : "r" (x));
}
static inline uint64_t
rdfsbase(void)
{
uint64_t x;
__asm __volatile("rdfsbase %0" : "=r" (x));
return (x);
}
static inline void
wrfsbase(uint64_t x)
{
__asm __volatile("wrfsbase %0" : : "r" (x));
}
static void *
rungs(void *arg __unused)
{
volatile char x[1024];
unsigned i;
uint64_t y, oldbase;
oldbase = rdgsbase();
for (i = 0;;) {
wrgsbase((uintptr_t)&x[i]);
if (rdgsbase() != (uintptr_t)&x[i]) {
wrgsbase(oldbase);
printf("bug1 %lx %lx\n", rdgsbase(), (uintptr_t)&x[i]);
exit(1);
}
sysarch(AMD64_GET_GSBASE, &y);
if (y != (uintptr_t)&x[i]) {
wrgsbase(oldbase);
printf("bug2 %lx %lx\n", y, (uintptr_t)&x[i]);
exit(1);
}
i++;
if (i >= nitems(x))
i = 0;
}
return (NULL);
}
static void *
runfs(void *arg __unused)
{
volatile char x[1024];
unsigned i;
uint64_t y, oldbase;
oldbase = rdfsbase();
for (i = 0;;) {
wrfsbase((uintptr_t)&x[i]);
if (rdfsbase() != (uintptr_t)&x[i]) {
wrfsbase(oldbase);
printf("bug3 %lx %lx\n", rdfsbase(), (uintptr_t)&x[i]);
exit(1);
}
sysarch(AMD64_GET_FSBASE, &y);
if (y != (uintptr_t)&x[i]) {
wrfsbase(oldbase);
printf("bug4 %lx %lx\n", y, (uintptr_t)&x[i]);
exit(1);
}
i++;
if (i > nitems(x))
i = 0;
}
return (NULL);
}
static void
start(int nthreads)
{
pthread_t thrs[nthreads * 2];
int error, i;
for (i = 0; i < nthreads; i++) {
error = pthread_create(&thrs[i], NULL, rungs, NULL);
if (error != 0)
errc(1, error, "pthread_create");
}
for (; i < 2 * nthreads; i++) {
error = pthread_create(&thrs[i], NULL, runfs, NULL);
if (error != 0)
errc(1, error, "pthread_create");
}
}
int
main(void)
{
static const int mib[2] = {CTL_HW, HW_NCPU};
int error, nthreads;
size_t len;
len = sizeof(nthreads);
error = sysctl(mib, nitems(mib), &nthreads, &len, NULL, 0);
if (error == -1)
err(1, "sysctl hw.ncpu");
start(nthreads);
for (;;)
pause();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment