Page MenuHomeFreeBSD

D13770.id37535.diff
No OneTemporary

D13770.id37535.diff

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: 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

Mime Type
text/plain
Expires
Mon, Feb 9, 1:45 PM (20 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28585792
Default Alt Text
D13770.id37535.diff (5 KB)

Event Timeline