summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorLuiz Souza <luiz@netgate.com>2018-02-23 19:42:43 -0300
committerLuiz Souza <luiz@netgate.com>2018-02-23 19:42:43 -0300
commit29512c967a8c82fe0de1e68058be2c424396dd86 (patch)
tree0d71f0c1f580139b0cd774314b1ffb6863b9a157 /sys
parent3f57606fecd6abc41fc7048c7419ffa6193c94e2 (diff)
downloadFreeBSD-src-29512c967a8c82fe0de1e68058be2c424396dd86.zip
FreeBSD-src-29512c967a8c82fe0de1e68058be2c424396dd86.tar.gz
Revert "Revert "MFC r327597:""
This reverts commit 38b302a111c25b2ca850c0ce8761761b2c48164a.
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/amd64/machdep.c2
-rw-r--r--sys/dev/cpuctl/cpuctl.c30
-rw-r--r--sys/sys/cpuctl.h1
-rw-r--r--sys/x86/include/x86_var.h3
-rw-r--r--sys/x86/x86/identcpu.c46
5 files changed, 59 insertions, 23 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 3ed29e0..8e508c3 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -1559,7 +1559,7 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
kmdp = init_ops.parse_preload_data(modulep);
- identify_cpu();
+ identify_cpu1();
identify_hypervisor();
/* Init basic tunables, hz etc */
diff --git a/sys/dev/cpuctl/cpuctl.c b/sys/dev/cpuctl/cpuctl.c
index 5351d8ed..6a854e4 100644
--- a/sys/dev/cpuctl/cpuctl.c
+++ b/sys/dev/cpuctl/cpuctl.c
@@ -71,6 +71,7 @@ static int cpuctl_do_cpuid(int cpu, cpuctl_cpuid_args_t *data,
struct thread *td);
static int cpuctl_do_cpuid_count(int cpu, cpuctl_cpuid_count_args_t *data,
struct thread *td);
+static int cpuctl_do_eval_cpu_features(int cpu, struct thread *td);
static int cpuctl_do_update(int cpu, cpuctl_update_args_t *data,
struct thread *td);
static int update_intel(int cpu, cpuctl_update_args_t *args,
@@ -157,7 +158,8 @@ cpuctl_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
}
/* Require write flag for "write" requests. */
if ((cmd == CPUCTL_MSRCBIT || cmd == CPUCTL_MSRSBIT ||
- cmd == CPUCTL_UPDATE || cmd == CPUCTL_WRMSR) &&
+ cmd == CPUCTL_UPDATE || cmd == CPUCTL_WRMSR ||
+ cmd == CPUCTL_EVAL_CPU_FEATURES) &&
(flags & FWRITE) == 0)
return (EPERM);
switch (cmd) {
@@ -185,6 +187,9 @@ cpuctl_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
ret = cpuctl_do_cpuid_count(cpu,
(cpuctl_cpuid_count_args_t *)data, td);
break;
+ case CPUCTL_EVAL_CPU_FEATURES:
+ ret = cpuctl_do_eval_cpu_features(cpu, td);
+ break;
default:
ret = EINVAL;
break;
@@ -502,6 +507,29 @@ fail:
return (ret);
}
+static int
+cpuctl_do_eval_cpu_features(int cpu, struct thread *td)
+{
+ int is_bound = 0;
+ int oldcpu;
+
+ KASSERT(cpu >= 0 && cpu <= mp_maxid,
+ ("[cpuctl,%d]: bad cpu number %d", __LINE__, cpu));
+
+#ifdef __i386__
+ if (cpu_id == 0)
+ return (ENODEV);
+#endif
+ oldcpu = td->td_oncpu;
+ is_bound = cpu_sched_is_bound(td);
+ set_cpu(cpu, td);
+ identify_cpu1();
+ identify_cpu2();
+ restore_cpu(oldcpu, is_bound, td);
+ return (0);
+}
+
+
int
cpuctl_open(struct cdev *dev, int flags, int fmt __unused, struct thread *td)
{
diff --git a/sys/sys/cpuctl.h b/sys/sys/cpuctl.h
index 30af524..65556ec 100644
--- a/sys/sys/cpuctl.h
+++ b/sys/sys/cpuctl.h
@@ -57,5 +57,6 @@ typedef struct {
#define CPUCTL_MSRSBIT _IOWR('c', 5, cpuctl_msr_args_t)
#define CPUCTL_MSRCBIT _IOWR('c', 6, cpuctl_msr_args_t)
#define CPUCTL_CPUID_COUNT _IOWR('c', 7, cpuctl_cpuid_count_args_t)
+#define CPUCTL_EVAL_CPU_FEATURES _IO('c', 8)
#endif /* _CPUCTL_H_ */
diff --git a/sys/x86/include/x86_var.h b/sys/x86/include/x86_var.h
index 7705a1c..ffdf2f0 100644
--- a/sys/x86/include/x86_var.h
+++ b/sys/x86/include/x86_var.h
@@ -116,7 +116,8 @@ void cpu_setregs(void);
void dump_add_page(vm_paddr_t);
void dump_drop_page(vm_paddr_t);
void finishidentcpu(void);
-void identify_cpu(void);
+void identify_cpu1(void);
+void identify_cpu2(void);
void identify_hypervisor(void);
void initializecpu(void);
void initializecpucache(void);
diff --git a/sys/x86/x86/identcpu.c b/sys/x86/x86/identcpu.c
index c0cc2a6..ab7214c 100644
--- a/sys/x86/x86/identcpu.c
+++ b/sys/x86/x86/identcpu.c
@@ -1370,9 +1370,8 @@ fix_cpuid(void)
return (false);
}
-#ifdef __amd64__
void
-identify_cpu(void)
+identify_cpu1(void)
{
u_int regs[4];
@@ -1389,7 +1388,29 @@ identify_cpu(void)
cpu_feature = regs[3];
cpu_feature2 = regs[2];
}
-#endif
+
+void
+identify_cpu2(void)
+{
+ u_int regs[4], cpu_stdext_disable;
+
+ if (cpu_high >= 7) {
+ cpuid_count(7, 0, regs);
+ cpu_stdext_feature = regs[1];
+
+ /*
+ * Some hypervisors failed to filter out unsupported
+ * extended features. Allow to disable the
+ * extensions, activation of which requires setting a
+ * bit in CR4, and which VM monitors do not support.
+ */
+ cpu_stdext_disable = 0;
+ TUNABLE_INT_FETCH("hw.cpu_stdext_disable", &cpu_stdext_disable);
+ cpu_stdext_feature &= ~cpu_stdext_disable;
+
+ cpu_stdext_feature2 = regs[2];
+ }
+}
/*
* Final stage of CPU identification.
@@ -1397,7 +1418,7 @@ identify_cpu(void)
void
finishidentcpu(void)
{
- u_int regs[4], cpu_stdext_disable;
+ u_int regs[4];
#ifdef __i386__
u_char ccr3;
#endif
@@ -1416,22 +1437,7 @@ finishidentcpu(void)
cpu_mon_max_size = regs[1] & CPUID5_MON_MAX_SIZE;
}
- if (cpu_high >= 7) {
- cpuid_count(7, 0, regs);
- cpu_stdext_feature = regs[1];
-
- /*
- * Some hypervisors failed to filter out unsupported
- * extended features. Allow to disable the
- * extensions, activation of which requires setting a
- * bit in CR4, and which VM monitors do not support.
- */
- cpu_stdext_disable = 0;
- TUNABLE_INT_FETCH("hw.cpu_stdext_disable", &cpu_stdext_disable);
- cpu_stdext_feature &= ~cpu_stdext_disable;
-
- cpu_stdext_feature2 = regs[2];
- }
+ identify_cpu2();
#ifdef __i386__
if (cpu_high > 0 &&
OpenPOWER on IntegriCloud