€•—DŒsphinx.addnodes”Œdocument”“”)�”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)�”}”(hhh]”(hŒ pending_xref”“”)�”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…”�”}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ,/translations/zh_CN/core-api/protection-keys”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)�”}”(hhh]”hŒChinese (Traditional)”…”�”}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/zh_TW/core-api/protection-keys”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒItalian”…”�”}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/it_IT/core-api/protection-keys”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒJapanese”…”�”}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/ja_JP/core-api/protection-keys”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒKorean”…”�”}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/ko_KR/core-api/protection-keys”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒPortuguese (Brazilian)”…”�”}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/pt_BR/core-api/protection-keys”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒSpanish”…”�”}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/sp_SP/core-api/protection-keys”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒcomment”“”)�”}”(hŒ SPDX-License-Identifier: GPL-2.0”h]”hŒ SPDX-License-Identifier: GPL-2.0”…”�”}”hh·sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1hµhhh²hh³ŒF/var/lib/git/docbuild/linux/Documentation/core-api/protection-keys.rst”h´KubhŒsection”“”)�”}”(hhh]”(hŒtitle”“”)�”}”(hŒMemory Protection Keys”h]”hŒMemory Protection Keys”…”�”}”(hhÏh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhÊh²hh³hÇh´KubhŒ paragraph”“”)�”}”(hŒ¶Memory Protection Keys provide a mechanism for enforcing page-based protections, but without requiring modification of the page tables when an application changes protection domains.”h]”hŒ¶Memory Protection Keys provide a mechanism for enforcing page-based protections, but without requiring modification of the page tables when an application changes protection domains.”…”�”}”(hhßh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KhhÊh²hubhŒdefinition_list”“”)�”}”(hhh]”hŒdefinition_list_item”“”)�”}”(hŒõPkeys Userspace (PKU) is a feature which can be found on: * Intel server CPUs, Skylake and later * Intel client CPUs, Tiger Lake (11th Gen Core) and later * Future AMD CPUs * arm64 CPUs implementing the Permission Overlay Extension (FEAT_S1POE) ”h]”(hŒterm”“”)�”}”(hŒ9Pkeys Userspace (PKU) is a feature which can be found on:”h]”hŒ9Pkeys Userspace (PKU) is a feature which can be found on:”…”�”}”(hhúh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1høh³hÇh´KhhôubhŒ definition”“”)�”}”(hhh]”hŒ bullet_list”“”)�”}”(hhh]”(hŒ list_item”“”)�”}”(hŒ$Intel server CPUs, Skylake and later”h]”hÞ)�”}”(hjh]”hŒ$Intel server CPUs, Skylake and later”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K hjubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjubj)�”}”(hŒ7Intel client CPUs, Tiger Lake (11th Gen Core) and later”h]”hÞ)�”}”(hj-h]”hŒ7Intel client CPUs, Tiger Lake (11th Gen Core) and later”…”�”}”(hj/h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K hj+ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjubj)�”}”(hŒFuture AMD CPUs”h]”hÞ)�”}”(hjDh]”hŒFuture AMD CPUs”…”�”}”(hjFh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KhjBubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjubj)�”}”(hŒFarm64 CPUs implementing the Permission Overlay Extension (FEAT_S1POE) ”h]”hÞ)�”}”(hŒEarm64 CPUs implementing the Permission Overlay Extension (FEAT_S1POE)”h]”hŒEarm64 CPUs implementing the Permission Overlay Extension (FEAT_S1POE)”…”�”}”(hj]h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KhjYubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ*”uh1j h³hÇh´K hj ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhhôubeh}”(h]”h ]”h"]”h$]”h&]”uh1hòh³hÇh´Khhïubah}”(h]”h ]”h"]”h$]”h&]”uh1híhhÊh²hh³Nh´NubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒx86_64”h]”hŒx86_64”…”�”}”(hjŽh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj‹h²hh³hÇh´KubhÞ)�”}”(hŒ|Pkeys work by dedicating 4 previously Reserved bits in each page table entry to a "protection key", giving 16 possible keys.”h]”hŒ€Pkeys work by dedicating 4 previously Reserved bits in each page table entry to a “protection keyâ€�, giving 16 possible keys.”…”�”}”(hjœh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khj‹h²hubhÞ)�”}”(hŒÁProtections for each key are defined with a per-CPU user-accessible register (PKRU). Each of these is a 32-bit register storing two bits (Access Disable and Write Disable) for each of 16 keys.”h]”hŒÁProtections for each key are defined with a per-CPU user-accessible register (PKRU). Each of these is a 32-bit register storing two bits (Access Disable and Write Disable) for each of 16 keys.”…”�”}”(hjªh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khj‹h²hubhÞ)�”}”(hŒ�Being a CPU register, PKRU is inherently thread-local, potentially giving each thread a different set of protections from every other thread.”h]”hŒ�Being a CPU register, PKRU is inherently thread-local, potentially giving each thread a different set of protections from every other thread.”…”�”}”(hj¸h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khj‹h²hubhÞ)�”}”(hXThere are two instructions (RDPKRU/WRPKRU) for reading and writing to the register. The feature is only available in 64-bit mode, even though there is theoretically space in the PAE PTEs. These permissions are enforced on data access only and have no effect on instruction fetches.”h]”hXThere are two instructions (RDPKRU/WRPKRU) for reading and writing to the register. The feature is only available in 64-bit mode, even though there is theoretically space in the PAE PTEs. These permissions are enforced on data access only and have no effect on instruction fetches.”…”�”}”(hjÆh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khj‹h²hubeh}”(h]”Œx86-64”ah ]”h"]”Œx86_64”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒarm64”h]”hŒarm64”…”�”}”(hjßh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjÜh²hh³hÇh´K#ubhÞ)�”}”(hŒfPkeys use 3 bits in each page table entry, to encode a "protection key index", giving 8 possible keys.”h]”hŒjPkeys use 3 bits in each page table entry, to encode a “protection key indexâ€�, giving 8 possible keys.”…”�”}”(hjíh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K%hjÜh²hubhÞ)�”}”(hŒËProtections for each key are defined with a per-CPU user-writable system register (POR_EL0). This is a 64-bit register encoding read, write and execute overlay permissions for each protection key index.”h]”hŒËProtections for each key are defined with a per-CPU user-writable system register (POR_EL0). This is a 64-bit register encoding read, write and execute overlay permissions for each protection key index.”…”�”}”(hjûh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K(hjÜh²hubhÞ)�”}”(hŒ�Being a CPU register, POR_EL0 is inherently thread-local, potentially giving each thread a different set of protections from every other thread.”h]”hŒ�Being a CPU register, POR_EL0 is inherently thread-local, potentially giving each thread a different set of protections from every other thread.”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K,hjÜh²hubhÞ)�”}”(hŒPUnlike x86_64, the protection key permissions also apply to instruction fetches.”h]”hŒPUnlike x86_64, the protection key permissions also apply to instruction fetches.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K/hjÜh²hubeh}”(h]”Œarm64”ah ]”h"]”Œarm64”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K#ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒSyscalls”h]”hŒSyscalls”…”�”}”(hj0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj-h²hh³hÇh´K3ubhÞ)�”}”(hŒ=There are 3 system calls which directly interact with pkeys::”h]”hŒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K5hj-h²hubhŒ literal_block”“”)�”}”(hŒÂint pkey_alloc(unsigned long flags, unsigned long init_access_rights) int pkey_free(int pkey); int pkey_mprotect(unsigned long start, size_t len, unsigned long prot, int pkey);”h]”hŒÂint pkey_alloc(unsigned long flags, unsigned long init_access_rights) int pkey_free(int pkey); int pkey_mprotect(unsigned long start, size_t len, unsigned long prot, int pkey);”…”�”}”hjNsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jLh³hÇh´K7hj-h²hubhÞ)�”}”(hXBefore a pkey can be used, it must first be allocated with pkey_alloc(). An application writes to the architecture specific CPU register directly in order to change access permissions to memory covered with a key. In this example this is wrapped by a C function called pkey_set(). ::”h]”hXBefore a pkey can be used, it must first be allocated with pkey_alloc(). An application writes to the architecture specific CPU register directly in order to change access permissions to memory covered with a key. In this example this is wrapped by a C function called pkey_set().”…”�”}”(hj\h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K