Intel CPU design flaw - FreeBSD affected? // disabling LDTSC
Klaus P. Ohrhallinger
k at 7he.at
Thu Jan 4 18:26:49 UTC 2018
Hello,
I disabled the ldtsc and ldtscp instructions for usermode on one of my
production servers:
% ./spectre
Reading 40 bytes:
Bus error (core dumped)
All PoC code I have seen today relies on those instructions.
Is there any other way to measure the memory/cache access times ?
On 10.4-RELEASE I had to rebuild world and some ports, but now
everything seems to be working fine.
Patches attached.
Regards, Klaus
-------------- next part --------------
diff -aupr src.orig/sys/amd64/amd64/initcpu.c src/sys/amd64/amd64/initcpu.c
--- src.orig/sys/amd64/amd64/initcpu.c 2017-09-29 02:20:05.000000000 +0200
+++ src/sys/amd64/amd64/initcpu.c 2018-01-04 15:19:32.741729000 +0100
@@ -210,6 +210,7 @@ initializecpu(void)
}
if (cpu_stdext_feature & CPUID_STDEXT_FSGSBASE)
cr4 |= CR4_FSGSBASE;
+ cr4 |= CR4_TSD;
/*
* Postpone enabling the SMEP on the boot CPU until the page
diff -aupr src.orig/sys/x86/x86/tsc.c src/sys/x86/x86/tsc.c
--- src.orig/sys/x86/x86/tsc.c 2017-09-29 02:20:06.000000000 +0200
+++ src/sys/x86/x86/tsc.c 2018-01-04 15:19:32.756123000 +0100
@@ -658,6 +658,7 @@ tsc_freq_changed(void *arg, const struct
static int
sysctl_machdep_tsc_freq(SYSCTL_HANDLER_ARGS)
{
+#if 0
int error;
uint64_t freq;
@@ -671,6 +672,9 @@ sysctl_machdep_tsc_freq(SYSCTL_HANDLER_A
freq >> (int)(intptr_t)tsc_timecounter.tc_priv);
}
return (error);
+#else
+ return (EOPNOTSUPP);
+#endif
}
SYSCTL_PROC(_machdep, OID_AUTO, tsc_freq, CTLTYPE_U64 | CTLFLAG_RW,
-------------- next part --------------
diff -aupr src.orig/lib/libc/amd64/sys/__vdso_gettc.c src/lib/libc/amd64/sys/__vdso_gettc.c
--- src.orig/lib/libc/amd64/sys/__vdso_gettc.c 2017-09-29 02:20:13.000000000 +0200
+++ src/lib/libc/amd64/sys/__vdso_gettc.c 2018-01-04 16:53:31.590961000 +0100
@@ -30,17 +30,22 @@ __FBSDID("$FreeBSD: releng/10.4/lib/libc
#include <sys/elf.h>
#include <sys/time.h>
#include <sys/vdso.h>
+#include <errno.h>
#include <machine/cpufunc.h>
#include "libc_private.h"
static u_int
__vdso_gettc_low(const struct vdso_timehands *th)
{
+#if 0
uint32_t rv;
__asm __volatile("rdtsc; shrd %%cl, %%edx, %0"
: "=a" (rv) : "c" (th->th_x86_shift) : "edx");
return (rv);
+#else
+ return (0);
+#endif
}
#pragma weak __vdso_gettc
@@ -48,7 +53,11 @@ u_int
__vdso_gettc(const struct vdso_timehands *th)
{
+#if 0
return (th->th_x86_shift > 0 ? __vdso_gettc_low(th) : rdtsc32());
+#else
+ return (0);
+#endif
}
#pragma weak __vdso_gettimekeep
@@ -56,5 +65,9 @@ int
__vdso_gettimekeep(struct vdso_timekeep **tk)
{
+#if 0
return (_elf_aux_info(AT_TIMEKEEP, tk, sizeof(*tk)));
+#else
+ return (ENOSYS);
+#endif
}
diff -aupr src.orig/lib/libc/i386/sys/__vdso_gettc.c src/lib/libc/i386/sys/__vdso_gettc.c
--- src.orig/lib/libc/i386/sys/__vdso_gettc.c 2017-09-29 02:20:14.000000000 +0200
+++ src/lib/libc/i386/sys/__vdso_gettc.c 2018-01-04 17:03:03.096724000 +0100
@@ -30,17 +30,22 @@ __FBSDID("$FreeBSD: releng/10.4/lib/libc
#include <sys/elf.h>
#include <sys/time.h>
#include <sys/vdso.h>
+#include <errno.h>
#include <machine/cpufunc.h>
#include "libc_private.h"
static u_int
__vdso_gettc_low(const struct vdso_timehands *th)
{
+#if 0
uint32_t rv;
__asm __volatile("rdtsc; shrd %%cl, %%edx, %0"
: "=a" (rv) : "c" (th->th_x86_shift) : "edx");
return (rv);
+#else
+ return (0);
+#endif
}
#pragma weak __vdso_gettc
@@ -48,7 +53,11 @@ u_int
__vdso_gettc(const struct vdso_timehands *th)
{
+#if 0
return (th->th_x86_shift > 0 ? __vdso_gettc_low(th) : rdtsc32());
+#else
+ return (0);
+#endif
}
#pragma weak __vdso_gettimekeep
@@ -56,5 +65,9 @@ int
__vdso_gettimekeep(struct vdso_timekeep **tk)
{
+#if 0
return (_elf_aux_info(AT_TIMEKEEP, tk, sizeof(*tk)));
+#else
+ return (ENOSYS);
+#endif
}
More information about the freebsd-current
mailing list