---
name: "cpuctl"
section: "4"
platform: "freebsd"
package: "base"
version: "16.0-CURRENT-20261027-61c70dc16a79"
release: "FreeBSD 16.0-CURRENT (2026-10-27)"
platforms: ["freebsd"]
url: "https://new.carta.tech/cpuctl/4"
---

# cpuctl(4)

cpuctl pseudo device

## NAME

**cpuctl** – cpuctl pseudo device

## SYNOPSIS

To compile this driver into the kernel, place the following lines in your kernel configuration file:

**device cpuctl**

Alternatively, to load the driver as a module at boot time, place the following in [loader.conf(5)](/loader.conf/5.md):

```
cpuctl_load="YES"
```

## DESCRIPTION

The special device */dev/cpuctl* presents interface to the system CPU. It provides functionality to retrieve CPUID information, read/write machine specific registers (MSR) and perform CPU firmware updates.

For each CPU present in the system, the special device */dev/cpuctl%d* with the appropriate index will be created. For multicore CPUs such a special device will be created for each core.

Currently, only i386 and amd64 processors are supported.

## IOCTL INTERFACE

All of the supported operations are invoked using the [ioctl(2)](/ioctl/2.md) system call. Currently, the following ioctls are defined:

- CPUCTL\_RDMSR *cpuctl\_msr\_args\_t*, *\*args*

  - CPUCTL\_WRMSR *cpuctl\_msr\_args\_t*, *\*args*

  Read/write CPU machine specific register. The *cpuctl\_msr\_args\_t* structure is defined in ⟨sys/cpuctl.h⟩ as:

  ```
  typedef struct {
  	int		msr;	/* MSR to read */
  	uint64_t	data;
  } cpuctl_msr_args_t;
  ```

- CPUCTL\_MSRSBIT *cpuctl\_msr\_args\_t*, *\*args*

  - CPUCTL\_MSRCBIT *cpuctl\_msr\_args\_t*, *\*args*

  Set/clear MSR bits according to the mask given in the *data* field.

- CPUCTL\_CPUID *cpuctl\_cpuid\_args\_t*, *\*args*

  Retrieve CPUID information. Arguments are supplied in the following structure:

  ```
  typedef struct {
  	int		level;		/* CPUID level */
  	uint32_t	data[4];
  } cpuctl_cpuid_args_t;
  ```

  It is equivalent to the CPUCTL\_CPUID\_COUNT request with *level\_type* set to 0.

- CPUCTL\_CPUID\_COUNT *cpuctl\_cpuid\_count\_args\_t*, *\*args*

  Retrieve CPUID information. Arguments are supplied in the following structure:

  ```
  typedef struct {
  	int		level;		/* CPUID level */
  	int		level_type;	/* CPUID level type */
  	uint32_t	data[4];
  } cpuctl_cpuid_count_args_t;
  ```

  The *level* field indicates the CPUID level to retrieve, it is loaded into the *%eax* register before the CPUID instruction is executed, The *level\_type* field indicates the CPUID level type to retrieve, it is loaded into the *%ecx* register.

  The *data* field is used to store the received CPUID data. That is, *data\[0\]* contains the value of *%eax* register after the CPUID instruction is executed, *data\[1\]* is for *%ebx*, *data\[2\]* for *%ecx*, and *data\[3\]* for *%edx*.

- CPUCTL\_UPDATE cpuctl\_update\_args\_t \*args

  Update CPU firmware (microcode). The structure is defined in ⟨sys/cpuctl.h⟩ as:

  ```
  typedef struct {
  	void	*data;
  	size_t	size;
  } cpuctl_update_args_t;
  ```

  The *data* field should point to the firmware image of size *size*.

For additional information refer to *cpuctl.h*.

## FILES

- */dev/cpuctl*

  ## ERRORS

- \[ENXIO\]

  The operation requested is not supported by the device (e.g., unsupported architecture or the CPU is disabled).

- \[EINVAL\]

  Incorrect request was supplied, or microcode image is not correct.

- \[ENOMEM\]

  No physical memory was available to complete the request.

- \[EFAULT\]

  The firmware image address points outside the process address space.

## SEE ALSO

[hwpmc(4)](/hwpmc/4.md), [cpucontrol(8)](/cpucontrol/8.md)

## HISTORY

The **cpuctl** driver first appeared in FreeBSD 7.2.

## AUTHORS

The **cpuctl** module and this manual page were written by Stanislav Sedov ⟨*stas@FreeBSD.org*⟩.

## BUGS

Yes, probably, report if any.
