Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144445344
D13770.id37536.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D13770.id37536.diff
View Options
Index: sys/dev/cpuctl/cpuctl.c
===================================================================
--- sys/dev/cpuctl/cpuctl.c
+++ sys/dev/cpuctl/cpuctl.c
@@ -73,6 +73,7 @@
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,
@@ -159,7 +160,8 @@
}
/* 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) {
@@ -187,6 +189,9 @@
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;
@@ -504,6 +509,29 @@
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)
{
Index: sys/sys/cpuctl.h
===================================================================
--- sys/sys/cpuctl.h
+++ sys/sys/cpuctl.h
@@ -59,5 +59,6 @@
#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_ */
Index: sys/x86/include/ifunc.h
===================================================================
--- /dev/null
+++ sys/x86/include/ifunc.h
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 2015, 2017 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Konstantin Belousov <kib@FreeBSD.org>
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __X86_IFUNC_H
+#define __X86_IFUNC_H
+
+#define DECLARE_LIFUNC(ret_type, name, args) \
+ret_type name args
+
+#define DEFINE_LIFUNC(scope, selector_qual, ret_type, name, args) \
+__asm__ (scope "\t" #name "\n" \
+ "\t.type\t" #name ",@function\n" \
+ #name ":\n" \
+ "\tjmp *" #name "_selector\n" \
+ "\t.size\t" #name ",\t. - "#name); \
+selector_qual ret_type (*name##_selector)args __used; \
+DECLARE_LIFUNC(ret_type, name, args)
+
+#define DEFINE_STATIC_LIFUNC(ret_type, name, args) \
+ DEFINE_LIFUNC(".local", static, ret_type, name, args)
+
+#define DEFINE_GLOBAL_LIFUNC(ret_type, name, args) \
+ DEFINE_LIFUNC(".globl", , ret_type, name, args)
+
+#define DEFINE_IFUNC(qual, ret_type, name, args, resolver_qual) \
+ resolver_qual ret_type (*name##_resolver(void))args __used; \
+ qual ret_type name args __attribute__((ifunc(#name "_resolver"))); \
+ resolver_qual ret_type (*name##_resolver(void))args
+
+#endif
Index: sys/x86/include/x86_var.h
===================================================================
--- sys/x86/include/x86_var.h
+++ sys/x86/include/x86_var.h
@@ -119,7 +119,8 @@
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);
Index: sys/x86/iommu/intel_utils.c
===================================================================
--- sys/x86/iommu/intel_utils.c
+++ sys/x86/iommu/intel_utils.c
@@ -368,8 +368,7 @@
* If DMAR does not snoop paging structures accesses, flush
* CPU cache to memory.
*/
- pmap_invalidate_cache_range((uintptr_t)dst, (uintptr_t)dst + sz,
- TRUE);
+ pmap_force_invalidate_cache_range((uintptr_t)dst, (uintptr_t)dst + sz);
}
void
Index: sys/x86/x86/identcpu.c
===================================================================
--- sys/x86/x86/identcpu.c
+++ sys/x86/x86/identcpu.c
@@ -1385,9 +1385,8 @@
return (false);
}
-#ifdef __amd64__
void
-identify_cpu(void)
+identify_cpu1(void)
{
u_int regs[4];
@@ -1404,7 +1403,29 @@
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.
@@ -1412,7 +1433,7 @@
void
finishidentcpu(void)
{
- u_int regs[4], cpu_stdext_disable;
+ u_int regs[4];
#ifdef __i386__
u_char ccr3;
#endif
@@ -1431,22 +1452,7 @@
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 &&
Index: usr.sbin/cpucontrol/cpucontrol.8
===================================================================
--- usr.sbin/cpucontrol/cpucontrol.8
+++ usr.sbin/cpucontrol/cpucontrol.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 30, 2017
+.Dd January 2, 2018
.Dt CPUCONTROL 8
.Os
.Sh NAME
@@ -76,6 +76,10 @@
.Bk
.Ar device
.Ek
+.Nm
+.Fl e
+.Bk
+.Ar device
.Sh DESCRIPTION
The
.Nm
@@ -136,6 +140,20 @@
.Nm
utility will walk through the configured data directories
and apply all firmware updates available for this CPU.
+.It Fl e
+Re-evaluate the kernel flags indicating the present CPU features.
+This command is typically executed after a firmware update was applied
+which changes information reported by the
+.Dv CPUID
+instruction.
+.Pp
+.Bf -symbolic
+Only execute the
+.Fl e
+command after the microcode update was applied to all CPUs in the system.
+Kernel does not operate correctly if the features of processors are
+not identical.
+.Ef
.It Fl v
Increase the verbosity level.
.It Fl h
Index: usr.sbin/cpucontrol/cpucontrol.c
===================================================================
--- usr.sbin/cpucontrol/cpucontrol.c
+++ usr.sbin/cpucontrol/cpucontrol.c
@@ -63,6 +63,7 @@
#define FLAG_M 0x02
#define FLAG_U 0x04
#define FLAG_N 0x08
+#define FLAG_E 0x10
#define OP_INVAL 0x00
#define OP_READ 0x01
@@ -117,7 +118,7 @@
if (name == NULL)
name = "cpuctl";
fprintf(stderr, "Usage: %s [-vh] [-d datadir] [-m msr[=value] | "
- "-i level | -i level,level_type | -u] device\n", name);
+ "-i level | -i level,level_type | -e | -u] device\n", name);
exit(EX_USAGE);
}
@@ -340,6 +341,25 @@
return (0);
}
+static int
+do_eval_cpu_features(const char *dev)
+{
+ int fd, error;
+
+ assert(dev != NULL);
+
+ fd = open(dev, O_RDWR);
+ if (fd < 0) {
+ WARN(0, "error opening %s for reading", dev);
+ return (1);
+ }
+ error = ioctl(fd, CPUCTL_EVAL_CPU_FEATURES, NULL);
+ if (error < 0)
+ WARN(0, "ioctl(%s, CPUCTL_EVAL_CPU_FEATURES)", dev);
+ close(fd);
+ return (error);
+}
+
static int
do_update(const char *dev)
{
@@ -430,11 +450,14 @@
error = 0;
cmdarg = ""; /* To keep gcc3 happy. */
- while ((c = getopt(argc, argv, "d:hi:m:nuv")) != -1) {
+ while ((c = getopt(argc, argv, "d:ehi:m:nuv")) != -1) {
switch (c) {
case 'd':
datadir_add(optarg);
break;
+ case 'e':
+ flags |= FLAG_E;
+ break;
case 'i':
flags |= FLAG_I;
cmdarg = optarg;
@@ -468,22 +491,25 @@
if ((flags & FLAG_N) == 0)
datadir_add(DEFAULT_DATADIR);
dev = argv[0];
- c = flags & (FLAG_I | FLAG_M | FLAG_U);
+ c = flags & (FLAG_E | FLAG_I | FLAG_M | FLAG_U);
switch (c) {
- case FLAG_I:
- if (strstr(cmdarg, ",") != NULL)
- error = do_cpuid_count(cmdarg, dev);
- else
- error = do_cpuid(cmdarg, dev);
- break;
- case FLAG_M:
- error = do_msr(cmdarg, dev);
- break;
- case FLAG_U:
- error = do_update(dev);
- break;
- default:
- usage(); /* Only one command can be selected. */
+ case FLAG_I:
+ if (strstr(cmdarg, ",") != NULL)
+ error = do_cpuid_count(cmdarg, dev);
+ else
+ error = do_cpuid(cmdarg, dev);
+ break;
+ case FLAG_M:
+ error = do_msr(cmdarg, dev);
+ break;
+ case FLAG_U:
+ error = do_update(dev);
+ break;
+ case FLAG_E:
+ error = do_eval_cpu_features(dev);
+ break;
+ default:
+ usage(); /* Only one command can be selected. */
}
SLIST_FREE(&datadirs, next, free);
return (error == 0 ? 0 : 1);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Feb 9, 11:44 AM (11 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28575376
Default Alt Text
D13770.id37536.diff (10 KB)
Attached To
Mode
D13770: Make it possible to re-evaluate cpu_features.
Attached
Detach File
Event Timeline
Log In to Comment