-
Notifications
You must be signed in to change notification settings - Fork 99
WRMSRLIST
WRMSRLIST — Write List of Model Specific Registers
| Opcode / Instruction | Op/ En | 64/32 bit Mode Support | CPUID Feature Flag | Description |
| F3 0F 01 C6 WRMSRLIST | ZO | V/N.E. | MSRLIST | Write requested list of MSRs with the values specified in memory. |
| Op/En | Operand 1 | Operand 2 | Operand 3 | Operand 4 |
| ZO | N/A | N/A | N/A | N/A |
This instruction writes a software-provided list of up to 64 MSRs with values loaded from memory.
WRMSRLIST takes three implied input operands:
-
1 RSI: Linear address of a table of MSR addresses (8 bytes per address) .
-
RDI: Linear address of a table from which MSR data is loaded (8 bytes per MSR).
-
RCX: 64-bit bitmask of valid bits for the MSRs. Bit 0 is the valid bit for entry 0 in each table, etc.
For each RCX bit [n] from 0 to 63, if RCX[n] is 1, WRMSRLIST will write the MSR specified at entry [n] in the RSI-based table with the value read from memory at the entry [n] in the RDI-based table.
This implies a maximum of 64 MSRs that can be processed by this instruction. The processor will clear RCX[n] after it finishes handling that MSR. Similar to repeated string operations, WRMSRLIST supports partial completion for interrupts, exceptions, and traps. In these situations, the RIP register saved will point to the MSRLIST instruction while the RCX register will have cleared bits corresponding to all completed iterations.
This instruction must be executed at privilege level 0; otherwise, a general protection exception #GP(0) is generated. This instruction performs MSR-specific checks in the same manner as WRMSR.
Like WRMSRNS (and unlike WRMSR), WRMSRLIST is not defined as a serializing instruction (see “Serializing ® Instructions” in Chapter 11 of the Intel 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A). This means that software should not rely on WRMSRLIST to drain all buffered writes to memory before the next instruction is fetched and executed. For implementation reasons, some processors may serialize when writing certain MSRs, even though that is not guaranteed.
Like WRMSR and WRMSRNS, WRMSRLIST ensures that all operations before WRMSRLIST do not use any new MSR value and that all operations after WRMSRLIST do use the new values. An exception to this rule is certain store related performance-monitor events that only count stores when they are drained to memory. Since WRMSRLIST is not a serializing instruction, if software uses WRMSRLIST to change the controls for such performance-monitor events, stores issued before WRMSRLIST may be counted based on the controls established by WRMSRLIST. Software can insert the SERIALIZE instruction before the WRMSRLIST if so desired.
Those MSRs that cause a TLB invalidation when they are written via WRMSR (e.g., MTRRs) will also cause the same TLB invalidation when written by WRMSRLIST.
In places where WRMSR is being used as a proxy for a serializing instruction, a different serializing instruction can be used (e.g., SERIALIZE).
WRMSRLIST writes MSRs in order, which means the processor will ensure that an MSR in iteration “n” will be written only after previous iterations (“n-1”). If the older MSR writes had a side effect that affects the behavior of the next MSR, the processor will ensure that side effect is honored.
The processor is allowed (but not required) to “load ahead” in the list. The following are examples of things the processor may do:
- Use an old memory type or TLB entry for loads or stores to memory containing the tables despite an MSR written by a previous iteration changing MTRR or invalidating TLBs.
- Since MSR addresses are only 32-bits wide, bits 63:32 of each MSR address table entry is reserved.
- th 1 Cause a page fault for access to a table entry after the n , despite the processor having written only n MSRs.
DO WHILE RCX != 0
MSR_index ← position of least significant bit set in RCX;
Load MSR_address_table_entry from 8 bytes at the linear address RSI + (MSR_index * 8);
IF MSR_address_table_entry[63:32] != 0 THEN #GP(0); FI;
MSR_address ← MSR_address_table_entry[31:0];
Load MSR_data from 8 bytes at the linear address RDI + (MSR_index * 8);
IF WRMSR of MSR_data to the MSR with address MSR_address would #GP THEN #GP(0); FI;
Load the MSR with address MSR_address with MSR_data;
RCX[MSR_index] ← 0;
Allow delivery of any pending interrupts or traps;
OD;None.
#UD The WRMSRLIST instruction is not recognized in protected mode.
#UD The WRMSRLIST instruction is not recognized in real-address mode.
#UD The WRMSRLIST instruction is not recognized in virtual-8086 mode.
#UD The WRMSRLIST instruction is not recognized in compatibility mode.
#GP(0) If the current privilege level is not 0. If RSI [2:0] ≠ 0, RDI [2:0] ≠ 0, or bits 63:32 of an MSR-address table entry are not all zero. If an execution of WRMSR to a specified MSR with a specified value would generate a general-protection exception (\#GP(0)). If the memory address is in a non-canonical form.
#PF(fault-code) If a page fault occurs.
#UD If the LOCK prefix is used. If CPUID.07H.01H:EAX.MSRLIST[27] = 0.
- For example, the processor may take a page fault due to a linear address for the 10th entry in the MSR address table despite only having completed the MSR writes up to entry 5.
Source: Intel® 64 and IA-32 Architectures Software Developer's Manual, Combined Volumes (Order Number 325462-091US, March 2026)
Generated: 7-6-2026