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