CPUCTL(4)

πŸ’– cpuctl β€” the cpuctl pseudo device πŸ’–

okay bestie, sit down, we're talking about cpuctl(4) today and honestly? it's giving kernel-interface-manual main character energy. this is the page from the Kernel Interfaces Manual, and it is so much cooler than it sounds, i promise. πŸ¦‹


✨ SYNOPSIS ✨

so to compile this driver into the kernel, you're gonna drop these lines into your kernel configuration file:

device cpuctl

and alternatively β€” yes bestie, there's an alternatively β€” if you wanna load the driver as a module at boot time instead, you put this in loader.conf(5):

cpuctl_load="YES"

pick your fighter, both are valid, both slay. πŸ’…


🌸 DESCRIPTION 🌸

so the special device /dev/cpuctl is basically the system CPU's little doorway, an interface to the system CPU itself. it provides functionality to:

  • retrieve CPUID information
  • read/write machine specific registers (MSR)
  • perform CPU firmware updates

and for each CPU present in the system, a special device /dev/cpuctl%d with the appropriate index gets created. for multicore CPUs? such a special device gets created for each core. one per core, no skips, no crumbs left behind. πŸŽ€

currently, only i386 and amd64 processors are supported. just those two. don't @ me. πŸ™ˆ


πŸ‘‘ IOCTL INTERFACE πŸ‘‘

all of the supported operations are invoked using the ioctl(2) system call. and 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. (basically the chill, no-extra-args version, periodt.)

  • 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 the %eax register after the CPUID instruction is executed, data[1] is for %ebx, data[2] for %ecx, and data[3] for %edx. four registers, four slots, everyone accounted for. ✨

  • 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. iykyk.


πŸ“ 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 🌈

go read those too, bestie, they're part of the lore. πŸ“š


⭐ HISTORY ⭐

the cpuctl driver first appeared in FreeBSD 7.2. vintage. iconic. a classic. πŸŽ€


🫢 AUTHORS 🫢

the cpuctl module and this manual page were written by Stanislav Sedov <stas@FreeBSD.org>. thank you king, we appreciate you. πŸ’œ


😭 BUGS 😭

Yes, probably, report if any.

that's it. that's the whole bug section. honestly? relatable. the most honest manpage in the game. πŸ’€


and that's the whole thing, bestie! this one's from the Debian edition, dated June 20, 2014, and you read it all the way through β€” obsessed with you fr fr. now go poke at /dev/cpuctl and be careful with those MSRs. mwah πŸ’…βœ¨πŸŒΈ

πŸ“¦ where this page comes from