svn commit: r301962 - head/sys/dev/cpuctl

Konstantin Belousov kib at FreeBSD.org
Thu Jun 16 12:07:41 UTC 2016


Author: kib
Date: Thu Jun 16 12:07:40 2016
New Revision: 301962
URL: https://svnweb.freebsd.org/changeset/base/301962

Log:
  Always allow loading of cpuctl(4).  When a CPU feature is not
  supported, e.g. CPUID or MSR, return ENODEV from the ioctl which needs
  that feature.
  
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week
  Approved by:	re (hrs)

Modified:
  head/sys/dev/cpuctl/cpuctl.c

Modified: head/sys/dev/cpuctl/cpuctl.c
==============================================================================
--- head/sys/dev/cpuctl/cpuctl.c	Thu Jun 16 12:05:44 2016	(r301961)
+++ head/sys/dev/cpuctl/cpuctl.c	Thu Jun 16 12:07:40 2016	(r301962)
@@ -67,9 +67,9 @@ static d_ioctl_t cpuctl_ioctl;
 
 static int cpuctl_do_msr(int cpu, cpuctl_msr_args_t *data, u_long cmd,
     struct thread *td);
-static void cpuctl_do_cpuid(int cpu, cpuctl_cpuid_args_t *data,
+static int cpuctl_do_cpuid(int cpu, cpuctl_cpuid_args_t *data,
     struct thread *td);
-static void cpuctl_do_cpuid_count(int cpu, cpuctl_cpuid_count_args_t *data,
+static int cpuctl_do_cpuid_count(int cpu, cpuctl_cpuid_count_args_t *data,
     struct thread *td);
 static int cpuctl_do_update(int cpu, cpuctl_update_args_t *data,
     struct thread *td);
@@ -171,8 +171,7 @@ cpuctl_ioctl(struct cdev *dev, u_long cm
 		ret = cpuctl_do_msr(cpu, (cpuctl_msr_args_t *)data, cmd, td);
 		break;
 	case CPUCTL_CPUID:
-		cpuctl_do_cpuid(cpu, (cpuctl_cpuid_args_t *)data, td);
-		ret = 0;
+		ret = cpuctl_do_cpuid(cpu, (cpuctl_cpuid_args_t *)data, td);
 		break;
 	case CPUCTL_UPDATE:
 		ret = priv_check(td, PRIV_CPUCTL_UPDATE);
@@ -181,9 +180,8 @@ cpuctl_ioctl(struct cdev *dev, u_long cm
 		ret = cpuctl_do_update(cpu, (cpuctl_update_args_t *)data, td);
 		break;
 	case CPUCTL_CPUID_COUNT:
-		cpuctl_do_cpuid_count(cpu, (cpuctl_cpuid_count_args_t *)data,
-		    td);
-		ret = 0;
+		ret = cpuctl_do_cpuid_count(cpu,
+		    (cpuctl_cpuid_count_args_t *)data, td);
 		break;
 	default:
 		ret = EINVAL;
@@ -196,7 +194,7 @@ fail:
 /*
  * Actually perform cpuid operation.
  */
-static void
+static int
 cpuctl_do_cpuid_count(int cpu, cpuctl_cpuid_count_args_t *data,
     struct thread *td)
 {
@@ -210,23 +208,30 @@ cpuctl_do_cpuid_count(int cpu, cpuctl_cp
 	bzero(data->data, sizeof(data->data));
 	DPRINTF("[cpuctl,%d]: retrieving cpuid lev %#0x type %#0x for %d cpu\n",
 	    __LINE__, data->level, data->level_type, 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);
 	cpuid_count(data->level, data->level_type, data->data);
 	restore_cpu(oldcpu, is_bound, td);
+	return (0);
 }
 
-static void
+static int
 cpuctl_do_cpuid(int cpu, cpuctl_cpuid_args_t *data, struct thread *td)
 {
 	cpuctl_cpuid_count_args_t cdata;
+	int error;
 
 	cdata.level = data->level;
 	/* Override the level type. */
 	cdata.level_type = 0;
-	cpuctl_do_cpuid_count(cpu, &cdata, td);
+	error = cpuctl_do_cpuid_count(cpu, &cdata, td);
 	bcopy(cdata.data, data->data, sizeof(data->data)); /* Ignore error */
+	return (error);
 }
 
 /*
@@ -249,6 +254,10 @@ cpuctl_do_msr(int cpu, cpuctl_msr_args_t
 	 */
 	DPRINTF("[cpuctl,%d]: operating on MSR %#0x for %d cpu\n", __LINE__,
 	    data->msr, cpu);
+#ifdef __i386__
+	if ((cpu_feature & CPUID_MSR) == 0)
+		return (ENODEV);
+#endif
 	oldcpu = td->td_oncpu;
 	is_bound = cpu_sched_is_bound(td);
 	set_cpu(cpu, td);
@@ -291,7 +300,9 @@ cpuctl_do_update(int cpu, cpuctl_update_
 	    ("[cpuctl,%d]: bad cpu number %d", __LINE__, cpu));
 	DPRINTF("[cpuctl,%d]: XXX %d", __LINE__, cpu);
 
-	cpuctl_do_cpuid(cpu, &args, td);
+	ret = cpuctl_do_cpuid(cpu, &args, td);
+	if (ret != 0)
+		return (ret);
 	((uint32_t *)vendor)[0] = args.data[1];
 	((uint32_t *)vendor)[1] = args.data[3];
 	((uint32_t *)vendor)[2] = args.data[2];
@@ -518,11 +529,6 @@ cpuctl_modevent(module_t mod __unused, i
 
 	switch(type) {
 	case MOD_LOAD:
-		if ((cpu_feature & CPUID_MSR) == 0) {
-			if (bootverbose)
-				printf("cpuctl: not available.\n");
-			return (ENODEV);
-		}
 		if (bootverbose)
 			printf("cpuctl: access to MSR registers/cpuid info.\n");
 		cpuctl_devs = malloc(sizeof(*cpuctl_devs) * mp_ncpus, M_CPUCTL,


More information about the svn-src-all mailing list