svn commit: r267673 - in head: share/man/man4 sys/dev/cpuctl sys/sys usr.sbin/cpucontrol

Konstantin Belousov kib at FreeBSD.org
Fri Jun 20 13:13:39 UTC 2014


Author: kib
Date: Fri Jun 20 13:13:38 2014
New Revision: 267673
URL: http://svnweb.freebsd.org/changeset/base/267673

Log:
  Restore the ABI of the cpuctl(4) ioctl request CPUCTL_CPUID, use
  separate argument structure with added level_type field for
  CPUID_CPUID_COUNT request.
  
  Reviewed by:	attilio (previous version)
  Sponsored by:	The FreeBSD Foundation
  MFC after:	2 weeks

Modified:
  head/share/man/man4/cpuctl.4
  head/sys/dev/cpuctl/cpuctl.c
  head/sys/sys/cpuctl.h
  head/usr.sbin/cpucontrol/cpucontrol.c

Modified: head/share/man/man4/cpuctl.4
==============================================================================
--- head/share/man/man4/cpuctl.4	Fri Jun 20 11:47:49 2014	(r267672)
+++ head/share/man/man4/cpuctl.4	Fri Jun 20 13:13:38 2014	(r267673)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd June 30, 2009
+.Dd June 20, 2014
 .Dt CPUCTL 4
 .Os
 .Sh NAME
@@ -65,7 +65,7 @@ All of the supported operations are invo
 .Xr ioctl 2
 system call.
 Currently, the following ioctls are defined:
-.Bl -tag -width CPUCTL_UPDATE
+.Bl -tag -width CPUCTL_CPUID_COUNT
 .It Dv CPUCTL_RDMSR Fa cpuctl_msr_args_t *args
 .It Dv CPUCTL_WRMSR Fa cpuctl_msr_args_t *args
 Read/write CPU machine specific register.
@@ -86,29 +86,60 @@ Set/clear MSR bits according to the mask
 .Va data
 field.
 .It Dv CPUCTL_CPUID Fa cpuctl_cpuid_args_t *args
-.It Dv CPUCTL_CPUID_COUNT Fa cpuctl_cpuid_args_t *args
 Retrieve CPUID information.
-Arguments are supplied in
-the following struct:
+Arguments are supplied in the following structure:
 .Bd -literal
 typedef struct {
 	int		level;		/* CPUID level */
-	int		level_type;	/* CPUID level type */
 	uint32_t	data[4];
 } cpuctl_cpuid_args_t;
 .Ed
-.Pp
+It is equivalent to the
+.Dv CPUCTL_CPUID_COUNT
+request with
+.Va level_type
+set to 0.
+.It Dv CPUCTL_CPUID_COUNT Fa cpuctl_cpuid_count_args_t *args
+Retrieve CPUID information.
+Arguments are supplied in the following structure:
+.Bd -literal
+typedef struct {
+	int		level;		/* CPUID level */
+	int		level_type;	/* CPUID level type */
+	uint32_t	data[4];
+} cpuctl_cpuid_count_args_t;
+.Ed
 The
 .Va level
-field indicates the CPUID level to retrieve.
+field indicates the CPUID level to retrieve,
+it is loaded into the
+.Va %eax
+register before the CPUID instruction is executed,
 The
 .Va level_type
-field indicates the CPUID level type to retrieve.
-It is overriden to 0 for
-.Va CPUCTL_CPUID .
-Finally, the
+field indicates the CPUID level type to retrieve,
+it is loaded into the
+.Va %ecx
+register.
+.Pp
+The
 .Va data
 field is used to store the received CPUID data.
+That is,
+.Va data[0]
+contains the value of
+.Va %eax
+register after the CPUID instruction is executed,
+.Va data[1]
+is for
+.Va %ebx ,
+.Va data[2]
+for
+.Va %ecx ,
+and
+.Va data[3]
+for
+.Va %edx .
 .It Dv CPUCTL_UPDATE cpuctl_update_args_t *args
 Update CPU firmware (microcode).
 The structure is defined in

Modified: head/sys/dev/cpuctl/cpuctl.c
==============================================================================
--- head/sys/dev/cpuctl/cpuctl.c	Fri Jun 20 11:47:49 2014	(r267672)
+++ head/sys/dev/cpuctl/cpuctl.c	Fri Jun 20 13:13:38 2014	(r267673)
@@ -69,7 +69,7 @@ static int cpuctl_do_msr(int cpu, cpuctl
     struct thread *td);
 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_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);
@@ -180,8 +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:
-		ret = cpuctl_do_cpuid_count(cpu, (cpuctl_cpuid_args_t *)data,
-		    td);
+		ret = cpuctl_do_cpuid_count(cpu,
+		    (cpuctl_cpuid_count_args_t *)data, td);
 		break;
 	default:
 		ret = EINVAL;
@@ -195,7 +195,8 @@ fail:
  * Actually perform cpuid operation.
  */
 static int
-cpuctl_do_cpuid_count(int cpu, cpuctl_cpuid_args_t *data, struct thread *td)
+cpuctl_do_cpuid_count(int cpu, cpuctl_cpuid_count_args_t *data,
+    struct thread *td)
 {
 	int is_bound = 0;
 	int oldcpu;
@@ -218,10 +219,15 @@ cpuctl_do_cpuid_count(int cpu, cpuctl_cp
 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. */
-	data->level_type = 0;
-	return (cpuctl_do_cpuid_count(cpu, data, td));
+	cdata.level_type = 0;
+	error = cpuctl_do_cpuid_count(cpu, &cdata, td);
+	bcopy(cdata.data, data->data, sizeof(data->data)); /* Ignore error */
+	return (error);
 }
 
 /*

Modified: head/sys/sys/cpuctl.h
==============================================================================
--- head/sys/sys/cpuctl.h	Fri Jun 20 11:47:49 2014	(r267672)
+++ head/sys/sys/cpuctl.h	Fri Jun 20 13:13:38 2014	(r267673)
@@ -36,11 +36,16 @@ typedef struct {
 
 typedef struct {
 	int		level;		/* CPUID level */
-	int		level_type;	/* CPUID level type */
 	uint32_t	data[4];
 } cpuctl_cpuid_args_t;
 
 typedef struct {
+	int		level;		/* CPUID level */
+	int		level_type;	/* CPUID level type */
+	uint32_t	data[4];
+} cpuctl_cpuid_count_args_t;
+
+typedef struct {
 	void	*data;
 	size_t	size;
 } cpuctl_update_args_t;
@@ -51,6 +56,6 @@ typedef struct {
 #define	CPUCTL_UPDATE	_IOWR('c', 4, cpuctl_update_args_t)
 #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_args_t)
+#define	CPUCTL_CPUID_COUNT _IOWR('c', 7, cpuctl_cpuid_count_args_t)
 
 #endif /* _CPUCTL_H_ */

Modified: head/usr.sbin/cpucontrol/cpucontrol.c
==============================================================================
--- head/usr.sbin/cpucontrol/cpucontrol.c	Fri Jun 20 11:47:49 2014	(r267672)
+++ head/usr.sbin/cpucontrol/cpucontrol.c	Fri Jun 20 13:13:38 2014	(r267673)
@@ -175,7 +175,7 @@ do_cpuid_count(const char *cmdarg, const
 {
 	char *cmdarg1, *endptr, *endptr1;
 	unsigned int level, level_type;
-	cpuctl_cpuid_args_t args;
+	cpuctl_cpuid_count_args_t args;
 	int fd, error;
 
 	assert(cmdarg != NULL);


More information about the svn-src-all mailing list