Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/x86/x86 Add a machdep.tsc_user_enable sysctl, to en...
details: https://anonhg.NetBSD.org/src/rev/e2aad9a9f4de
branches: trunk
changeset: 356554:e2aad9a9f4de
user: maxv <maxv%NetBSD.org@localhost>
date: Mon Oct 02 19:23:16 2017 +0000
description:
Add a machdep.tsc_user_enable sysctl, to enable/disable the rdtsc
instruction in usermode. It defaults to enabled.
diffstat:
sys/arch/x86/x86/tsc.c | 36 +++++++++++++++++++++++++++++-
sys/arch/x86/x86/tsc.h | 4 ++-
sys/arch/x86/x86/x86_machdep.c | 49 ++++++++++++++++++++++++++++++++++++++++-
3 files changed, 84 insertions(+), 5 deletions(-)
diffs (177 lines):
diff -r 7a9383c78805 -r e2aad9a9f4de sys/arch/x86/x86/tsc.c
--- a/sys/arch/x86/x86/tsc.c Mon Oct 02 17:48:01 2017 +0000
+++ b/sys/arch/x86/x86/tsc.c Mon Oct 02 19:23:16 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tsc.c,v 1.36 2013/12/18 03:20:19 msaitoh Exp $ */
+/* $NetBSD: tsc.c,v 1.37 2017/10/02 19:23:16 maxv Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tsc.c,v 1.36 2013/12/18 03:20:19 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tsc.c,v 1.37 2017/10/02 19:23:16 maxv Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -37,6 +37,7 @@
#include <sys/atomic.h>
#include <sys/kernel.h>
#include <sys/cpu.h>
+#include <sys/xcall.h>
#include <machine/cpu_counter.h>
#include <machine/cpuvar.h>
@@ -53,6 +54,8 @@
static int64_t tsc_drift_observed;
static bool tsc_good;
+int tsc_user_enabled = 1;
+
static volatile int64_t tsc_sync_val;
static volatile struct cpu_info *tsc_sync_cpu;
@@ -265,6 +268,35 @@
tsc_post_ap(ci);
}
+static void
+tsc_apply_cpu(void *arg1, void *arg2)
+{
+ bool enable = (bool)arg1;
+ if (enable) {
+ lcr4(rcr4() & ~CR4_TSD);
+ } else {
+ lcr4(rcr4() | CR4_TSD);
+ }
+}
+
+void
+tsc_user_enable(void)
+{
+ uint64_t xc;
+
+ xc = xc_broadcast(0, tsc_apply_cpu, (void *)true, NULL);
+ xc_wait(xc);
+}
+
+void
+tsc_user_disable(void)
+{
+ uint64_t xc;
+
+ xc = xc_broadcast(0, tsc_apply_cpu, (void *)false, NULL);
+ xc_wait(xc);
+}
+
uint64_t
cpu_frequency(struct cpu_info *ci)
{
diff -r 7a9383c78805 -r e2aad9a9f4de sys/arch/x86/x86/tsc.h
--- a/sys/arch/x86/x86/tsc.h Mon Oct 02 17:48:01 2017 +0000
+++ b/sys/arch/x86/x86/tsc.h Mon Oct 02 19:23:16 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tsc.h,v 1.5 2013/12/11 02:14:08 msaitoh Exp $ */
+/* $NetBSD: tsc.h,v 1.6 2017/10/02 19:23:16 maxv Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -31,3 +31,5 @@
void tsc_sync_ap(struct cpu_info *);
void tsc_sync_bp(struct cpu_info *);
void tsc_sync_drift(int64_t);
+void tsc_user_enable(void);
+void tsc_user_disable(void);
diff -r 7a9383c78805 -r e2aad9a9f4de sys/arch/x86/x86/x86_machdep.c
--- a/sys/arch/x86/x86/x86_machdep.c Mon Oct 02 17:48:01 2017 +0000
+++ b/sys/arch/x86/x86/x86_machdep.c Mon Oct 02 19:23:16 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: x86_machdep.c,v 1.95 2017/09/30 12:01:56 maxv Exp $ */
+/* $NetBSD: x86_machdep.c,v 1.96 2017/10/02 19:23:16 maxv Exp $ */
/*-
* Copyright (c) 2002, 2006, 2007 YAMAMOTO Takashi,
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.95 2017/09/30 12:01:56 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.96 2017/10/02 19:23:16 maxv Exp $");
#include "opt_modular.h"
#include "opt_physmem.h"
@@ -70,6 +70,8 @@
#include <uvm/uvm_extern.h>
+#include "tsc.h"
+
#include "acpica.h"
#if NACPICA > 0
#include <dev/acpi/acpivar.h>
@@ -1109,6 +1111,38 @@
return sysctl_lookup(SYSCTLFN_CALL(&node));
}
+#ifndef XEN
+static int
+sysctl_machdep_tsc_enable(SYSCTLFN_ARGS)
+{
+ struct sysctlnode node;
+ int error, val;
+
+ val = *(int *)rnode->sysctl_data;
+
+ node = *rnode;
+ node.sysctl_data = &val;
+
+ error = sysctl_lookup(SYSCTLFN_CALL(&node));
+ if (error != 0 || newp == NULL)
+ return error;
+
+ if (val == 1) {
+ tsc_user_enable();
+ } else if (val == 0) {
+ tsc_user_disable();
+ } else {
+ error = EINVAL;
+ }
+ if (error)
+ return error;
+
+ *(int *)rnode->sysctl_data = val;
+
+ return 0;
+}
+#endif
+
static void
const_sysctl(struct sysctllog **clog, const char *name, int type,
u_quad_t value, int tag)
@@ -1122,6 +1156,9 @@
SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup")
{
extern uint64_t tsc_freq;
+#ifndef XEN
+ extern int tsc_user_enabled;
+#endif
extern int sparse_dump;
sysctl_createv(clog, 0, NULL, NULL,
@@ -1167,6 +1204,14 @@
SYSCTL_DESCR("Whether the kernel uses PAE"),
NULL, 0, &use_pae, 0,
CTL_MACHDEP, CTL_CREATE, CTL_EOL);
+#ifndef XEN
+ sysctl_createv(clog, 0, NULL, NULL,
+ CTLFLAG_READWRITE,
+ CTLTYPE_INT, "tsc_user_enable",
+ SYSCTL_DESCR("RDTSC instruction enabled in usermode"),
+ sysctl_machdep_tsc_enable, 0, &tsc_user_enabled, 0,
+ CTL_MACHDEP, CTL_CREATE, CTL_EOL);
+#endif
/* None of these can ever change once the system has booted */
const_sysctl(clog, "fpu_present", CTLTYPE_INT, i386_fpu_present,
Home |
Main Index |
Thread Index |
Old Index