€•�þŒ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”Œ7/translations/zh_CN/arch/arm64/memory-tagging-extension”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)�”}”(hhh]”hŒChinese (Traditional)”…”�”}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ7/translations/zh_TW/arch/arm64/memory-tagging-extension”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒItalian”…”�”}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ7/translations/it_IT/arch/arm64/memory-tagging-extension”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒJapanese”…”�”}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ7/translations/ja_JP/arch/arm64/memory-tagging-extension”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒKorean”…”�”}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ7/translations/ko_KR/arch/arm64/memory-tagging-extension”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒPortuguese (Brazilian)”…”�”}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ7/translations/pt_BR/arch/arm64/memory-tagging-extension”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒSpanish”…”�”}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ7/translations/sp_SP/arch/arm64/memory-tagging-extension”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒsection”“”)�”}”(hhh]”(hŒtitle”“”)�”}”(hŒ/Memory Tagging Extension (MTE) in AArch64 Linux”h]”hŒ/Memory Tagging Extension (MTE) in AArch64 Linux”…”�”}”(hh¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhh·h²hh³ŒQ/var/lib/git/docbuild/linux/Documentation/arch/arm64/memory-tagging-extension.rst”h´KubhŒdefinition_list”“”)�”}”(hhh]”hŒdefinition_list_item”“”)�”}”(hŒaAuthors: Vincenzo Frascino Catalin Marinas ”h]”(hŒterm”“”)�”}”(hŒ6Authors: Vincenzo Frascino ”h]”(hŒAuthors: Vincenzo Frascino <”…”�”}”(hhØh²hh³Nh´NubhŒ reference”“”)�”}”(hŒvincenzo.frascino@arm.com”h]”hŒvincenzo.frascino@arm.com”…”�”}”(hhâh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”Œ mailto:vincenzo.frascino@arm.com”uh1hàhhØubhŒ>”…”�”}”(hhØh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´KhhÒubhŒ definition”“”)�”}”(hhh]”hŒ paragraph”“”)�”}”(hŒ)Catalin Marinas ”h]”(hŒCatalin Marinas <”…”�”}”(hjh²hh³Nh´Nubhá)�”}”(hŒcatalin.marinas@arm.com”h]”hŒcatalin.marinas@arm.com”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”Œmailto:catalin.marinas@arm.com”uh1hàhjubhŒ>”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Khhþubah}”(h]”h ]”h"]”h$]”h&]”uh1hühhÒubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÐh³hÊh´KhhÍubah}”(h]”h ]”h"]”h$]”h&]”uh1hËhh·h²hh³hÊh´Nubj)�”}”(hŒDate: 2020-02-25”h]”hŒDate: 2020-02-25”…”�”}”(hj7h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Khh·h²hubj)�”}”(hŒeThis document describes the provision of the Memory Tagging Extension functionality in AArch64 Linux.”h]”hŒeThis document describes the provision of the Memory Tagging Extension functionality in AArch64 Linux.”…”�”}”(hjEh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K hh·h²hubh¶)�”}”(hhh]”(h»)�”}”(hŒ Introduction”h]”hŒ Introduction”…”�”}”(hjVh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjSh²hh³hÊh´Kubj)�”}”(hXdARMv8.5 based processors introduce the Memory Tagging Extension (MTE) feature. MTE is built on top of the ARMv8.0 virtual address tagging TBI (Top Byte Ignore) feature and allows software to access a 4-bit allocation tag for each 16-byte granule in the physical address space. Such memory range must be mapped with the Normal-Tagged memory attribute. A logical tag is derived from bits 59-56 of the virtual address used for the memory access. A CPU with MTE enabled will compare the logical tag against the allocation tag and potentially raise an exception on mismatch, subject to system registers configuration.”h]”hXdARMv8.5 based processors introduce the Memory Tagging Extension (MTE) feature. MTE is built on top of the ARMv8.0 virtual address tagging TBI (Top Byte Ignore) feature and allows software to access a 4-bit allocation tag for each 16-byte granule in the physical address space. Such memory range must be mapped with the Normal-Tagged memory attribute. A logical tag is derived from bits 59-56 of the virtual address used for the memory access. A CPU with MTE enabled will compare the logical tag against the allocation tag and potentially raise an exception on mismatch, subject to system registers configuration.”…”�”}”(hjdh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KhjSh²hubeh}”(h]”Œ introduction”ah ]”h"]”Œ introduction”ah$]”h&]”uh1hµhh·h²hh³hÊh´Kubh¶)�”}”(hhh]”(h»)�”}”(hŒUserspace Support”h]”hŒUserspace Support”…”�”}”(hj}h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjzh²hh³hÊh´Kubj)�”}”(hŒ£When ``CONFIG_ARM64_MTE`` is selected and Memory Tagging Extension is supported by the hardware, the kernel advertises the feature to userspace via ``HWCAP2_MTE``.”h]”(hŒWhen ”…”�”}”(hj‹h²hh³Nh´NubhŒliteral”“”)�”}”(hŒ``CONFIG_ARM64_MTE``”h]”hŒCONFIG_ARM64_MTE”…”�”}”(hj•h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj‹ubhŒ{ is selected and Memory Tagging Extension is supported by the hardware, the kernel advertises the feature to userspace via ”…”�”}”(hj‹h²hh³Nh´Nubj”)�”}”(hŒ``HWCAP2_MTE``”h]”hŒ HWCAP2_MTE”…”�”}”(hj§h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj‹ubhŒ.”…”�”}”(hj‹h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Khjzh²hubh¶)�”}”(hhh]”(h»)�”}”(hŒPROT_MTE”h]”hŒPROT_MTE”…”�”}”(hjÂh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj¿h²hh³hÊh´K"ubj)�”}”(hŒ¦To access the allocation tags, a user process must enable the Tagged memory attribute on an address range using a new ``prot`` flag for ``mmap()`` and ``mprotect()``:”h]”(hŒvTo access the allocation tags, a user process must enable the Tagged memory attribute on an address range using a new ”…”�”}”(hjÐh²hh³Nh´Nubj”)�”}”(hŒ``prot``”h]”hŒprot”…”�”}”(hjØh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjÐubhŒ flag for ”…”�”}”(hjÐh²hh³Nh´Nubj”)�”}”(hŒ ``mmap()``”h]”hŒmmap()”…”�”}”(hjêh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjÐubhŒ and ”…”�”}”(hjÐh²hh³Nh´Nubj”)�”}”(hŒ``mprotect()``”h]”hŒ mprotect()”…”�”}”(hjüh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjÐubhŒ:”…”�”}”(hjÐh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K$hj¿h²hubj)�”}”(hŒ=``PROT_MTE`` - Pages allow access to the MTE allocation tags.”h]”(j”)�”}”(hŒ ``PROT_MTE``”h]”hŒPROT_MTE”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjubhŒ1 - Pages allow access to the MTE allocation tags.”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K(hj¿h²hubj)�”}”(hŒÎThe allocation tag is set to 0 when such pages are first mapped in the user address space and preserved on copy-on-write. ``MAP_SHARED`` is supported and the allocation tags can be shared between processes.”h]”(hŒzThe allocation tag is set to 0 when such pages are first mapped in the user address space and preserved on copy-on-write. ”…”�”}”(hj0h²hh³Nh´Nubj”)�”}”(hŒ``MAP_SHARED``”h]”hŒ MAP_SHARED”…”�”}”(hj8h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj0ubhŒF is supported and the allocation tags can be shared between processes.”…”�”}”(hj0h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K*hj¿h²hubj)�”}”(hŒÑ**Note**: ``PROT_MTE`` is only supported on ``MAP_ANONYMOUS`` and RAM-based file mappings (``tmpfs``, ``memfd``). Passing it to other types of mapping will result in ``-EINVAL`` returned by these system calls.”h]”(hŒstrong”“”)�”}”(hŒ**Note**”h]”hŒNote”…”�”}”(hjVh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jThjPubhŒ: ”…”�”}”(hjPh²hh³Nh´Nubj”)�”}”(hŒ ``PROT_MTE``”h]”hŒPROT_MTE”…”�”}”(hjhh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjPubhŒ is only supported on ”…”�”}”(hjPh²hh³Nh´Nubj”)�”}”(hŒ``MAP_ANONYMOUS``”h]”hŒ MAP_ANONYMOUS”…”�”}”(hjzh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjPubhŒ and RAM-based file mappings (”…”�”}”(hjPh²hh³Nh´Nubj”)�”}”(hŒ ``tmpfs``”h]”hŒtmpfs”…”�”}”(hjŒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjPubhŒ, ”…”�”}”(hjPh²hh³Nh´Nubj”)�”}”(hŒ ``memfd``”h]”hŒmemfd”…”�”}”(hjžh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjPubhŒ7). Passing it to other types of mapping will result in ”…”�”}”(hjPh²hh³Nh´Nubj”)�”}”(hŒ ``-EINVAL``”h]”hŒ-EINVAL”…”�”}”(hj°h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjPubhŒ returned by these system calls.”…”�”}”(hjPh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K.hj¿h²hubj)�”}”(hŒd**Note**: The ``PROT_MTE`` flag (and corresponding memory type) cannot be cleared by ``mprotect()``.”h]”(jU)�”}”(hŒ**Note**”h]”hŒNote”…”�”}”(hjÌh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jThjÈubhŒ: The ”…”�”}”(hjÈh²hh³Nh´Nubj”)�”}”(hŒ ``PROT_MTE``”h]”hŒPROT_MTE”…”�”}”(hjÞh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjÈubhŒ; flag (and corresponding memory type) cannot be cleared by ”…”�”}”(hjÈh²hh³Nh´Nubj”)�”}”(hŒ``mprotect()``”h]”hŒ mprotect()”…”�”}”(hjðh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjÈubhŒ.”…”�”}”(hjÈh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K3hj¿h²hubj)�”}”(hŒ¢**Note**: ``madvise()`` memory ranges with ``MADV_DONTNEED`` and ``MADV_FREE`` may have the allocation tags cleared (set to 0) at any point after the system call.”h]”(jU)�”}”(hŒ**Note**”h]”hŒNote”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jThjubhŒ: ”…”�”}”(hjh²hh³Nh´Nubj”)�”}”(hŒ ``madvise()``”h]”hŒ madvise()”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjubhŒ memory ranges with ”…”�”}”(hjh²hh³Nh´Nubj”)�”}”(hŒ``MADV_DONTNEED``”h]”hŒ MADV_DONTNEED”…”�”}”(hj0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjubhŒ and ”…”�”}”(hjh²hh³Nh´Nubj”)�”}”(hŒ ``MADV_FREE``”h]”hŒ MADV_FREE”…”�”}”(hjBh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjubhŒT may have the allocation tags cleared (set to 0) at any point after the system call.”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K6hj¿h²hubeh}”(h]”Œprot-mte”ah ]”h"]”Œprot_mte”ah$]”h&]”uh1hµhjzh²hh³hÊh´K"ubh¶)�”}”(hhh]”(h»)�”}”(hŒTag Check Faults”h]”hŒTag Check Faults”…”�”}”(hjeh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjbh²hh³hÊh´K;ubj)�”}”(hŒ¢When ``PROT_MTE`` is enabled on an address range and a mismatch between the logical and allocation tags occurs on access, there are three configurable behaviours:”h]”(hŒWhen ”…”�”}”(hjsh²hh³Nh´Nubj”)�”}”(hŒ ``PROT_MTE``”h]”hŒPROT_MTE”…”�”}”(hj{h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjsubhŒ‘ is enabled on an address range and a mismatch between the logical and allocation tags occurs on access, there are three configurable behaviours:”…”�”}”(hjsh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K=hjbh²hubhŒ bullet_list”“”)�”}”(hhh]”(hŒ list_item”“”)�”}”(hŒW*Ignore* - This is the default mode. The CPU (and kernel) ignores the tag check fault. ”h]”j)�”}”(hŒV*Ignore* - This is the default mode. The CPU (and kernel) ignores the tag check fault.”h]”(hŒemphasis”“”)�”}”(hŒ*Ignore*”h]”hŒIgnore”…”�”}”(hj¤h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¢hjžubhŒN - This is the default mode. The CPU (and kernel) ignores the tag check fault.”…”�”}”(hjžh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KAhjšubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hj•h²hh³hÊh´Nubj™)�”}”(hX *Synchronous* - The kernel raises a ``SIGSEGV`` synchronously, with ``.si_code = SEGV_MTESERR`` and ``.si_addr = ``. The memory access is not performed. If ``SIGSEGV`` is ignored or blocked by the offending thread, the containing process is terminated with a ``coredump``. ”h]”j)�”}”(hX*Synchronous* - The kernel raises a ``SIGSEGV`` synchronously, with ``.si_code = SEGV_MTESERR`` and ``.si_addr = ``. The memory access is not performed. If ``SIGSEGV`` is ignored or blocked by the offending thread, the containing process is terminated with a ``coredump``.”h]”(j£)�”}”(hŒ *Synchronous*”h]”hŒ Synchronous”…”�”}”(hjÊh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¢hjÆubhŒ - The kernel raises a ”…”�”}”(hjÆh²hh³Nh´Nubj”)�”}”(hŒ ``SIGSEGV``”h]”hŒSIGSEGV”…”�”}”(hjÜh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjÆubhŒ synchronously, with ”…”�”}”(hjÆh²hh³Nh´Nubj”)�”}”(hŒ``.si_code = SEGV_MTESERR``”h]”hŒ.si_code = SEGV_MTESERR”…”�”}”(hjîh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjÆubhŒ and ”…”�”}”(hjÆh²hh³Nh´Nubj”)�”}”(hŒ``.si_addr = ``”h]”hŒ.si_addr = ”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjÆubhŒ). The memory access is not performed. If ”…”�”}”(hjÆh²hh³Nh´Nubj”)�”}”(hŒ ``SIGSEGV``”h]”hŒSIGSEGV”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjÆubhŒ\ is ignored or blocked by the offending thread, the containing process is terminated with a ”…”�”}”(hjÆh²hh³Nh´Nubj”)�”}”(hŒ ``coredump``”h]”hŒcoredump”…”�”}”(hj$h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjÆubhŒ.”…”�”}”(hjÆh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KDhjÂubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hj•h²hh³hÊh´Nubj™)�”}”(hŒß*Asynchronous* - The kernel raises a ``SIGSEGV``, in the offending thread, asynchronously following one or multiple tag check faults, with ``.si_code = SEGV_MTEAERR`` and ``.si_addr = 0`` (the faulting address is unknown). ”h]”j)�”}”(hŒÞ*Asynchronous* - The kernel raises a ``SIGSEGV``, in the offending thread, asynchronously following one or multiple tag check faults, with ``.si_code = SEGV_MTEAERR`` and ``.si_addr = 0`` (the faulting address is unknown).”h]”(j£)�”}”(hŒ*Asynchronous*”h]”hŒ Asynchronous”…”�”}”(hjJh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¢hjFubhŒ - The kernel raises a ”…”�”}”(hjFh²hh³Nh´Nubj”)�”}”(hŒ ``SIGSEGV``”h]”hŒSIGSEGV”…”�”}”(hj\h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjFubhŒ[, in the offending thread, asynchronously following one or multiple tag check faults, with ”…”�”}”(hjFh²hh³Nh´Nubj”)�”}”(hŒ``.si_code = SEGV_MTEAERR``”h]”hŒ.si_code = SEGV_MTEAERR”…”�”}”(hjnh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjFubhŒ and ”…”�”}”(hjFh²hh³Nh´Nubj”)�”}”(hŒ``.si_addr = 0``”h]”hŒ .si_addr = 0”…”�”}”(hj€h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjFubhŒ# (the faulting address is unknown).”…”�”}”(hjFh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KJhjBubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hj•h²hh³hÊh´Nubj™)�”}”(hŒl*Asymmetric* - Reads are handled as for synchronous mode while writes are handled as for asynchronous mode. ”h]”j)�”}”(hŒk*Asymmetric* - Reads are handled as for synchronous mode while writes are handled as for asynchronous mode.”h]”(j£)�”}”(hŒ *Asymmetric*”h]”hŒ Asymmetric”…”�”}”(hj¦h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¢hj¢ubhŒ_ - Reads are handled as for synchronous mode while writes are handled as for asynchronous mode.”…”�”}”(hj¢h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KOhjžubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hj•h²hh³hÊh´Nubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1j“h³hÊh´KAhjbh²hubj)�”}”(hŒÛThe user can select the above modes, per thread, using the ``prctl(PR_SET_TAGGED_ADDR_CTRL, flags, 0, 0, 0)`` system call where ``flags`` contains any number of the following values in the ``PR_MTE_TCF_MASK`` bit-field:”h]”(hŒ;The user can select the above modes, per thread, using the ”…”�”}”(hjÌh²hh³Nh´Nubj”)�”}”(hŒ2``prctl(PR_SET_TAGGED_ADDR_CTRL, flags, 0, 0, 0)``”h]”hŒ.prctl(PR_SET_TAGGED_ADDR_CTRL, flags, 0, 0, 0)”…”�”}”(hjÔh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjÌubhŒ system call where ”…”�”}”(hjÌh²hh³Nh´Nubj”)�”}”(hŒ ``flags``”h]”hŒflags”…”�”}”(hjæh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjÌubhŒ4 contains any number of the following values in the ”…”�”}”(hjÌh²hh³Nh´Nubj”)�”}”(hŒ``PR_MTE_TCF_MASK``”h]”hŒPR_MTE_TCF_MASK”…”�”}”(hjøh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjÌubhŒ bit-field:”…”�”}”(hjÌh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KRhjbh²hubj”)�”}”(hhh]”(j™)�”}”(hŒq``PR_MTE_TCF_NONE``  - *Ignore* tag check faults (ignored if combined with other options)”h]”hÌ)�”}”(hhh]”hÑ)�”}”(hŒZ``PR_MTE_TCF_NONE``  - *Ignore* tag check faults (ignored if combined with other options)”h]”(h×)�”}”(hŒ1``PR_MTE_TCF_NONE``  - *Ignore* tag check faults”h]”(j”)�”}”(hŒ``PR_MTE_TCF_NONE``”h]”hŒPR_MTE_TCF_NONE”…”�”}”(hj"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjubhŒ  - ”…”�”}”(hjh²hh³Nh´Nubj£)�”}”(hŒ*Ignore*”h]”hŒIgnore”…”�”}”(hj4h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¢hjubhŒ tag check faults”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´KWhjubhý)�”}”(hhh]”j)�”}”(hŒ((ignored if combined with other options)”h]”hŒ((ignored if combined with other options)”…”�”}”(hjOh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KXhjLubah}”(h]”h ]”h"]”h$]”h&]”uh1hühjubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÐh³hÊh´KWhjubah}”(h]”h ]”h"]”h$]”h&]”uh1hËhjubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hjh²hh³Nh´Nubj™)�”}”(hŒ9``PR_MTE_TCF_SYNC`` - *Synchronous* tag check fault mode”h]”j)�”}”(hjwh]”(j”)�”}”(hŒ``PR_MTE_TCF_SYNC``”h]”hŒPR_MTE_TCF_SYNC”…”�”}”(hj|h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjyubhŒ - ”…”�”}”(hjyh²hh³Nh´Nubj£)�”}”(hŒ *Synchronous*”h]”hŒ Synchronous”…”�”}”(hjŽh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¢hjyubhŒ tag check fault mode”…”�”}”(hjyh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KYhjuubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hjh²hh³hÊh´Nubj™)�”}”(hŒ;``PR_MTE_TCF_ASYNC`` - *Asynchronous* tag check fault mode ”h]”j)�”}”(hŒ:``PR_MTE_TCF_ASYNC`` - *Asynchronous* tag check fault mode”h]”(j”)�”}”(hŒ``PR_MTE_TCF_ASYNC``”h]”hŒPR_MTE_TCF_ASYNC”…”�”}”(hj´h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj°ubhŒ - ”…”�”}”(hj°h²hh³Nh´Nubj£)�”}”(hŒ*Asynchronous*”h]”hŒ Asynchronous”…”�”}”(hjÆh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¢hj°ubhŒ tag check fault mode”…”�”}”(hj°h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KZhj¬ubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hjh²hh³hÊh´Nubeh}”(h]”h ]”h"]”h$]”h&]”jÊjËuh1j“h³hÊh´KWhjbh²hubj)�”}”(hŒúIf no modes are specified, tag check faults are ignored. If a single mode is specified, the program will run in that mode. If multiple modes are specified, the mode is selected as described in the "Per-CPU preferred tag checking modes" section below.”h]”hŒþIf no modes are specified, tag check faults are ignored. If a single mode is specified, the program will run in that mode. If multiple modes are specified, the mode is selected as described in the “Per-CPU preferred tag checking modesâ€� section below.”…”�”}”(hjêh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K\hjbh²hubj)�”}”(hŒ·The current tag check fault configuration can be read using the ``prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0)`` system call. If multiple modes were requested then all will be reported.”h]”(hŒ@The current tag check fault configuration can be read using the ”…”�”}”(hjøh²hh³Nh´Nubj”)�”}”(hŒ.``prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0)``”h]”hŒ*prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0)”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjøubhŒI system call. If multiple modes were requested then all will be reported.”…”�”}”(hjøh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Kahjbh²hubj)�”}”(hŒkTag checking can also be disabled for a user thread by setting the ``PSTATE.TCO`` bit with ``MSR TCO, #1``.”h]”(hŒCTag checking can also be disabled for a user thread by setting the ”…”�”}”(hjh²hh³Nh´Nubj”)�”}”(hŒ``PSTATE.TCO``”h]”hŒ PSTATE.TCO”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjubhŒ bit with ”…”�”}”(hjh²hh³Nh´Nubj”)�”}”(hŒ``MSR TCO, #1``”h]”hŒ MSR TCO, #1”…”�”}”(hj2h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjubhŒ.”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Kehjbh²hubj)�”}”(hŒ�**Note**: Signal handlers are always invoked with ``PSTATE.TCO = 0``, irrespective of the interrupted context. ``PSTATE.TCO`` is restored on ``sigreturn()``.”h]”(jU)�”}”(hŒ**Note**”h]”hŒNote”…”�”}”(hjNh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jThjJubhŒ*: Signal handlers are always invoked with ”…”�”}”(hjJh²hh³Nh´Nubj”)�”}”(hŒ``PSTATE.TCO = 0``”h]”hŒPSTATE.TCO = 0”…”�”}”(hj`h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjJubhŒ+, irrespective of the interrupted context. ”…”�”}”(hjJh²hh³Nh´Nubj”)�”}”(hŒ``PSTATE.TCO``”h]”hŒ PSTATE.TCO”…”�”}”(hjrh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjJubhŒ is restored on ”…”�”}”(hjJh²hh³Nh´Nubj”)�”}”(hŒ``sigreturn()``”h]”hŒ sigreturn()”…”�”}”(hj„h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjJubhŒ.”…”�”}”(hjJh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Khhjbh²hubj)�”}”(hŒP**Note**: There are no *match-all* logical tags available for user applications.”h]”(jU)�”}”(hŒ**Note**”h]”hŒNote”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jThjœubhŒ: There are no ”…”�”}”(hjœh²hh³Nh´Nubj£)�”}”(hŒ *match-all*”h]”hŒ match-all”…”�”}”(hj²h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¢hjœubhŒ. logical tags available for user applications.”…”�”}”(hjœh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Klhjbh²hubj)�”}”(hXÞ**Note**: Kernel accesses to the user address space (e.g. ``read()`` system call) are not checked if the user thread tag checking mode is ``PR_MTE_TCF_NONE`` or ``PR_MTE_TCF_ASYNC``. If the tag checking mode is ``PR_MTE_TCF_SYNC``, the kernel makes a best effort to check its user address accesses, however it cannot always guarantee it. Kernel accesses to user addresses are always performed with an effective ``PSTATE.TCO`` value of zero, regardless of the user configuration.”h]”(jU)�”}”(hŒ**Note**”h]”hŒNote”…”�”}”(hjÎh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jThjÊubhŒ2: Kernel accesses to the user address space (e.g. ”…”�”}”(hjÊh²hh³Nh´Nubj”)�”}”(hŒ ``read()``”h]”hŒread()”…”�”}”(hjàh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjÊubhŒF system call) are not checked if the user thread tag checking mode is ”…”�”}”(hjÊh²hh³Nh´Nubj”)�”}”(hŒ``PR_MTE_TCF_NONE``”h]”hŒPR_MTE_TCF_NONE”…”�”}”(hjòh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjÊubhŒ or ”…”�”}”(hjÊh²hh³Nh´Nubj”)�”}”(hŒ``PR_MTE_TCF_ASYNC``”h]”hŒPR_MTE_TCF_ASYNC”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjÊubhŒ. If the tag checking mode is ”…”�”}”(hjÊh²hh³Nh´Nubj”)�”}”(hŒ``PR_MTE_TCF_SYNC``”h]”hŒPR_MTE_TCF_SYNC”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjÊubhŒµ, the kernel makes a best effort to check its user address accesses, however it cannot always guarantee it. Kernel accesses to user addresses are always performed with an effective ”…”�”}”(hjÊh²hh³Nh´Nubj”)�”}”(hŒ``PSTATE.TCO``”h]”hŒ PSTATE.TCO”…”�”}”(hj(h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjÊubhŒ5 value of zero, regardless of the user configuration.”…”�”}”(hjÊh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Kohjbh²hubeh}”(h]”Œtag-check-faults”ah ]”h"]”Œtag check faults”ah$]”h&]”uh1hµhjzh²hh³hÊh´K;ubh¶)�”}”(hhh]”(h»)�”}”(hŒAExcluding Tags in the ``IRG``, ``ADDG`` and ``SUBG`` instructions”h]”(hŒExcluding Tags in the ”…”�”}”(hjKh²hh³Nh´Nubj”)�”}”(hŒ``IRG``”h]”hŒIRG”…”�”}”(hjSh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjKubhŒ, ”…”�”}”(hjKh²hh³Nh´Nubj”)�”}”(hŒ``ADDG``”h]”hŒADDG”…”�”}”(hjeh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjKubhŒ and ”…”�”}”(hjKh²hh³Nh´Nubj”)�”}”(hŒ``SUBG``”h]”hŒSUBG”…”�”}”(hjwh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjKubhŒ instructions”…”�”}”(hjKh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hºhjHh²hh³hÊh´Kxubj)�”}”(hX†The architecture allows excluding certain tags to be randomly generated via the ``GCR_EL1.Exclude`` register bit-field. By default, Linux excludes all tags other than 0. A user thread can enable specific tags in the randomly generated set using the ``prctl(PR_SET_TAGGED_ADDR_CTRL, flags, 0, 0, 0)`` system call where ``flags`` contains the tags bitmap in the ``PR_MTE_TAG_MASK`` bit-field.”h]”(hŒPThe architecture allows excluding certain tags to be randomly generated via the ”…”�”}”(hj�h²hh³Nh´Nubj”)�”}”(hŒ``GCR_EL1.Exclude``”h]”hŒGCR_EL1.Exclude”…”�”}”(hj—h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj�ubhŒ– register bit-field. By default, Linux excludes all tags other than 0. A user thread can enable specific tags in the randomly generated set using the ”…”�”}”(hj�h²hh³Nh´Nubj”)�”}”(hŒ2``prctl(PR_SET_TAGGED_ADDR_CTRL, flags, 0, 0, 0)``”h]”hŒ.prctl(PR_SET_TAGGED_ADDR_CTRL, flags, 0, 0, 0)”…”�”}”(hj©h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj�ubhŒ system call where ”…”�”}”(hj�h²hh³Nh´Nubj”)�”}”(hŒ ``flags``”h]”hŒflags”…”�”}”(hj»h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj�ubhŒ! contains the tags bitmap in the ”…”�”}”(hj�h²hh³Nh´Nubj”)�”}”(hŒ``PR_MTE_TAG_MASK``”h]”hŒPR_MTE_TAG_MASK”…”�”}”(hjÍh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj�ubhŒ bit-field.”…”�”}”(hj�h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KzhjHh²hubj)�”}”(hŒÈ**Note**: The hardware uses an exclude mask but the ``prctl()`` interface provides an include mask. An include mask of ``0`` (exclusion mask ``0xffff``) results in the CPU always generating tag ``0``.”h]”(jU)�”}”(hŒ**Note**”h]”hŒNote”…”�”}”(hjéh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jThjåubhŒ,: The hardware uses an exclude mask but the ”…”�”}”(hjåh²hh³Nh´Nubj”)�”}”(hŒ ``prctl()``”h]”hŒprctl()”…”�”}”(hjûh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjåubhŒ8 interface provides an include mask. An include mask of ”…”�”}”(hjåh²hh³Nh´Nubj”)�”}”(hŒ``0``”h]”hŒ0”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjåubhŒ (exclusion mask ”…”�”}”(hjåh²hh³Nh´Nubj”)�”}”(hŒ ``0xffff``”h]”hŒ0xffff”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjåubhŒ+) results in the CPU always generating tag ”…”�”}”(hjåh²hh³Nh´Nubj”)�”}”(hŒ``0``”h]”hŒ0”…”�”}”(hj1h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjåubhŒ.”…”�”}”(hjåh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K�hjHh²hubeh}”(h]”Œ4excluding-tags-in-the-irg-addg-and-subg-instructions”ah ]”h"]”Œ5excluding tags in the irg, addg and subg instructions”ah$]”h&]”uh1hµhjzh²hh³hÊh´Kxubh¶)�”}”(hhh]”(h»)�”}”(hŒ#Per-CPU preferred tag checking mode”h]”hŒ#Per-CPU preferred tag checking mode”…”�”}”(hjTh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjQh²hh³hÊh´K†ubj)�”}”(hXÑOn some CPUs the performance of MTE in stricter tag checking modes is similar to that of less strict tag checking modes. This makes it worthwhile to enable stricter checks on those CPUs when a less strict checking mode is requested, in order to gain the error detection benefits of the stricter checks without the performance downsides. To support this scenario, a privileged user may configure a stricter tag checking mode as the CPU's preferred tag checking mode.”h]”hXÓOn some CPUs the performance of MTE in stricter tag checking modes is similar to that of less strict tag checking modes. This makes it worthwhile to enable stricter checks on those CPUs when a less strict checking mode is requested, in order to gain the error detection benefits of the stricter checks without the performance downsides. To support this scenario, a privileged user may configure a stricter tag checking mode as the CPU’s preferred tag checking mode.”…”�”}”(hjbh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KˆhjQh²hubj)�”}”(hŒûThe preferred tag checking mode for each CPU is controlled by ``/sys/devices/system/cpu/cpu/mte_tcf_preferred``, to which a privileged user may write the value ``async``, ``sync`` or ``asymm``. The default preferred mode for each CPU is ``async``.”h]”(hŒ>The preferred tag checking mode for each CPU is controlled by ”…”�”}”(hjph²hh³Nh´Nubj”)�”}”(hŒ4``/sys/devices/system/cpu/cpu/mte_tcf_preferred``”h]”hŒ0/sys/devices/system/cpu/cpu/mte_tcf_preferred”…”�”}”(hjxh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjpubhŒ1, to which a privileged user may write the value ”…”�”}”(hjph²hh³Nh´Nubj”)�”}”(hŒ ``async``”h]”hŒasync”…”�”}”(hjŠh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjpubhŒ, ”…”�”}”(hjph²hh³Nh´Nubj”)�”}”(hŒ``sync``”h]”hŒsync”…”�”}”(hjœh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjpubhŒ or ”…”�”}”(hjph²hh³Nh´Nubj”)�”}”(hŒ ``asymm``”h]”hŒasymm”…”�”}”(hj®h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjpubhŒ.. The default preferred mode for each CPU is ”…”�”}”(hjph²hh³Nh´Nubj”)�”}”(hŒ ``async``”h]”hŒasync”…”�”}”(hjÀh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjpubhŒ.”…”�”}”(hjph²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K�hjQh²hubj)�”}”(hX[To allow a program to potentially run in the CPU's preferred tag checking mode, the user program may set multiple tag check fault mode bits in the ``flags`` argument to the ``prctl(PR_SET_TAGGED_ADDR_CTRL, flags, 0, 0, 0)`` system call. If both synchronous and asynchronous modes are requested then asymmetric mode may also be selected by the kernel. If the CPU's preferred tag checking mode is in the task's set of provided tag checking modes, that mode will be selected. Otherwise, one of the modes in the task's mode will be selected by the kernel from the task's mode set using the preference order:”h]”(hŒ•To allow a program to potentially run in the CPU’s preferred tag checking mode, the user program may set multiple tag check fault mode bits in the ”…”�”}”(hjØh²hh³Nh´Nubj”)�”}”(hŒ ``flags``”h]”hŒflags”…”�”}”(hjàh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjØubhŒ argument to the ”…”�”}”(hjØh²hh³Nh´Nubj”)�”}”(hŒ2``prctl(PR_SET_TAGGED_ADDR_CTRL, flags, 0, 0, 0)``”h]”hŒ.prctl(PR_SET_TAGGED_ADDR_CTRL, flags, 0, 0, 0)”…”�”}”(hjòh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjØubhX„ system call. If both synchronous and asynchronous modes are requested then asymmetric mode may also be selected by the kernel. If the CPU’s preferred tag checking mode is in the task’s set of provided tag checking modes, that mode will be selected. Otherwise, one of the modes in the task’s mode will be selected by the kernel from the task’s mode set using the preference order:”…”�”}”(hjØh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K•hjQh²hubhŒ block_quote”“”)�”}”(hŒ-1. Asynchronous 2. Asymmetric 3. Synchronous ”h]”hŒenumerated_list”“”)�”}”(hhh]”(j™)�”}”(hŒ Asynchronous”h]”j)�”}”(hj h]”hŒ Asynchronous”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KŸhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hj ubj™)�”}”(hŒ Asymmetric”h]”j)�”}”(hj. h]”hŒ Asymmetric”…”�”}”(hj0 h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K hj, ubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hj ubj™)�”}”(hŒ Synchronous ”h]”j)�”}”(hŒ Synchronous”h]”hŒ Synchronous”…”�”}”(hjG h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K¡hjC ubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hj ubeh}”(h]”h ]”h"]”h$]”h&]”Œenumtype”Œarabic”Œprefix”hŒsuffix”Œ.”uh1j hj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j h³hÊh´KŸhjQh²hubj)�”}”(hŒcNote that there is no way for userspace to request multiple modes and also disable asymmetric mode.”h]”hŒcNote that there is no way for userspace to request multiple modes and also disable asymmetric mode.”…”�”}”(hjl h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K£hjQh²hubeh}”(h]”Œ#per-cpu-preferred-tag-checking-mode”ah ]”h"]”Œ#per-cpu preferred tag checking mode”ah$]”h&]”uh1hµhjzh²hh³hÊh´K†ubh¶)�”}”(hhh]”(h»)�”}”(hŒInitial process state”h]”hŒInitial process state”…”�”}”(hj… h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj‚ h²hh³hÊh´K§ubj)�”}”(hŒAOn ``execve()``, the new process has the following configuration:”h]”(hŒOn ”…”�”}”(hj“ h²hh³Nh´Nubj”)�”}”(hŒ ``execve()``”h]”hŒexecve()”…”�”}”(hj› h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj“ ubhŒ2, the new process has the following configuration:”…”�”}”(hj“ h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K©hj‚ h²hubj”)�”}”(hhh]”(j™)�”}”(hŒ-``PR_TAGGED_ADDR_ENABLE`` set to 0 (disabled)”h]”j)�”}”(hj¸ h]”(j”)�”}”(hŒ``PR_TAGGED_ADDR_ENABLE``”h]”hŒPR_TAGGED_ADDR_ENABLE”…”�”}”(hj½ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjº ubhŒ set to 0 (disabled)”…”�”}”(hjº h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K«hj¶ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hj³ h²hh³hÊh´Nubj™)�”}”(hŒ=No tag checking modes are selected (tag check faults ignored)”h]”j)�”}”(hjÝ h]”hŒ=No tag checking modes are selected (tag check faults ignored)”…”�”}”(hjß h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K¬hjÛ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hj³ h²hh³hÊh´Nubj™)�”}”(hŒ0``PR_MTE_TAG_MASK`` set to 0 (all tags excluded)”h]”j)�”}”(hjô h]”(j”)�”}”(hŒ``PR_MTE_TAG_MASK``”h]”hŒPR_MTE_TAG_MASK”…”�”}”(hjù h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjö ubhŒ set to 0 (all tags excluded)”…”�”}”(hjö h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K­hjò ubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hj³ h²hh³hÊh´Nubj™)�”}”(hŒ``PSTATE.TCO`` set to 0”h]”j)�”}”(hj h]”(j”)�”}”(hŒ``PSTATE.TCO``”h]”hŒ PSTATE.TCO”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj ubhŒ set to 0”…”�”}”(hj h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K®hj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hj³ h²hh³hÊh´Nubj™)�”}”(hŒ7``PROT_MTE`` not set on any of the initial memory maps ”h]”j)�”}”(hŒ6``PROT_MTE`` not set on any of the initial memory maps”h]”(j”)�”}”(hŒ ``PROT_MTE``”h]”hŒPROT_MTE”…”�”}”(hjD h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj@ ubhŒ* not set on any of the initial memory maps”…”�”}”(hj@ h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K¯hj< ubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hj³ h²hh³hÊh´Nubeh}”(h]”h ]”h"]”h$]”h&]”jÊjËuh1j“h³hÊh´K«hj‚ h²hubj)�”}”(hŒÚOn ``fork()``, the new process inherits the parent's configuration and memory map attributes with the exception of the ``madvise()`` ranges with ``MADV_WIPEONFORK`` which will have the data and tags cleared (set to 0).”h]”(hŒOn ”…”�”}”(hjh h²hh³Nh´Nubj”)�”}”(hŒ ``fork()``”h]”hŒfork()”…”�”}”(hjp h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjh ubhŒl, the new process inherits the parent’s configuration and memory map attributes with the exception of the ”…”�”}”(hjh h²hh³Nh´Nubj”)�”}”(hŒ ``madvise()``”h]”hŒ madvise()”…”�”}”(hj‚ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjh ubhŒ ranges with ”…”�”}”(hjh h²hh³Nh´Nubj”)�”}”(hŒ``MADV_WIPEONFORK``”h]”hŒMADV_WIPEONFORK”…”�”}”(hj” h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjh ubhŒ6 which will have the data and tags cleared (set to 0).”…”�”}”(hjh h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K±hj‚ h²hubeh}”(h]”Œinitial-process-state”ah ]”h"]”Œinitial process state”ah$]”h&]”uh1hµhjzh²hh³hÊh´K§ubh¶)�”}”(hhh]”(h»)�”}”(hŒThe ``ptrace()`` interface”h]”(hŒThe ”…”�”}”(hj· h²hh³Nh´Nubj”)�”}”(hŒ ``ptrace()``”h]”hŒptrace()”…”�”}”(hj¿ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj· ubhŒ interface”…”�”}”(hj· h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hºhj´ h²hh³hÊh´K·ubj)�”}”(hŒÚ``PTRACE_PEEKMTETAGS`` and ``PTRACE_POKEMTETAGS`` allow a tracer to read the tags from or set the tags to a tracee's address space. The ``ptrace()`` system call is invoked as ``ptrace(request, pid, addr, data)`` where:”h]”(j”)�”}”(hŒ``PTRACE_PEEKMTETAGS``”h]”hŒPTRACE_PEEKMTETAGS”…”�”}”(hjÛ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj× ubhŒ and ”…”�”}”(hj× h²hh³Nh´Nubj”)�”}”(hŒ``PTRACE_POKEMTETAGS``”h]”hŒPTRACE_POKEMTETAGS”…”�”}”(hjí h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj× ubhŒY allow a tracer to read the tags from or set the tags to a tracee’s address space. The ”…”�”}”(hj× h²hh³Nh´Nubj”)�”}”(hŒ ``ptrace()``”h]”hŒptrace()”…”�”}”(hjÿ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj× ubhŒ system call is invoked as ”…”�”}”(hj× h²hh³Nh´Nubj”)�”}”(hŒ$``ptrace(request, pid, addr, data)``”h]”hŒ ptrace(request, pid, addr, data)”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj× ubhŒ where:”…”�”}”(hj× h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K¹hj´ h²hubj”)�”}”(hhh]”(j™)�”}”(hŒF``request`` - one of ``PTRACE_PEEKMTETAGS`` or ``PTRACE_POKEMTETAGS``.”h]”j)�”}”(hj. h]”(j”)�”}”(hŒ ``request``”h]”hŒrequest”…”�”}”(hj3 h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj0 ubhŒ - one of ”…”�”}”(hj0 h²hh³Nh´Nubj”)�”}”(hŒ``PTRACE_PEEKMTETAGS``”h]”hŒPTRACE_PEEKMTETAGS”…”�”}”(hjE h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj0 ubhŒ or ”…”�”}”(hj0 h²hh³Nh´Nubj”)�”}”(hŒ``PTRACE_POKEMTETAGS``”h]”hŒPTRACE_POKEMTETAGS”…”�”}”(hjW h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj0 ubhŒ.”…”�”}”(hj0 h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K¾hj, ubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hj) h²hh³hÊh´Nubj™)�”}”(hŒ``pid`` - the tracee's PID.”h]”j)�”}”(hjw h]”(j”)�”}”(hŒ``pid``”h]”hŒpid”…”�”}”(hj| h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjy ubhŒ - the tracee’s PID.”…”�”}”(hjy h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K¿hju ubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hj) h²hh³hÊh´Nubj™)�”}”(hŒ1``addr`` - address in the tracee's address space.”h]”j)�”}”(hjœ h]”(j”)�”}”(hŒ``addr``”h]”hŒaddr”…”�”}”(hj¡ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjž ubhŒ+ - address in the tracee’s address space.”…”�”}”(hjž h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KÀhjš ubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hj) h²hh³hÊh´Nubj™)�”}”(hŒ„``data`` - pointer to a ``struct iovec`` where ``iov_base`` points to a buffer of ``iov_len`` length in the tracer's address space. ”h]”j)�”}”(hŒƒ``data`` - pointer to a ``struct iovec`` where ``iov_base`` points to a buffer of ``iov_len`` length in the tracer's address space.”h]”(j”)�”}”(hŒ``data``”h]”hŒdata”…”�”}”(hjÇ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjà ubhŒ - pointer to a ”…”�”}”(hjà h²hh³Nh´Nubj”)�”}”(hŒ``struct iovec``”h]”hŒ struct iovec”…”�”}”(hjÙ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjà ubhŒ where ”…”�”}”(hjà h²hh³Nh´Nubj”)�”}”(hŒ ``iov_base``”h]”hŒiov_base”…”�”}”(hjë h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjà ubhŒ points to a buffer of ”…”�”}”(hjà h²hh³Nh´Nubj”)�”}”(hŒ ``iov_len``”h]”hŒiov_len”…”�”}”(hjý h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjà ubhŒ( length in the tracer’s address space.”…”�”}”(hjà h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KÁhj¿ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hj) h²hh³hÊh´Nubeh}”(h]”h ]”h"]”h$]”h&]”jÊjËuh1j“h³hÊh´K¾hj´ h²hubj)�”}”(hŒ¡The tags in the tracer's ``iov_base`` buffer are represented as one 4-bit tag per byte and correspond to a 16-byte MTE tag granule in the tracee's address space.”h]”(hŒThe tags in the tracer’s ”…”�”}”(hj! h²hh³Nh´Nubj”)�”}”(hŒ ``iov_base``”h]”hŒiov_base”…”�”}”(hj) h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj! ubhŒ~ buffer are represented as one 4-bit tag per byte and correspond to a 16-byte MTE tag granule in the tracee’s address space.”…”�”}”(hj! h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KÄhj´ h²hubj)�”}”(hŒq**Note**: If ``addr`` is not aligned to a 16-byte granule, the kernel will use the corresponding aligned address.”h]”(jU)�”}”(hŒ**Note**”h]”hŒNote”…”�”}”(hjE h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jThjA ubhŒ: If ”…”�”}”(hjA h²hh³Nh´Nubj”)�”}”(hŒ``addr``”h]”hŒaddr”…”�”}”(hjW h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjA ubhŒ\ is not aligned to a 16-byte granule, the kernel will use the corresponding aligned address.”…”�”}”(hjA h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KÈhj´ h²hubj)�”}”(hŒ``ptrace()`` return value:”h]”(j”)�”}”(hŒ ``ptrace()``”h]”hŒptrace()”…”�”}”(hjs h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjo ubhŒ return value:”…”�”}”(hjo h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KËhj´ h²hubj”)�”}”(hhh]”(j™)�”}”(hX0 - tags were copied, the tracer's ``iov_len`` was updated to the number of tags transferred. This may be smaller than the requested ``iov_len`` if the requested address range in the tracee's or the tracer's space cannot be accessed or does not have valid tags.”h]”j)�”}”(hX0 - tags were copied, the tracer's ``iov_len`` was updated to the number of tags transferred. This may be smaller than the requested ``iov_len`` if the requested address range in the tracee's or the tracer's space cannot be accessed or does not have valid tags.”h]”(hŒ%0 - tags were copied, the tracer’s ”…”�”}”(hj’ h²hh³Nh´Nubj”)�”}”(hŒ ``iov_len``”h]”hŒiov_len”…”�”}”(hjš h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj’ ubhŒW was updated to the number of tags transferred. This may be smaller than the requested ”…”�”}”(hj’ h²hh³Nh´Nubj”)�”}”(hŒ ``iov_len``”h]”hŒiov_len”…”�”}”(hj¬ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj’ ubhŒy if the requested address range in the tracee’s or the tracer’s space cannot be accessed or does not have valid tags.”…”�”}”(hj’ h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KÍhjŽ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hj‹ h²hh³hÊh´Nubj™)�”}”(hŒ4``-EPERM`` - the specified process cannot be traced.”h]”j)�”}”(hjÌ h]”(j”)�”}”(hŒ ``-EPERM``”h]”hŒ-EPERM”…”�”}”(hjÑ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjÎ ubhŒ* - the specified process cannot be traced.”…”�”}”(hjÎ h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KÑhjÊ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hj‹ h²hh³hÊh´Nubj™)�”}”(hŒÀ``-EIO`` - the tracee's address range cannot be accessed (e.g. invalid address) or does not have valid tags (not mapped with the ``PROT_MTE`` flag) and no tags copied. ``iov_len`` not updated.”h]”j)�”}”(hŒÀ``-EIO`` - the tracee's address range cannot be accessed (e.g. invalid address) or does not have valid tags (not mapped with the ``PROT_MTE`` flag) and no tags copied. ``iov_len`` not updated.”h]”(j”)�”}”(hŒ``-EIO``”h]”hŒ-EIO”…”�”}”(hj÷ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjó ubhŒ{ - the tracee’s address range cannot be accessed (e.g. invalid address) or does not have valid tags (not mapped with the ”…”�”}”(hjó h²hh³Nh´Nubj”)�”}”(hŒ ``PROT_MTE``”h]”hŒPROT_MTE”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjó ubhŒ flag) and no tags copied. ”…”�”}”(hjó h²hh³Nh´Nubj”)�”}”(hŒ ``iov_len``”h]”hŒiov_len”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjó ubhŒ not updated.”…”�”}”(hjó h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KÒhjï ubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hj‹ h²hh³hÊh´Nubj™)�”}”(hŒŒ``-EFAULT`` - fault on accessing the tracer's memory (``struct iovec`` or ``iov_base`` buffer) and no tags copied. ``iov_len`` not updated. ”h]”j)�”}”(hŒ‹``-EFAULT`` - fault on accessing the tracer's memory (``struct iovec`` or ``iov_base`` buffer) and no tags copied. ``iov_len`` not updated.”h]”(j”)�”}”(hŒ ``-EFAULT``”h]”hŒ-EFAULT”…”�”}”(hjA h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj= ubhŒ- - fault on accessing the tracer’s memory (”…”�”}”(hj= h²hh³Nh´Nubj”)�”}”(hŒ``struct iovec``”h]”hŒ struct iovec”…”�”}”(hjS h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj= ubhŒ or ”…”�”}”(hj= h²hh³Nh´Nubj”)�”}”(hŒ ``iov_base``”h]”hŒiov_base”…”�”}”(hje h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj= ubhŒ buffer) and no tags copied. ”…”�”}”(hj= h²hh³Nh´Nubj”)�”}”(hŒ ``iov_len``”h]”hŒiov_len”…”�”}”(hjw h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj= ubhŒ not updated.”…”�”}”(hj= h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KÕhj9 ubah}”(h]”h ]”h"]”h$]”h&]”uh1j˜hj‹ h²hh³hÊh´Nubeh}”(h]”h ]”h"]”h$]”h&]”jÊjËuh1j“h³hÊh´KÍhj´ h²hubj)�”}”(hŒ‹**Note**: There are no transient errors for the requests above, so user programs should not retry in case of a non-zero system call return.”h]”(jU)�”}”(hŒ**Note**”h]”hŒNote”…”�”}”(hjŸ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jThj› ubhŒƒ: There are no transient errors for the requests above, so user programs should not retry in case of a non-zero system call return.”…”�”}”(hj› h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KØhj´ h²hubj)�”}”(hXg``PTRACE_GETREGSET`` and ``PTRACE_SETREGSET`` with ``addr == ``NT_ARM_TAGGED_ADDR_CTRL`` allow ``ptrace()`` access to the tagged address ABI control and MTE configuration of a process as per the ``prctl()`` options described in Documentation/arch/arm64/tagged-address-abi.rst and above. The corresponding ``regset`` is 1 element of 8 bytes (``sizeof(long)``).”h]”(j”)�”}”(hŒ``PTRACE_GETREGSET``”h]”hŒPTRACE_GETREGSET”…”�”}”(hj» h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj· ubhŒ and ”…”�”}”(hj· h²hh³Nh´Nubj”)�”}”(hŒ``PTRACE_SETREGSET``”h]”hŒPTRACE_SETREGSET”…”�”}”(hjÍ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj· ubhŒ with ”…”�”}”(hj· h²hh³Nh´Nubj”)�”}”(hŒ%``addr == ``NT_ARM_TAGGED_ADDR_CTRL``”h]”hŒ!addr == ``NT_ARM_TAGGED_ADDR_CTRL”…”�”}”(hjß h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj· ubhŒ allow ”…”�”}”(hj· h²hh³Nh´Nubj”)�”}”(hŒ ``ptrace()``”h]”hŒptrace()”…”�”}”(hjñ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj· ubhŒX access to the tagged address ABI control and MTE configuration of a process as per the ”…”�”}”(hj· h²hh³Nh´Nubj”)�”}”(hŒ ``prctl()``”h]”hŒprctl()”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj· ubhŒc options described in Documentation/arch/arm64/tagged-address-abi.rst and above. The corresponding ”…”�”}”(hj· h²hh³Nh´Nubj”)�”}”(hŒ ``regset``”h]”hŒregset”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj· ubhŒ is 1 element of 8 bytes (”…”�”}”(hj· h²hh³Nh´Nubj”)�”}”(hŒ``sizeof(long)``”h]”hŒ sizeof(long)”…”�”}”(hj'h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj· ubhŒ).”…”�”}”(hj· h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KÛhj´ h²hubeh}”(h]”Œthe-ptrace-interface”ah ]”h"]”Œthe ptrace() interface”ah$]”h&]”uh1hµhjzh²hh³hÊh´K·ubh¶)�”}”(hhh]”(h»)�”}”(hŒCore dump support”h]”hŒCore dump support”…”�”}”(hjJh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjGh²hh³hÊh´Kãubj)�”}”(hŒ½The allocation tags for user memory mapped with ``PROT_MTE`` are dumped in the core file as additional ``PT_AARCH64_MEMTAG_MTE`` segments. The program header for such segment is defined as:”h]”(hŒ0The allocation tags for user memory mapped with ”…”�”}”(hjXh²hh³Nh´Nubj”)�”}”(hŒ ``PROT_MTE``”h]”hŒPROT_MTE”…”�”}”(hj`h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjXubhŒ+ are dumped in the core file as additional ”…”�”}”(hjXh²hh³Nh´Nubj”)�”}”(hŒ``PT_AARCH64_MEMTAG_MTE``”h]”hŒPT_AARCH64_MEMTAG_MTE”…”�”}”(hjrh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjXubhŒ= segments. The program header for such segment is defined as:”…”�”}”(hjXh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KåhjGh²hubhŒ field_list”“”)�”}”(hhh]”(hŒfield”“”)�”}”(hhh]”(hŒ field_name”“”)�”}”(hŒ ``p_type``”h]”j”)�”}”(hj˜h]”hŒp_type”…”�”}”(hjšh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj–ubah}”(h]”h ]”h"]”h$]”h&]”uh1j”hj‘h³hÊh´KubhŒ field_body”“”)�”}”(hŒ``PT_AARCH64_MEMTAG_MTE``”h]”j)�”}”(hj±h]”j”)�”}”(hj±h]”hŒPT_AARCH64_MEMTAG_MTE”…”�”}”(hj¶h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj³ubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Kéhj¯ubah}”(h]”h ]”h"]”h$]”h&]”uh1j­hj‘ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³hÊh´KéhjŒh²hubj�)�”}”(hhh]”(j•)�”}”(hŒ ``p_flags``”h]”j”)�”}”(hjÚh]”hŒp_flags”…”�”}”(hjÜh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjØubah}”(h]”h ]”h"]”h$]”h&]”uh1j”hjÕh³hÊh´Kubj®)�”}”(hŒ0”h]”j)�”}”(hjñh]”hŒ0”…”�”}”(hjóh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Kêhjïubah}”(h]”h ]”h"]”h$]”h&]”uh1j­hjÕubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³hÊh´KêhjŒh²hubj�)�”}”(hhh]”(j•)�”}”(hŒ ``p_offset``”h]”j”)�”}”(hjh]”hŒp_offset”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjubah}”(h]”h ]”h"]”h$]”h&]”uh1j”hj h³hÊh´Kubj®)�”}”(hŒsegment file offset”h]”j)�”}”(hj(h]”hŒsegment file offset”…”�”}”(hj*h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Këhj&ubah}”(h]”h ]”h"]”h$]”h&]”uh1j­hj ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³hÊh´KëhjŒh²hubj�)�”}”(hhh]”(j•)�”}”(hŒ ``p_vaddr``”h]”j”)�”}”(hjHh]”hŒp_vaddr”…”�”}”(hjJh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjFubah}”(h]”h ]”h"]”h$]”h&]”uh1j”hjCh³hÊh´Kubj®)�”}”(hŒFsegment virtual address, same as the corresponding ``PT_LOAD`` segment”h]”j)�”}”(hŒFsegment virtual address, same as the corresponding ``PT_LOAD`` segment”h]”(hŒ3segment virtual address, same as the corresponding ”…”�”}”(hjah²hh³Nh´Nubj”)�”}”(hŒ ``PT_LOAD``”h]”hŒPT_LOAD”…”�”}”(hjih²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjaubhŒ segment”…”�”}”(hjah²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Kìhj]ubah}”(h]”h ]”h"]”h$]”h&]”uh1j­hjCubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³hÊh´KìhjŒh²hubj�)�”}”(hhh]”(j•)�”}”(hŒ ``p_paddr``”h]”j”)�”}”(hj’h]”hŒp_paddr”…”�”}”(hj”h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj�ubah}”(h]”h ]”h"]”h$]”h&]”uh1j”hj�h³hÊh´Kubj®)�”}”(hjñh]”j)�”}”(hjñh]”hŒ0”…”�”}”(hjªh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Kîhj§ubah}”(h]”h ]”h"]”h$]”h&]”uh1j­hj�ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³hÊh´KîhjŒh²hubj�)�”}”(hhh]”(j•)�”}”(hŒ ``p_filesz``”h]”j”)�”}”(hjÈh]”hŒp_filesz”…”�”}”(hjÊh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjÆubah}”(h]”h ]”h"]”h$]”h&]”uh1j”hjÃh³hÊh´Kubj®)�”}”(hŒ_segment size in file, calculated as ``p_mem_sz / 32`` (two 4-bit tags cover 32 bytes of memory)”h]”j)�”}”(hŒ_segment size in file, calculated as ``p_mem_sz / 32`` (two 4-bit tags cover 32 bytes of memory)”h]”(hŒ$segment size in file, calculated as ”…”�”}”(hjáh²hh³Nh´Nubj”)�”}”(hŒ``p_mem_sz / 32``”h]”hŒ p_mem_sz / 32”…”�”}”(hjéh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjáubhŒ* (two 4-bit tags cover 32 bytes of memory)”…”�”}”(hjáh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KïhjÝubah}”(h]”h ]”h"]”h$]”h&]”uh1j­hjÃubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³hÊh´KïhjŒh²hubj�)�”}”(hhh]”(j•)�”}”(hŒ ``p_memsz``”h]”j”)�”}”(hjh]”hŒp_memsz”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjubah}”(h]”h ]”h"]”h$]”h&]”uh1j”hj h³hÊh´Kubj®)�”}”(hŒEsegment size in memory, same as the corresponding ``PT_LOAD`` segment”h]”j)�”}”(hŒEsegment size in memory, same as the corresponding ``PT_LOAD`` segment”h]”(hŒ2segment size in memory, same as the corresponding ”…”�”}”(hj+h²hh³Nh´Nubj”)�”}”(hŒ ``PT_LOAD``”h]”hŒPT_LOAD”…”�”}”(hj3h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj+ubhŒ segment”…”�”}”(hj+h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Kñhj'ubah}”(h]”h ]”h"]”h$]”h&]”uh1j­hj ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³hÊh´KñhjŒh²hubj�)�”}”(hhh]”(j•)�”}”(hŒ ``p_align``”h]”j”)�”}”(hj\h]”hŒp_align”…”�”}”(hj^h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hjZubah}”(h]”h ]”h"]”h$]”h&]”uh1j”hjWh³hÊh´Kubj®)�”}”(hŒ0 ”h]”j)�”}”(hjñh]”hŒ0”…”�”}”(hjuh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Kóhjqubah}”(h]”h ]”h"]”h$]”h&]”uh1j­hjWubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³hÊh´KóhjŒh²hubeh}”(h]”h ]”h"]”h$]”h&]”uh1jŠhjGh²hh³hÊh´Kéubj)�”}”(hŒ¢The tags are stored in the core file at ``p_offset`` as two 4-bit tags in a byte. With the tag granule of 16 bytes, a 4K page requires 128 bytes in the core file.”h]”(hŒ(The tags are stored in the core file at ”…”�”}”(hj”h²hh³Nh´Nubj”)�”}”(hŒ ``p_offset``”h]”hŒp_offset”…”�”}”(hjœh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j“hj”ubhŒn as two 4-bit tags in a byte. With the tag granule of 16 bytes, a 4K page requires 128 bytes in the core file.”…”�”}”(hj”h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KõhjGh²hubeh}”(h]”Œcore-dump-support”ah ]”h"]”Œcore dump support”ah$]”h&]”uh1hµhjzh²hh³hÊh´Kãubeh}”(h]”Œuserspace-support”ah ]”h"]”Œuserspace support”ah$]”h&]”uh1hµhh·h²hh³hÊh´Kubh¶)�”}”(hhh]”(h»)�”}”(hŒExample of correct usage”h]”hŒExample of correct usage”…”�”}”(hjÇh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjÄh²hh³hÊh´Kúubj)�”}”(hŒ*MTE Example code*”h]”j£)�”}”(hj×h]”hŒMTE Example code”…”�”}”(hjÙh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¢hjÕubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KühjÄh²hubhŒ literal_block”“”)�”}”(hX› /* * To be compiled with -march=armv8.5-a+memtag */ #include #include #include #include #include #include #include #include /* * From arch/arm64/include/uapi/asm/hwcap.h */ #define HWCAP2_MTE (1 << 18) /* * From arch/arm64/include/uapi/asm/mman.h */ #define PROT_MTE 0x20 /* * From include/uapi/linux/prctl.h */ #define PR_SET_TAGGED_ADDR_CTRL 55 #define PR_GET_TAGGED_ADDR_CTRL 56 # define PR_TAGGED_ADDR_ENABLE (1UL << 0) # define PR_MTE_TCF_SHIFT 1 # define PR_MTE_TCF_NONE (0UL << PR_MTE_TCF_SHIFT) # define PR_MTE_TCF_SYNC (1UL << PR_MTE_TCF_SHIFT) # define PR_MTE_TCF_ASYNC (2UL << PR_MTE_TCF_SHIFT) # define PR_MTE_TCF_MASK (3UL << PR_MTE_TCF_SHIFT) # define PR_MTE_TAG_SHIFT 3 # define PR_MTE_TAG_MASK (0xffffUL << PR_MTE_TAG_SHIFT) /* * Insert a random logical tag into the given pointer. */ #define insert_random_tag(ptr) ({ \ uint64_t __val; \ asm("irg %0, %1" : "=r" (__val) : "r" (ptr)); \ __val; \ }) /* * Set the allocation tag on the destination address. */ #define set_tag(tagged_addr) do { \ asm volatile("stg %0, [%0]" : : "r" (tagged_addr) : "memory"); \ } while (0) int main() { unsigned char *a; unsigned long page_sz = sysconf(_SC_PAGESIZE); unsigned long hwcap2 = getauxval(AT_HWCAP2); /* check if MTE is present */ if (!(hwcap2 & HWCAP2_MTE)) return EXIT_FAILURE; /* * Enable the tagged address ABI, synchronous or asynchronous MTE * tag check faults (based on per-CPU preference) and allow all * non-zero tags in the randomly generated set. */ if (prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC | (0xfffe << PR_MTE_TAG_SHIFT), 0, 0, 0)) { perror("prctl() failed"); return EXIT_FAILURE; } a = mmap(0, page_sz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (a == MAP_FAILED) { perror("mmap() failed"); return EXIT_FAILURE; } /* * Enable MTE on the above anonymous mmap. The flag could be passed * directly to mmap() and skip this step. */ if (mprotect(a, page_sz, PROT_READ | PROT_WRITE | PROT_MTE)) { perror("mprotect() failed"); return EXIT_FAILURE; } /* access with the default tag (0) */ a[0] = 1; a[1] = 2; printf("a[0] = %hhu a[1] = %hhu\n", a[0], a[1]); /* set the logical and allocation tags */ a = (unsigned char *)insert_random_tag(a); set_tag(a); printf("%p\n", a); /* non-zero tag access */ a[0] = 3; printf("a[0] = %hhu a[1] = %hhu\n", a[0], a[1]); /* * If MTE is enabled correctly the next instruction will generate an * exception. */ printf("Expecting SIGSEGV...\n"); a[16] = 0xdd; /* this should not be printed in the PR_MTE_TCF_SYNC mode */ printf("...haven't got one\n"); return EXIT_FAILURE; }”h]”hX› /* * To be compiled with -march=armv8.5-a+memtag */ #include #include #include #include #include #include #include #include /* * From arch/arm64/include/uapi/asm/hwcap.h */ #define HWCAP2_MTE (1 << 18) /* * From arch/arm64/include/uapi/asm/mman.h */ #define PROT_MTE 0x20 /* * From include/uapi/linux/prctl.h */ #define PR_SET_TAGGED_ADDR_CTRL 55 #define PR_GET_TAGGED_ADDR_CTRL 56 # define PR_TAGGED_ADDR_ENABLE (1UL << 0) # define PR_MTE_TCF_SHIFT 1 # define PR_MTE_TCF_NONE (0UL << PR_MTE_TCF_SHIFT) # define PR_MTE_TCF_SYNC (1UL << PR_MTE_TCF_SHIFT) # define PR_MTE_TCF_ASYNC (2UL << PR_MTE_TCF_SHIFT) # define PR_MTE_TCF_MASK (3UL << PR_MTE_TCF_SHIFT) # define PR_MTE_TAG_SHIFT 3 # define PR_MTE_TAG_MASK (0xffffUL << PR_MTE_TAG_SHIFT) /* * Insert a random logical tag into the given pointer. */ #define insert_random_tag(ptr) ({ \ uint64_t __val; \ asm("irg %0, %1" : "=r" (__val) : "r" (ptr)); \ __val; \ }) /* * Set the allocation tag on the destination address. */ #define set_tag(tagged_addr) do { \ asm volatile("stg %0, [%0]" : : "r" (tagged_addr) : "memory"); \ } while (0) int main() { unsigned char *a; unsigned long page_sz = sysconf(_SC_PAGESIZE); unsigned long hwcap2 = getauxval(AT_HWCAP2); /* check if MTE is present */ if (!(hwcap2 & HWCAP2_MTE)) return EXIT_FAILURE; /* * Enable the tagged address ABI, synchronous or asynchronous MTE * tag check faults (based on per-CPU preference) and allow all * non-zero tags in the randomly generated set. */ if (prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC | (0xfffe << PR_MTE_TAG_SHIFT), 0, 0, 0)) { perror("prctl() failed"); return EXIT_FAILURE; } a = mmap(0, page_sz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (a == MAP_FAILED) { perror("mmap() failed"); return EXIT_FAILURE; } /* * Enable MTE on the above anonymous mmap. The flag could be passed * directly to mmap() and skip this step. */ if (mprotect(a, page_sz, PROT_READ | PROT_WRITE | PROT_MTE)) { perror("mprotect() failed"); return EXIT_FAILURE; } /* access with the default tag (0) */ a[0] = 1; a[1] = 2; printf("a[0] = %hhu a[1] = %hhu\n", a[0], a[1]); /* set the logical and allocation tags */ a = (unsigned char *)insert_random_tag(a); set_tag(a); printf("%p\n", a); /* non-zero tag access */ a[0] = 3; printf("a[0] = %hhu a[1] = %hhu\n", a[0], a[1]); /* * If MTE is enabled correctly the next instruction will generate an * exception. */ printf("Expecting SIGSEGV...\n"); a[16] = 0xdd; /* this should not be printed in the PR_MTE_TCF_SYNC mode */ printf("...haven't got one\n"); return EXIT_FAILURE; }”…”�”}”hjîsbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”Œforce”‰Œlanguage”Œc”Œhighlight_args”}”uh1jìh³hÊh´KþhjÄh²hubeh}”(h]”Œexample-of-correct-usage”ah ]”h"]”Œexample of correct usage”ah$]”h&]”uh1hµhh·h²hh³hÊh´Kúubeh}”(h]”Œ-memory-tagging-extension-mte-in-aarch64-linux”ah ]”h"]”Œ/memory tagging extension (mte) in aarch64 linux”ah$]”h&]”uh1hµhhh²hh³hÊh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÊuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)�”}”(hºNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”j6Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÊŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(jj jwjtjÁj¾j_j\jEjBjNjKj j| j± j® jDjAj¹j¶jjuŒ nametypes”}”(j‰jw‰jÁ‰j_‰jE‰jN‰j ‰j± ‰jD‰j¹‰j‰uh}”(j h·jtjSj¾jzj\j¿jBjbjKjHj| jQj® j‚ jAj´ j¶jGjjÄuŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.