Instruction
WRPKRU
Writes PKRU from EAX, changing which of the 16 protection keys allow access and writes, without a system call; ECX and EDX must be zero.
- Extensions
- Forms
- 1 (1 Legacy)
- Data
- Intel XED v2026.08.23
WRPKRU loads EAX into PKRU, the register of protection keys for user pages. The page tables tag each user page with one of 16 keys, and PKRU gives each key k two bits: bit 2k denies every data access to its pages, bit 2k + 1 denies writes. One unprivileged instruction thus changes the rights of every page of a key, for the running thread alone, without a system call or a TLB flush. ECX and EDX must be 0, or WRPKRU raises #GP; it raises #UD unless the kernel has set CR4.PKE, which CPUID leaf 7, ECX bit 4 (OSPKE) reports. Bits 63:32 of RAX, RCX and RDX do not count: on Zen 5, EAX = FFFFFFFCH under random upper bits became PKRU as it was, and ECX or EDX of 1 raised #GP and left PKRU alone.
Keys under Linux
Linux 7.3 starts a process with PKRU at 55555554H (its init_pkru_value):
key 0, which every page has until the program says otherwise, open, and
keys 1 to 15 closed to all access. A program asks the kernel for a key
with pkey_alloc() and tags pages with pkey_mprotect(); the kernel’s
documentation describes glibc’s pkey_set(), which changes a key’s
rights afterwards, as a wrapper around this write. An access that a key
denies raises #PF, which Linux delivers as SIGSEGV with si_code
SEGV_PKERR. Keys govern data accesses only: instruction fetches ignore
them (Intel’s manual, volume 3), so a page can stay executable while
unreadable.
A window around one access
Opening a key, reading and closing it relies on their order. The manuals
state it differently: Intel’s says WRPKRU never runs speculatively and
that no access PKRU governs runs before earlier WRPKRUs have updated it;
AMD’s says it orders the loads and stores before it against those after
it. With -mpku, or an -march such as skylake-avx512 or znver3 (x86-64-v4
lacks it), GCC 14 and Clang 23 at -O2 compile _wrpkru(open); v = *p; _wrpkru(old); to the load between two WRPKRUs. Clang zeroes ECX and EDX
before each; GCC zeroes them once.
Any code in the process can run WRPKRU, so keys stop stray pointers, not an attacker who chooses the instructions. RDPKRU reads the register. With an F3 prefix these bytes are STUI on Intel’s processors with user interrupts. AMD’s Zen 5 guide lists WRPKRU as microcoded.
Forms
| Instruction | Encoding | Requires |
|---|---|---|
WRPKRU
WRPKRU | NP 0F 01 EF | PKU + OSPKU |
Latency and throughput
| Model | WRPKRU |
|---|---|
| Skylake, Skylake-SP, Ice Lake | 100 / 0.25p0156 |
| Alder Lake, Sapphire Rapids | 100 / 4p0 p1 p5 p6 p11 |
| Zen 3, Zen 4 | 100 / 25ALU0 ALU1 ALU2 ALU3 |
Operation
What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.
if ecx != 0 or edx != 0: # bits 63:32 of RCX and RDX do not
fault(GP, 0) # count, nor those of RAX
pkru = eax
# Intel's manual allows no 66, F2 or F3 prefix here: with F3 the
# bytes are STUI on its processors with user interruptsRun on AMD Zen 5 (EPYC 9645): 5 cases.
Operands
| Operand | Kind | Action |
|---|---|---|
WRPKRU | ||
EDX | implicit | read |
EAX | implicit | read |
ECX | implicit | read |
Flags
None: XED records no flag that the forms test or change.
CPUID and processors
Each form belongs to an XED ISA set. A form can be used when the processor reports every CPUID bit of one of its ISA set's alternatives.
| ISA set | CPUID | Processors |
|---|---|---|
PKU | PKU + OSPKU | Comet Lake, Cannon Lake, Ice Lake (client), Tiger Lake, Alder Lake, Arrow Lake, Panther Lake, Nova Lake, Skylake-SP, Cascade Lake, Cooper Lake, Ice Lake (server), Sapphire Rapids, Emerald Rapids, Granite Rapids, Diamond Rapids, Sierra Forest, Clearwater Forest, Zen 3, Zen 4, Zen 5, Zen 6 |
More PKU instructions
Sources
- Intel XED v2026.08.23 (commit
0bcb6237345c): forms, encodings, operands, flags, exception classes, attributes, ISA sets, CPUID bits and chip model. - The CPU data of x86-64.net: Zen 3 to Zen 6, from GCC’s
-marchfeature sets and AMD’s Processor Programming References, which the page of each processor cites. - LLVM 23.1.2's x86 scheduling models (commit
85ac56026243): the latency, reciprocal throughput and ports of each form, as llvm-mca reports them. - Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 2 (325383-093, September 2026): Volume 2D, page 6-15 (WRPKRU)
- Linux kernel documentation: Memory Protection Keys
- Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 3 (325384-093, September 2026)
- AMD64 Architecture Programmer's Manual, Volume 3: General-Purpose and System Instructions (24594, rev. 3.38, July 2026)
- Software Optimization Guide for the AMD Zen5 Microarchitecture (58455, rev. 1.00, August 2024), Wayback Machine copy of AMD's ZIP
- Linux 7.3: arch/x86/mm/pkeys.c, lines 112-127 (init_pkru_value, the PKRU of a new process)
The tables are derived from Intel XED, Copyright Intel Corporation, licensed under the Apache License 2.0; x86-64.net converted and reformatted them. The timings come from LLVM's scheduling models, part of the LLVM Project, licensed under the Apache License 2.0 with LLVM Exceptions. The text is our own.