Reading and Writing Model Specific Registers (MSRs) in Linux*

ID 785677
Updated 2/23/2024
Version 1.0
Public

Key Takeaways

  • msr-tools are a set of utilities that enable reading and writing MSRs from userspace. This document assumes that the utilities are installed in the system.

  • msr-tools should only be used in places where system stability, support, and increased vulnerability exposure are not important, such as in development or debugging environments.

author-image

By

Model-specific registers (MSR) are control registers provided by the processor implementation so that system software can interact with a variety of features, including performance monitoring, checking processor status, debugging, program tracing or toggling specific CPU features.

System software interacts with these registers by reading or writing to them. There are also userspace tools that provide easy to use utilities to handle MSRs. This document focuses on two of those utilities in the Linux* OS without serving as an extensive tutorial for how to use the tools.

Handling MSRs with msr-tools

msr-tools are a set of utilities that enable reading and writing MSRs from userspace. You should check with your Linux vendor/distribution OS provider regarding the availability of these tools. This document assumes that the utilities are installed in the system.

WARNING: wrmsr manipulates MSRs independently of existing Linux kernel infrastructure. Using wrmsr can cause writes from both the kernel and wrmsr can be clobbered and lost. This may result in reduced system stability and vulnerability exposure. wrmsr may also induce the kernel to also mark itself as “tainted,” which may affect your ability to obtain support from your Linux vendor.

WARNING: msr-tools should only be used in places where system stability,support and increased vulnerability exposure are not important, such as in development or debugging environments.

This article focuses on two of the tools provided by msr-tools: rdmsr and wrmsr.

Reading MSRs using RDMSR

The rdmsr tool enables reading the value of a specific MSR from userspace. It also allows the user to specify the core from which to read the MSR.

The basic syntax is as follows:

# rdmsr MSR [ -p CPU ]

Where MSR is the hexadecimal value for the MSR we are trying to read and -p CPU is an optional hexadecimal value indicating the CPU number for which we are reading the MSR. This CPU number is the value as listed in /proc/cpuinfo.

A simple example of how to use this tool is:

# rdmsr 0x10a

This returns the value of the IA32_ARCH_CAPABILITIES MSR.

If we wanted to see the value of this MSR for all CPUs, we could simply use:

# rdmsr 0x10a -a

Several of the 64 bits of this particular MSR, 0x10AH, describe different capabilities of the CPU. For example, bit 5 (MDS_NO) describes if the CPU is susceptible to Microarchitectural Data Sampling (MDS). If we wanted to check the value of only this bit, the command would look like:

# rdmsr 0x10a -f 5:5

Writing MSRs using WRMSR

The msr-tools utility to write or update the value of an existing MSR is wrmsr. It follows a very similar syntax to rdmsr:

# wrmsr MSR value [ -p CPU ]

As with rdmsr, MSR is the hexadecimal value of the MSR that we want to write to, value is the new hexadecimal value we want to write to the MSR, and -p CPU is an optional parameter specifying the CPU number, also in hexadecimal format.

The following is an example of how to use this utility to write a new value to an existing MSR. Developers must use this example with care, since writing to MSRs can affect your system's behavior, support status, and risk profile. Only use msr-tools to write to MSRs in cases where you understand the impact the write will have on your system. In this case we choose to write to the IA32_TSX_CTRL MSR, a thread scope MSR with address 0x122H. The example assumes the presence of this MSR. We want to write 0 to bit 1 of this MSR (TSX_CPUID_CLEAR bit).

First, we are going to read the value of the MSR.

# rdmsr 0x122
3

With this first command, we know that both bit 0 and 1 of this MSR are set to 1 (since 3 is 0b11). If we want to set bit 1 to 0, but keep bit 0 with its current value, we need to write 0b01, which is 1).

# wrmsr 0x122 1

We can now check that reading 0x122 will return 1 instead of 3:

# rdmsr 0x122 
1

We could also check the individual bit 1 with:

# rdmsr 0x122 -f 1:1
0

In all these examples, since we have not indicated the core for which these changes take place, rdmsr and wrmsr default to core 0.

Why Do I Need to Run modprobe msr?

The msr driver is not auto-loaded on some Linux distributions. Because of this, you might need to use the following command to explicitly load the module before you can use it:

# modprobe msr 

More Information

Check Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 4: Model-specific Registers for more information about all the different MSRs across Intel processor families.

 

Software Security Guidance Home | Advisory Guidance | Technical Documentation | Best Practices | Resources