sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget /translations/zh_CN/arch/x86/sgxmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget /translations/zh_TW/arch/x86/sgxmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget /translations/it_IT/arch/x86/sgxmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget /translations/ja_JP/arch/x86/sgxmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget /translations/ko_KR/arch/x86/sgxmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hPortuguese (Brazilian)}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget /translations/pt_BR/arch/x86/sgxmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget /translations/sp_SP/arch/x86/sgxmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhh:/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx.rsthKubhsection)}(hhh](htitle)}(hSoftware Guard eXtensions (SGX)h]hSoftware Guard eXtensions (SGX)}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hOverviewh]hOverview}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh paragraph)}(hSoftware Guard eXtensions (SGX) hardware enables for user space applications to set aside private memory regions of code and data:h]hSoftware Guard eXtensions (SGX) hardware enables for user space applications to set aside private memory regions of code and data:}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hhhhubh bullet_list)}(hhh](h list_item)}(hPPrivileged (ring-0) ENCLS functions orchestrate the construction of the regions.h]h)}(hPPrivileged (ring-0) ENCLS functions orchestrate the construction of the regions.h]hPPrivileged (ring-0) ENCLS functions orchestrate the construction of the regions.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hdUnprivileged (ring-3) ENCLU functions allow an application to enter and execute inside the regions. h]h)}(hcUnprivileged (ring-3) ENCLU functions allow an application to enter and execute inside the regions.h]hcUnprivileged (ring-3) ENCLU functions allow an application to enter and execute inside the regions.}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]h ]h"]h$]h&]bullet*uh1hhhhK hhhhubh)}(hXThese memory regions are called enclaves. An enclave can be only entered at a fixed set of entry points. Each entry point can hold a single hardware thread at a time. While the enclave is loaded from a regular binary file by using ENCLS functions, only the threads inside the enclave can access its memory. The region is denied from outside access by the CPU, and encrypted before it leaves from LLC.h]hXThese memory regions are called enclaves. An enclave can be only entered at a fixed set of entry points. Each entry point can hold a single hardware thread at a time. While the enclave is loaded from a regular binary file by using ENCLS functions, only the threads inside the enclave can access its memory. The region is denied from outside access by the CPU, and encrypted before it leaves from LLC.}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(h The support can be determined byh]h The support can be determined by}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh block_quote)}(h``grep sgx /proc/cpuinfo`` h]h)}(h``grep sgx /proc/cpuinfo``h]hliteral)}(hjah]hgrep sgx /proc/cpuinfo}(hjehhhNhNubah}(h]h ]h"]h$]h&]uh1jchj_ubah}(h]h ]h"]h$]h&]uh1hhhhKhj[ubah}(h]h ]h"]h$]h&]uh1jYhhhKhhhhubh)}(hXSGX must both be supported in the processor and enabled by the BIOS. If SGX appears to be unsupported on a system which has hardware support, ensure support is enabled in the BIOS. If a BIOS presents a choice between "Enabled" and "Software Enabled" modes for SGX, choose "Enabled".h]hX(SGX must both be supported in the processor and enabled by the BIOS. If SGX appears to be unsupported on a system which has hardware support, ensure support is enabled in the BIOS. If a BIOS presents a choice between “Enabled” and “Software Enabled” modes for SGX, choose “Enabled”.}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubeh}(h]overviewah ]h"]overviewah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hEnclave Page Cacheh]hEnclave Page Cache}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK#ubh)}(hX=SGX utilizes an *Enclave Page Cache (EPC)* to store pages that are associated with an enclave. It is contained in a BIOS-reserved region of physical memory. Unlike pages used for regular memory, pages can only be accessed from outside of the enclave during enclave construction with special, limited SGX instructions.h](hSGX utilizes an }(hjhhhNhNubhemphasis)}(h*Enclave Page Cache (EPC)*h]hEnclave Page Cache (EPC)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhX to store pages that are associated with an enclave. It is contained in a BIOS-reserved region of physical memory. Unlike pages used for regular memory, pages can only be accessed from outside of the enclave during enclave construction with special, limited SGX instructions.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK%hjhhubh)}(hOnly a CPU executing inside an enclave can directly access enclave memory. However, a CPU executing inside an enclave may access normal memory outside the enclave.h]hOnly a CPU executing inside an enclave can directly access enclave memory. However, a CPU executing inside an enclave may access normal memory outside the enclave.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK*hjhhubh)}(hIThe kernel manages enclave memory similar to how it treats device memory.h]hIThe kernel manages enclave memory similar to how it treats device memory.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK.hjhhubh)}(hhh](h)}(hEnclave Page Typesh]hEnclave Page Types}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK1ubhdefinition_list)}(hhh](hdefinition_list_item)}(h**SGX Enclave Control Structure (SECS)** Enclave's address range, attributes and other global data are defined by this structure. h](hterm)}(h(**SGX Enclave Control Structure (SECS)**h]hstrong)}(hjh]h$SGX Enclave Control Structure (SECS)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jhhhK5hjubh definition)}(hhh]h)}(hXEnclave's address range, attributes and other global data are defined by this structure.h]hZEnclave’s address range, attributes and other global data are defined by this structure.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK4hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhK5hjubj)}(hM**Regular (REG)** Regular EPC pages contain the code and data of an enclave. h](j)}(h**Regular (REG)**h]j)}(hj?h]h Regular (REG)}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj=ubah}(h]h ]h"]h$]h&]uh1jhhhK8hj9ubj)}(hhh]h)}(h:Regular EPC pages contain the code and data of an enclave.h]h:Regular EPC pages contain the code and data of an enclave.}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK8hjTubah}(h]h ]h"]h$]h&]uh1jhj9ubeh}(h]h ]h"]h$]h&]uh1jhhhK8hjhhubj)}(h**Thread Control Structure (TCS)** Thread Control Structure pages define the entry points to an enclave and track the execution state of an enclave thread. h](j)}(h"**Thread Control Structure (TCS)**h]j)}(hjwh]hThread Control Structure (TCS)}(hjyhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjuubah}(h]h ]h"]h$]h&]uh1jhhhK)}jA]jD)}j7jsbc.sgx_ioc_enclave_add_pagesasbuh1hhjubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubjX)}(hj<h]h*}(hjhhhNhNubah}(h]h ]jcah"]h$]h&]uh1jWhjubj)}(henclh]hencl}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]noemphhhuh1jhjubj)}(hvoid __user *argh](j)}(hvoidh]hvoid}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubj)}(h h]h }(hj&hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubh__user}(hjhhhNhNubj)}(h h]h }(hj8hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubjX)}(hj<h]h*}(hjFhhhNhNubah}(h]h ]jcah"]h$]h&]uh1jWhjubj)}(hargh]harg}(hjShhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]noemphhhuh1jhjubeh}(h]h ]h"]h$]h&]hhuh1jhjehhhjwhMyubeh}(h]h ]h"]h$]h&]hhjuh1jjjhjahhhjwhMyubah}(h]j\ah ](jjeh"]h$]h&]jj)jhuh1jhjwhMyhj^hhubj)}(hhh]h)}(h-The handler for ``SGX_IOC_ENCLAVE_ADD_PAGES``h](hThe handler for }(hj}hhhNhNubjd)}(h``SGX_IOC_ENCLAVE_ADD_PAGES``h]hSGX_IOC_ENCLAVE_ADD_PAGES}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchj}ubeh}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMyhjzhhubah}(h]h ]h"]h$]h&]uh1jhj^hhhjwhMyubeh}(h]h ](j5functioneh"]h$]h&]jj5jjjjjjjuh1jhhhj]hNhNubj )}(hX**Parameters** ``struct sgx_encl *encl`` an enclave pointer ``void __user *arg`` a user pointer to a struct sgx_enclave_add_pages instance **Description** Add one or more pages to an uninitialized enclave, and optionally extend the measurement with the contents of the page. The SECINFO and measurement mask are applied to all pages. A SECINFO for a TCS is required to always contain zero permissions because CPU silently zeros them. Allowing anything else would cause a mismatch in the measurement. mmap()'s protection bits are capped by the page permissions. For each page address, the maximum protection bits are computed with the following heuristics: 1. A regular page: PROT_R, PROT_W and PROT_X match the SECINFO permissions. 2. A TCS page: PROT_R | PROT_W. mmap() is not allowed to surpass the minimum of the maximum protection bits within the given address range. The function deinitializes kernel data structures for enclave and returns -EIO in any of the following conditions: - Enclave Page Cache (EPC), the physical memory holding enclaves, has been invalidated. This will cause EADD and EEXTEND to fail. - If the source address is corrupted somehow when executing EADD. **Return** - 0: Success. - -EACCES: The source page is located in a noexec partition. - -ENOMEM: Out of EPC pages. - -EINTR: The call was interrupted before data was processed. - -EIO: Either EADD or EEXTEND failed because invalid source address or power cycle. - -errno: POSIX error.h](h)}(h**Parameters**h]j)}(hjh]h Parameters}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chM}hjubj)}(hhh](j)}(h-``struct sgx_encl *encl`` an enclave pointer h](j)}(h``struct sgx_encl *encl``h]jd)}(hjh]hstruct sgx_encl *encl}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubah}(h]h ]h"]h$]h&]uh1jh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMzhjubj)}(hhh]h)}(han enclave pointerh]han enclave pointer}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMzhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhMzhjubj)}(hO``void __user *arg`` a user pointer to a struct sgx_enclave_add_pages instance h](j)}(h``void __user *arg``h]jd)}(hjh]hvoid __user *arg}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubah}(h]h ]h"]h$]h&]uh1jh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chM{hjubj)}(hhh]h)}(h9a user pointer to a struct sgx_enclave_add_pages instanceh]h9a user pointer to a struct sgx_enclave_add_pages instance}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM{hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhM{hjubeh}(h]h ]h"]h$]h&]uh1jhjubh)}(h**Description**h]j)}(hj@h]h Description}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj>ubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chM}hjubh)}(hAdd one or more pages to an uninitialized enclave, and optionally extend the measurement with the contents of the page. The SECINFO and measurement mask are applied to all pages.h]hAdd one or more pages to an uninitialized enclave, and optionally extend the measurement with the contents of the page. The SECINFO and measurement mask are applied to all pages.}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chM|hjubh)}(hA SECINFO for a TCS is required to always contain zero permissions because CPU silently zeros them. Allowing anything else would cause a mismatch in the measurement.h]hA SECINFO for a TCS is required to always contain zero permissions because CPU silently zeros them. Allowing anything else would cause a mismatch in the measurement.}(hjehhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjubh)}(hmmap()'s protection bits are capped by the page permissions. For each page address, the maximum protection bits are computed with the following heuristics:h]hmmap()’s protection bits are capped by the page permissions. For each page address, the maximum protection bits are computed with the following heuristics:}(hjthhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjubhenumerated_list)}(hhh](j)}(hHA regular page: PROT_R, PROT_W and PROT_X match the SECINFO permissions.h]h)}(hjh]hHA regular page: PROT_R, PROT_W and PROT_X match the SECINFO permissions.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hA TCS page: PROT_R | PROT_W. h]h)}(hA TCS page: PROT_R | PROT_W.h]hA TCS page: PROT_R | PROT_W.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]enumtypearabicprefixhsuffix.uh1jhjubh)}(hkmmap() is not allowed to surpass the minimum of the maximum protection bits within the given address range.h]hkmmap() is not allowed to surpass the minimum of the maximum protection bits within the given address range.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjubh)}(hrThe function deinitializes kernel data structures for enclave and returns -EIO in any of the following conditions:h]hrThe function deinitializes kernel data structures for enclave and returns -EIO in any of the following conditions:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjubh)}(hhh](j)}(hEnclave Page Cache (EPC), the physical memory holding enclaves, has been invalidated. This will cause EADD and EEXTEND to fail.h]h)}(hEnclave Page Cache (EPC), the physical memory holding enclaves, has been invalidated. This will cause EADD and EEXTEND to fail.h]hEnclave Page Cache (EPC), the physical memory holding enclaves, has been invalidated. This will cause EADD and EEXTEND to fail.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(h@If the source address is corrupted somehow when executing EADD. h]h)}(h?If the source address is corrupted somehow when executing EADD.h]h?If the source address is corrupted somehow when executing EADD.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]j;jHuh1hhjhMhjubh)}(h **Return**h]j)}(hj h]hReturn}(hj! hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjubh)}(hhh](j)}(h0: Success.h]h)}(hj: h]h0: Success.}(hj< hhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMhj8 ubah}(h]h ]h"]h$]h&]uh1jhj5 ubj)}(h<-EACCES: The source page is located in a noexec partition.h]h)}(hjR h]h<-EACCES: The source page is located in a noexec partition.}(hjT hhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjP ubah}(h]h ]h"]h$]h&]uh1jhj5 ubj)}(h-ENOMEM: Out of EPC pages.h]h)}(hjj h]h-ENOMEM: Out of EPC pages.}(hjl hhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjh ubah}(h]h ]h"]h$]h&]uh1jhj5 ubj)}(h>-EINTR: The call was interrupted before data was processed.h]h)}(hj h]h>-EINTR: The call was interrupted before data was processed.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMhj ubah}(h]h ]h"]h$]h&]uh1jhj5 ubj)}(hb-EIO: Either EADD or EEXTEND failed because invalid source address or power cycle.h]j)}(hhh]j)}(hW-EIO: Either EADD or EEXTEND failed because invalid source address or power cycle.h](j)}(hG-EIO: Either EADD or EEXTEND failed because invalid source addressh]hG-EIO: Either EADD or EEXTEND failed because invalid source address}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMhj ubj)}(hhh]h)}(hor power cycle.h]hor power cycle.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMhj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj hMhj ubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1jhj5 ubj)}(h-errno: POSIX error.h]h)}(hj h]h-errno: POSIX error.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMhj ubah}(h]h ]h"]h$]h&]uh1jhj5 ubeh}(h]h ]h"]h$]h&]j;jHuh1hhjI hMhjubeh}(h]h ] kernelindentah"]h$]h&]uh1jhj]hhhNhNubj)}(hhh]h}(h]h ]h"]h$]h&]entries](j!sgx_ioc_enclave_init (C function)c.sgx_ioc_enclave_inithNtauh1jhj]hhhNhNubj)}(hhh](j)}(hClong sgx_ioc_enclave_init (struct sgx_encl *encl, void __user *arg)h]j)}(hBlong sgx_ioc_enclave_init(struct sgx_encl *encl, void __user *arg)h](j)}(hlongh]hlong}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj hhh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chM/ubj)}(h h]h }(hj) hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj hhhj( hM/ubj)}(hsgx_ioc_enclave_inith]j)}(hsgx_ioc_enclave_inith]hsgx_ioc_enclave_init}(hj; hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj7 ubah}(h]h ](jjeh"]h$]h&]hhuh1jhj hhhj( hM/ubj)}(h)(struct sgx_encl *encl, void __user *arg)h](j)}(hstruct sgx_encl *enclh](j)}(hjh]hstruct}(hjW hhhNhNubah}(h]h ]j ah"]h$]h&]uh1jhjS ubj)}(h h]h }(hjd hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjS ubh)}(hhh]j)}(hsgx_enclh]hsgx_encl}(hju hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjr ubah}(h]h ]h"]h$]h&] refdomainj5reftypej7 reftargetjw modnameN classnameNj;j>)}jA]jD)}j7j= sbc.sgx_ioc_enclave_initasbuh1hhjS ubj)}(h h]h }(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjS ubjX)}(hj<h]h*}(hj hhhNhNubah}(h]h ]jcah"]h$]h&]uh1jWhjS ubj)}(henclh]hencl}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjS ubeh}(h]h ]h"]h$]h&]noemphhhuh1jhjO ubj)}(hvoid __user *argh](j)}(hvoidh]hvoid}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj ubj)}(h h]h }(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj ubh__user}(hj hhhNhNubj)}(h h]h }(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj ubjX)}(hj<h]h*}(hj hhhNhNubah}(h]h ]jcah"]h$]h&]uh1jWhj ubj)}(hargh]harg}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]noemphhhuh1jhjO ubeh}(h]h ]h"]h$]h&]hhuh1jhj hhhj( hM/ubeh}(h]h ]h"]h$]h&]hhjuh1jjjhj hhhj( hM/ubah}(h]j ah ](jjeh"]h$]h&]jj)jhuh1jhj( hM/hj hhubj)}(hhh]h)}(h$handler for ``SGX_IOC_ENCLAVE_INIT``h](h handler for }(hj. hhhNhNubjd)}(h``SGX_IOC_ENCLAVE_INIT``h]hSGX_IOC_ENCLAVE_INIT}(hj6 hhhNhNubah}(h]h ]h"]h$]h&]uh1jchj. ubeh}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chM/hj+ hhubah}(h]h ]h"]h$]h&]uh1jhj hhhj( hM/ubeh}(h]h ](j5functioneh"]h$]h&]jj5jjT jjT jjjuh1jhhhj]hNhNubj )}(hX **Parameters** ``struct sgx_encl *encl`` an enclave pointer ``void __user *arg`` userspace pointer to a struct sgx_enclave_init instance **Description** Flush any outstanding enqueued EADD operations and perform EINIT. The Launch Enclave Public Key Hash MSRs are rewritten as necessary to match the enclave's MRSIGNER, which is calculated from the provided sigstruct. **Return** - 0: Success. - -EPERM: Invalid SIGSTRUCT. - -EIO: EINIT failed because of a power cycle. - -errno: POSIX error.h](h)}(h**Parameters**h]j)}(hj^ h]h Parameters}(hj` hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj\ ubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chM3hjX ubj)}(hhh](j)}(h-``struct sgx_encl *encl`` an enclave pointer h](j)}(h``struct sgx_encl *encl``h]jd)}(hj} h]hstruct sgx_encl *encl}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jchj{ ubah}(h]h ]h"]h$]h&]uh1jh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chM0hjw ubj)}(hhh]h)}(han enclave pointerh]han enclave pointer}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hM0hj ubah}(h]h ]h"]h$]h&]uh1jhjw ubeh}(h]h ]h"]h$]h&]uh1jhj hM0hjt ubj)}(hM``void __user *arg`` userspace pointer to a struct sgx_enclave_init instance h](j)}(h``void __user *arg``h]jd)}(hj h]hvoid __user *arg}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jchj ubah}(h]h ]h"]h$]h&]uh1jh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chM1hj ubj)}(hhh]h)}(h7userspace pointer to a struct sgx_enclave_init instanceh]h7userspace pointer to a struct sgx_enclave_init instance}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hM1hj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj hM1hjt ubeh}(h]h ]h"]h$]h&]uh1jhjX ubh)}(h**Description**h]j)}(hj h]h Description}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chM3hjX ubh)}(hFlush any outstanding enqueued EADD operations and perform EINIT. The Launch Enclave Public Key Hash MSRs are rewritten as necessary to match the enclave's MRSIGNER, which is calculated from the provided sigstruct.h]hFlush any outstanding enqueued EADD operations and perform EINIT. The Launch Enclave Public Key Hash MSRs are rewritten as necessary to match the enclave’s MRSIGNER, which is calculated from the provided sigstruct.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chM2hjX ubh)}(h **Return**h]j)}(hj h]hReturn}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chM6hjX ubh)}(hhh](j)}(h0: Success.h]h)}(hj3 h]h0: Success.}(hj5 hhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chM7hj1 ubah}(h]h ]h"]h$]h&]uh1jhj. ubj)}(h-EPERM: Invalid SIGSTRUCT.h]h)}(hjK h]h-EPERM: Invalid SIGSTRUCT.}(hjM hhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chM8hjI ubah}(h]h ]h"]h$]h&]uh1jhj. ubj)}(h1-EIO: EINIT failed because of a power cycle.h]h)}(hjc h]h1-EIO: EINIT failed because of a power cycle.}(hje hhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chM9hja ubah}(h]h ]h"]h$]h&]uh1jhj. ubj)}(h-errno: POSIX error.h]h)}(hj{ h]h-errno: POSIX error.}(hj} hhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chM:hjy ubah}(h]h ]h"]h$]h&]uh1jhj. ubeh}(h]h ]h"]h$]h&]j;jHuh1hhjB hM7hjX ubeh}(h]h ] kernelindentah"]h$]h&]uh1jhj]hhhNhNubj)}(hhh]h}(h]h ]h"]h$]h&]entries](j&sgx_ioc_enclave_provision (C function)c.sgx_ioc_enclave_provisionhNtauh1jhj]hhhNhNubj)}(hhh](j)}(hHlong sgx_ioc_enclave_provision (struct sgx_encl *encl, void __user *arg)h]j)}(hGlong sgx_ioc_enclave_provision(struct sgx_encl *encl, void __user *arg)h](j)}(hlongh]hlong}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj hhh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMrubj)}(h h]h }(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj hhhj hMrubj)}(hsgx_ioc_enclave_provisionh]j)}(hsgx_ioc_enclave_provisionh]hsgx_ioc_enclave_provision}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj ubah}(h]h ](jjeh"]h$]h&]hhuh1jhj hhhj hMrubj)}(h)(struct sgx_encl *encl, void __user *arg)h](j)}(hstruct sgx_encl *enclh](j)}(hjh]hstruct}(hj hhhNhNubah}(h]h ]j ah"]h$]h&]uh1jhj ubj)}(h h]h }(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj ubh)}(hhh]j)}(hsgx_enclh]hsgx_encl}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&] refdomainj5reftypej7 reftargetj modnameN classnameNj;j>)}jA]jD)}j7j sbc.sgx_ioc_enclave_provisionasbuh1hhj ubj)}(h h]h }(hj2 hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj ubjX)}(hj<h]h*}(hj@ hhhNhNubah}(h]h ]jcah"]h$]h&]uh1jWhj ubj)}(henclh]hencl}(hjM hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]noemphhhuh1jhj ubj)}(hvoid __user *argh](j)}(hvoidh]hvoid}(hjf hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjb ubj)}(h h]h }(hjt hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjb ubh__user}(hjb hhhNhNubj)}(h h]h }(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjb ubjX)}(hj<h]h*}(hj hhhNhNubah}(h]h ]jcah"]h$]h&]uh1jWhjb ubj)}(hargh]harg}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjb ubeh}(h]h ]h"]h$]h&]noemphhhuh1jhj ubeh}(h]h ]h"]h$]h&]hhuh1jhj hhhj hMrubeh}(h]h ]h"]h$]h&]hhjuh1jjjhj hhhj hMrubah}(h]j ah ](jjeh"]h$]h&]jj)jhuh1jhj hMrhj hhubj)}(hhh]h)}(h)handler for ``SGX_IOC_ENCLAVE_PROVISION``h](h handler for }(hj hhhNhNubjd)}(h``SGX_IOC_ENCLAVE_PROVISION``h]hSGX_IOC_ENCLAVE_PROVISION}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jchj ubeh}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMrhj hhubah}(h]h ]h"]h$]h&]uh1jhj hhhj hMrubeh}(h]h ](j5functioneh"]h$]h&]jj5jj jj jjjuh1jhhhj]hNhNubj )}(hX?**Parameters** ``struct sgx_encl *encl`` an enclave pointer ``void __user *arg`` userspace pointer to a struct sgx_enclave_provision instance **Description** Allow ATTRIBUTE.PROVISION_KEY for an enclave by providing a file handle to /dev/sgx_provision. **Return** - 0: Success. - -errno: Otherwise.h](h)}(h**Parameters**h]j)}(hj h]h Parameters}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMvhj ubj)}(hhh](j)}(h-``struct sgx_encl *encl`` an enclave pointer h](j)}(h``struct sgx_encl *encl``h]jd)}(hjh]hstruct sgx_encl *encl}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubah}(h]h ]h"]h$]h&]uh1jh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMshjubj)}(hhh]h)}(han enclave pointerh]han enclave pointer}(hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj/hMshj0ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhj/hMshjubj)}(hR``void __user *arg`` userspace pointer to a struct sgx_enclave_provision instance h](j)}(h``void __user *arg``h]jd)}(hjSh]hvoid __user *arg}(hjUhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjQubah}(h]h ]h"]h$]h&]uh1jh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMthjMubj)}(hhh]h)}(h)}jA]jD)}j7jnsb&c.sgx_ioc_enclave_restrict_permissionsasbuh1hhjubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubjX)}(hj<h]h*}(hjhhhNhNubah}(h]h ]jcah"]h$]h&]uh1jWhjubj)}(henclh]hencl}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]noemphhhuh1jhjubj)}(hvoid __user *argh](j)}(hvoidh]hvoid}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubh__user}(hjhhhNhNubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubjX)}(hj<h]h*}(hj(hhhNhNubah}(h]h ]jcah"]h$]h&]uh1jWhjubj)}(hargh]harg}(hj5hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]noemphhhuh1jhjubeh}(h]h ]h"]h$]h&]hhuh1jhjGhhhjYhM$ubeh}(h]h ]h"]h$]h&]hhjuh1jjjhjChhhjYhM$ubah}(h]j>ah ](jjeh"]h$]h&]jj)jhuh1jhjYhM$hj@hhubj)}(hhh]h)}(h4handler for ``SGX_IOC_ENCLAVE_RESTRICT_PERMISSIONS``h](h handler for }(hj_hhhNhNubjd)}(h(``SGX_IOC_ENCLAVE_RESTRICT_PERMISSIONS``h]h$SGX_IOC_ENCLAVE_RESTRICT_PERMISSIONS}(hjghhhNhNubah}(h]h ]h"]h$]h&]uh1jchj_ubeh}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chM$hj\hhubah}(h]h ]h"]h$]h&]uh1jhj@hhhjYhM$ubeh}(h]h ](j5functioneh"]h$]h&]jj5jjjjjjjuh1jhhhjhNhNubj )}(hX**Parameters** ``struct sgx_encl *encl`` an enclave pointer ``void __user *arg`` userspace pointer to a :c:type:`struct sgx_enclave_restrict_permissions ` instance **Description** SGX2 distinguishes between relaxing and restricting the enclave page permissions maintained by the hardware (EPCM permissions) of pages belonging to an initialized enclave (after SGX_IOC_ENCLAVE_INIT). EPCM permissions cannot be restricted from within the enclave, the enclave requires the kernel to run the privileged level 0 instructions ENCLS[EMODPR] and ENCLS[ETRACK]. An attempt to relax EPCM permissions with this call will be ignored by the hardware. **Return** - 0: Success - -errno: Otherwiseh](h)}(h**Parameters**h]j)}(hjh]h Parameters}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chM(hjubj)}(hhh](j)}(h-``struct sgx_encl *encl`` an enclave pointer h](j)}(h``struct sgx_encl *encl``h]jd)}(hjh]hstruct sgx_encl *encl}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubah}(h]h ]h"]h$]h&]uh1jh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chM&hjubj)}(hhh]h)}(han enclave pointerh]han enclave pointer}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM&hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhM&hjubj)}(h``void __user *arg`` userspace pointer to a :c:type:`struct sgx_enclave_restrict_permissions ` instance h](j)}(h``void __user *arg``h]jd)}(hjh]hvoid __user *arg}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubah}(h]h ]h"]h$]h&]uh1jh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chM(hjubj)}(hhh]h)}(htuserspace pointer to a :c:type:`struct sgx_enclave_restrict_permissions ` instanceh](huserspace pointer to a }(hjhhhNhNubh)}(hT:c:type:`struct sgx_enclave_restrict_permissions `h]jd)}(hj h]h'struct sgx_enclave_restrict_permissions}(hj hhhNhNubah}(h]h ](xrefj5c-typeeh"]h$]h&]uh1jchjubah}(h]h ]h"]h$]h&]refdoc arch/x86/sgx refdomainj5reftypetype refexplicitrefwarnj;j>)}jA]sb reftarget sgx_enclave_restrict_permissionsuh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chM'hjubh instance}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhj-hM'hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhM(hjubeh}(h]h ]h"]h$]h&]uh1jhjubh)}(h**Description**h]j)}(hjLh]h Description}(hjNhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjJubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chM*hjubh)}(hSGX2 distinguishes between relaxing and restricting the enclave page permissions maintained by the hardware (EPCM permissions) of pages belonging to an initialized enclave (after SGX_IOC_ENCLAVE_INIT).h]hSGX2 distinguishes between relaxing and restricting the enclave page permissions maintained by the hardware (EPCM permissions) of pages belonging to an initialized enclave (after SGX_IOC_ENCLAVE_INIT).}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chM)hjubh)}(hEPCM permissions cannot be restricted from within the enclave, the enclave requires the kernel to run the privileged level 0 instructions ENCLS[EMODPR] and ENCLS[ETRACK]. An attempt to relax EPCM permissions with this call will be ignored by the hardware.h]hEPCM permissions cannot be restricted from within the enclave, the enclave requires the kernel to run the privileged level 0 instructions ENCLS[EMODPR] and ENCLS[ETRACK]. An attempt to relax EPCM permissions with this call will be ignored by the hardware.}(hjqhhhNhNubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chM-hjubh)}(h **Return**h]j)}(hjh]hReturn}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chM2hjubh)}(hhh](j)}(h0: Successh]h)}(hjh]h0: Success}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chM3hjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(h-errno: Otherwiseh]h)}(hjh]h-errno: Otherwise}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chM4hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]j;jHuh1hhjhM3hjubeh}(h]h ] kernelindentah"]h$]h&]uh1jhjhhhNhNubj)}(hhh]h}(h]h ]h"]h$]h&]entries](j)sgx_ioc_enclave_modify_types (C function)c.sgx_ioc_enclave_modify_typeshNtauh1jhjhhhNhNubj)}(hhh](j)}(hKlong sgx_ioc_enclave_modify_types (struct sgx_encl *encl, void __user *arg)h]j)}(hJlong sgx_ioc_enclave_modify_types(struct sgx_encl *encl, void __user *arg)h](j)}(hlongh]hlong}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjhhh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjhhhjhMubj)}(hsgx_ioc_enclave_modify_typesh]j)}(hsgx_ioc_enclave_modify_typesh]hsgx_ioc_enclave_modify_types}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubah}(h]h ](jjeh"]h$]h&]hhuh1jhjhhhjhMubj)}(h)(struct sgx_encl *encl, void __user *arg)h](j)}(hstruct sgx_encl *enclh](j)}(hjh]hstruct}(hj.hhhNhNubah}(h]h ]j ah"]h$]h&]uh1jhj*ubj)}(h h]h }(hj;hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj*ubh)}(hhh]j)}(hsgx_enclh]hsgx_encl}(hjLhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjIubah}(h]h ]h"]h$]h&] refdomainj5reftypej7 reftargetjNmodnameN classnameNj;j>)}jA]jD)}j7jsbc.sgx_ioc_enclave_modify_typesasbuh1hhj*ubj)}(h h]h }(hjlhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj*ubjX)}(hj<h]h*}(hjzhhhNhNubah}(h]h ]jcah"]h$]h&]uh1jWhj*ubj)}(henclh]hencl}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj*ubeh}(h]h ]h"]h$]h&]noemphhhuh1jhj&ubj)}(hvoid __user *argh](j)}(hvoidh]hvoid}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubh__user}(hjhhhNhNubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubjX)}(hj<h]h*}(hjhhhNhNubah}(h]h ]jcah"]h$]h&]uh1jWhjubj)}(hargh]harg}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]noemphhŕOhuh1jhj&ubeh}(h]h ]h"]h$]h&]hhuh1jhjhhhjhMubeh}(h]h ]h"]h$]h&]hhjuh1jjjhjhhhjhMubah}(h]jah ](jjeh"]h$]h&]jj)jhuh1jhjhMhjhhubj)}(hhh]h)}(h,handler for ``SGX_IOC_ENCLAVE_MODIFY_TYPES``h](h handler for }(hjhhhNhNubjd)}(h ``SGX_IOC_ENCLAVE_MODIFY_TYPES``h]hSGX_IOC_ENCLAVE_MODIFY_TYPES}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubeh}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjhhubah}(h]h ]h"]h$]h&]uh1jhjhhhjhMubeh}(h]h ](j5functioneh"]h$]h&]jj5jj+jj+jjjuh1jhhhjhNhNubj )}(hX**Parameters** ``struct sgx_encl *encl`` an enclave pointer ``void __user *arg`` userspace pointer to a :c:type:`struct sgx_enclave_modify_types ` instance **Description** Ability to change the enclave page type supports the following use cases: * It is possible to add TCS pages to an enclave by changing the type of regular pages (``SGX_PAGE_TYPE_REG``) to TCS (``SGX_PAGE_TYPE_TCS``) pages. With this support the number of threads supported by an initialized enclave can be increased dynamically. * Regular or TCS pages can dynamically be removed from an initialized enclave by changing the page type to ``SGX_PAGE_TYPE_TRIM``. Changing the page type to ``SGX_PAGE_TYPE_TRIM`` marks the page for removal with actual removal done by handler of ``SGX_IOC_ENCLAVE_REMOVE_PAGES`` ioctl() called after ENCLU[EACCEPT] is run on ``SGX_PAGE_TYPE_TRIM`` page from within the enclave. **Return** - 0: Success - -errno: Otherwiseh](h)}(h**Parameters**h]j)}(hj5h]h Parameters}(hj7hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj3ubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhj/ubj)}(hhh](j)}(h-``struct sgx_encl *encl`` an enclave pointer h](j)}(h``struct sgx_encl *encl``h]jd)}(hjTh]hstruct sgx_encl *encl}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjRubah}(h]h ]h"]h$]h&]uh1jh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjNubj)}(hhh]h)}(han enclave pointerh]han enclave pointer}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjihMhjjubah}(h]h ]h"]h$]h&]uh1jhjNubeh}(h]h ]h"]h$]h&]uh1jhjihMhjKubj)}(hz``void __user *arg`` userspace pointer to a :c:type:`struct sgx_enclave_modify_types ` instance h](j)}(h``void __user *arg``h]jd)}(hjh]hvoid __user *arg}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubah}(h]h ]h"]h$]h&]uh1jh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjubj)}(hhh]h)}(hduserspace pointer to a :c:type:`struct sgx_enclave_modify_types ` instanceh](huserspace pointer to a }(hjhhhNhNubh)}(hD:c:type:`struct sgx_enclave_modify_types `h]jd)}(hjh]hstruct sgx_enclave_modify_types}(hjhhhNhNubah}(h]h ](jj5c-typeeh"]h$]h&]uh1jchjubah}(h]h ]h"]h$]h&]refdocj" refdomainj5reftypetype refexplicitrefwarnj;j(j+sgx_enclave_modify_typesuh1hhjhMhjubh instance}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhMhjKubeh}(h]h ]h"]h$]h&]uh1jhj/ubh)}(h**Description**h]j)}(hjh]h Description}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhj/ubh)}(hIAbility to change the enclave page type supports the following use cases:h]hIAbility to change the enclave page type supports the following use cases:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhj/ubh)}(hhh](j)}(hIt is possible to add TCS pages to an enclave by changing the type of regular pages (``SGX_PAGE_TYPE_REG``) to TCS (``SGX_PAGE_TYPE_TCS``) pages. With this support the number of threads supported by an initialized enclave can be increased dynamically. h]h)}(hIt is possible to add TCS pages to an enclave by changing the type of regular pages (``SGX_PAGE_TYPE_REG``) to TCS (``SGX_PAGE_TYPE_TCS``) pages. With this support the number of threads supported by an initialized enclave can be increased dynamically.h](hUIt is possible to add TCS pages to an enclave by changing the type of regular pages (}(hjhhhNhNubjd)}(h``SGX_PAGE_TYPE_REG``h]hSGX_PAGE_TYPE_REG}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubh ) to TCS (}(hjhhhNhNubjd)}(h``SGX_PAGE_TYPE_TCS``h]hSGX_PAGE_TYPE_TCS}(hj1hhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubhr) pages. With this support the number of threads supported by an initialized enclave can be increased dynamically.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hXxRegular or TCS pages can dynamically be removed from an initialized enclave by changing the page type to ``SGX_PAGE_TYPE_TRIM``. Changing the page type to ``SGX_PAGE_TYPE_TRIM`` marks the page for removal with actual removal done by handler of ``SGX_IOC_ENCLAVE_REMOVE_PAGES`` ioctl() called after ENCLU[EACCEPT] is run on ``SGX_PAGE_TYPE_TRIM`` page from within the enclave. h]h)}(hXwRegular or TCS pages can dynamically be removed from an initialized enclave by changing the page type to ``SGX_PAGE_TYPE_TRIM``. Changing the page type to ``SGX_PAGE_TYPE_TRIM`` marks the page for removal with actual removal done by handler of ``SGX_IOC_ENCLAVE_REMOVE_PAGES`` ioctl() called after ENCLU[EACCEPT] is run on ``SGX_PAGE_TYPE_TRIM`` page from within the enclave.h](hiRegular or TCS pages can dynamically be removed from an initialized enclave by changing the page type to }(hjThhhNhNubjd)}(h``SGX_PAGE_TYPE_TRIM``h]hSGX_PAGE_TYPE_TRIM}(hj\hhhNhNubah}(h]h ]h"]h$]h&]uh1jchjTubh. Changing the page type to }(hjThhhNhNubjd)}(h``SGX_PAGE_TYPE_TRIM``h]hSGX_PAGE_TYPE_TRIM}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjTubhC marks the page for removal with actual removal done by handler of }(hjThhhNhNubjd)}(h ``SGX_IOC_ENCLAVE_REMOVE_PAGES``h]hSGX_IOC_ENCLAVE_REMOVE_PAGES}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjTubh/ ioctl() called after ENCLU[EACCEPT] is run on }(hjThhhNhNubjd)}(h``SGX_PAGE_TYPE_TRIM``h]hSGX_PAGE_TYPE_TRIM}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjTubh page from within the enclave.}(hjThhhNhNubeh}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjPubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]j;j<uh1hhjIhMhj/ubh)}(h **Return**h]j)}(hjh]hReturn}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhj/ubh)}(hhh](j)}(h0: Successh]h)}(hjh]h0: Success}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(h-errno: Otherwiseh]h)}(hjh]h-errno: Otherwise}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]j;jHuh1hhjhMhj/ubeh}(h]h ] kernelindentah"]h$]h&]uh1jhjhhhNhNubj)}(hhh]h}(h]h ]h"]h$]h&]entries](j)sgx_ioc_enclave_remove_pages (C function)c.sgx_ioc_enclave_remove_pageshNtauh1jhjhhhNhNubj)}(hhh](j)}(hKlong sgx_ioc_enclave_remove_pages (struct sgx_encl *encl, void __user *arg)h]j)}(hJlong sgx_ioc_enclave_remove_pages(struct sgx_encl *encl, void __user *arg)h](j)}(hlongh]hlong}(hj(hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj$hhh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMubj)}(h h]h }(hj7hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj$hhhj6hMubj)}(hsgx_ioc_enclave_remove_pagesh]j)}(hsgx_ioc_enclave_remove_pagesh]hsgx_ioc_enclave_remove_pages}(hjIhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjEubah}(h]h ](jjeh"]h$]h&]hhuh1jhj$hhhj6hMubj)}(h)(struct sgx_encl *encl, void __user *arg)h](j)}(hstruct sgx_encl *enclh](j)}(hjh]hstruct}(hjehhhNhNubah}(h]h ]j ah"]h$]h&]uh1jhjaubj)}(h h]h }(hjrhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjaubh)}(hhh]j)}(hsgx_enclh]hsgx_encl}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&] refdomainj5reftypej7 reftargetjmodnameN classnameNj;j>)}jA]jD)}j7jKsbc.sgx_ioc_enclave_remove_pagesasbuh1hhjaubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjaubjX)}(hj<h]h*}(hjhhhNhNubah}(h]h ]jcah"]h$]h&]uh1jWhjaubj)}(henclh]hencl}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjaubeh}(h]h ]h"]h$]h&]noemphhhuh1jhj]ubj)}(hvoid __user *argh](j)}(hvoidh]hvoid}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubh__user}(hjhhhNhNubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubjX)}(hj<h]h*}(hjhhhNhNubah}(h]h ]jcah"]h$]h&]uh1jWhjubj)}(hargh]harg}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]noemphhhuh1jhj]ubeh}(h]h ]h"]h$]h&]hhuh1jhj$hhhj6hMubeh}(h]h ]h"]h$]h&]hhjuh1jjjhj hhhj6hMubah}(h]jah ](jjeh"]h$]h&]jj)jhuh1jhj6hMhjhhubj)}(hhh]h)}(h,handler for ``SGX_IOC_ENCLAVE_REMOVE_PAGES``h](h handler for }(hj<hhhNhNubjd)}(h ``SGX_IOC_ENCLAVE_REMOVE_PAGES``h]hSGX_IOC_ENCLAVE_REMOVE_PAGES}(hjDhhhNhNubah}(h]h ]h"]h$]h&]uh1jchj<ubeh}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhj9hhubah}(h]h ]h"]h$]h&]uh1jhjhhhj6hMubeh}(h]h ](j5functioneh"]h$]h&]jj5jjbjjbjjjuh1jhhhjhNhNubj )}(hX**Parameters** ``struct sgx_encl *encl`` an enclave pointer ``void __user *arg`` userspace pointer to :c:type:`struct sgx_enclave_remove_pages ` instance **Description** Final step of the flow removing pages from an initialized enclave. The complete flow is: 1) User changes the type of the pages to be removed to ``SGX_PAGE_TYPE_TRIM`` using the ``SGX_IOC_ENCLAVE_MODIFY_TYPES`` ioctl(). 2) User approves the page removal by running ENCLU[EACCEPT] from within the enclave. 3) User initiates actual page removal using the ``SGX_IOC_ENCLAVE_REMOVE_PAGES`` ioctl() that is handled here. First remove any page table entries pointing to the page and then proceed with the actual removal of the enclave page and data in support of it. VA pages are not affected by this removal. It is thus possible that the enclave may end up with more VA pages than needed to support all its pages. **Return** - 0: Success - -errno: Otherwiseh](h)}(h**Parameters**h]j)}(hjlh]h Parameters}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjjubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjfubj)}(hhh](j)}(h-``struct sgx_encl *encl`` an enclave pointer h](j)}(h``struct sgx_encl *encl``h]jd)}(hjh]hstruct sgx_encl *encl}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubah}(h]h ]h"]h$]h&]uh1jh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjubj)}(hhh]h)}(han enclave pointerh]han enclave pointer}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhMhjubj)}(hx``void __user *arg`` userspace pointer to :c:type:`struct sgx_enclave_remove_pages ` instance h](j)}(h``void __user *arg``h]jd)}(hjh]hvoid __user *arg}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubah}(h]h ]h"]h$]h&]uh1jh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjubj)}(hhh]h)}(hbuserspace pointer to :c:type:`struct sgx_enclave_remove_pages ` instanceh](huserspace pointer to }(hjhhhNhNubh)}(hD:c:type:`struct sgx_enclave_remove_pages `h]jd)}(hjh]hstruct sgx_enclave_remove_pages}(hjhhhNhNubah}(h]h ](jj5c-typeeh"]h$]h&]uh1jchjubah}(h]h ]h"]h$]h&]refdocj" refdomainj5reftypetype refexplicitrefwarnj;j(j+sgx_enclave_remove_pagesuh1hhjhMhjubh instance}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhMhjubeh}(h]h ]h"]h$]h&]uh1jhjfubh)}(h**Description**h]j)}(hj"h]h Description}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjfubh)}(hXFinal step of the flow removing pages from an initialized enclave. The complete flow is:h]hXFinal step of the flow removing pages from an initialized enclave. The complete flow is:}(hj8hhhNhNubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjfubj)}(hhh](j)}(h~User changes the type of the pages to be removed to ``SGX_PAGE_TYPE_TRIM`` using the ``SGX_IOC_ENCLAVE_MODIFY_TYPES`` ioctl().h]h)}(h~User changes the type of the pages to be removed to ``SGX_PAGE_TYPE_TRIM`` using the ``SGX_IOC_ENCLAVE_MODIFY_TYPES`` ioctl().h](h4User changes the type of the pages to be removed to }(hjNhhhNhNubjd)}(h``SGX_PAGE_TYPE_TRIM``h]hSGX_PAGE_TYPE_TRIM}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjNubh using the }(hjNhhhNhNubjd)}(h ``SGX_IOC_ENCLAVE_MODIFY_TYPES``h]hSGX_IOC_ENCLAVE_MODIFY_TYPES}(hjhhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjNubh ioctl().}(hjNhhhNhNubeh}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjJubah}(h]h ]h"]h$]h&]uh1jhjGubj)}(hQUser approves the page removal by running ENCLU[EACCEPT] from within the enclave.h]h)}(hQUser approves the page removal by running ENCLU[EACCEPT] from within the enclave.h]hQUser approves the page removal by running ENCLU[EACCEPT] from within the enclave.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjubah}(h]h ]h"]h$]h&]uh1jhjGubj)}(hlUser initiates actual page removal using the ``SGX_IOC_ENCLAVE_REMOVE_PAGES`` ioctl() that is handled here. h]h)}(hkUser initiates actual page removal using the ``SGX_IOC_ENCLAVE_REMOVE_PAGES`` ioctl() that is handled here.h](h-User initiates actual page removal using the }(hjhhhNhNubjd)}(h ``SGX_IOC_ENCLAVE_REMOVE_PAGES``h]hSGX_IOC_ENCLAVE_REMOVE_PAGES}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubh ioctl() that is handled here.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjubah}(h]h ]h"]h$]h&]uh1jhjGubeh}(h]h ]h"]h$]h&]jjjhj)uh1jhjfubh)}(hFirst remove any page table entries pointing to the page and then proceed with the actual removal of the enclave page and data in support of it.h]hFirst remove any page table entries pointing to the page and then proceed with the actual removal of the enclave page and data in support of it.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjfubh)}(hVA pages are not affected by this removal. It is thus possible that the enclave may end up with more VA pages than needed to support all its pages.h]hVA pages are not affected by this removal. It is thus possible that the enclave may end up with more VA pages than needed to support all its pages.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjfubh)}(h **Return**h]j)}(hjh]hReturn}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjfubh)}(hhh](j)}(h0: Successh]h)}(hj h]h0: Success}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhj ubah}(h]h ]h"]h$]h&]uh1jhjubj)}(h-errno: Otherwiseh]h)}(hj%h]h-errno: Otherwise}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhj#ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]j;jHuh1hhjhMhjfubeh}(h]h ] kernelindentah"]h$]h&]uh1jhjhhhNhNubeh}(h]enclave-runtime-managementah ]h"]enclave runtime managementah$]h&]uh1hhjLhhhhhKhubh)}(hhh](h)}(h Enclave vDSOh]h Enclave vDSO}(hjShhhNhNubah}(h]h ]h"]h$]h&]uh1hhjPhhhhhKwubh)}(hXlEntering an enclave can only be done through SGX-specific EENTER and ERESUME functions, and is a non-trivial process. Because of the complexity of transitioning to and from an enclave, enclaves typically utilize a library to handle the actual transitions. This is roughly analogous to how glibc implementations are used by most applications to wrap system calls.h]hXlEntering an enclave can only be done through SGX-specific EENTER and ERESUME functions, and is a non-trivial process. Because of the complexity of transitioning to and from an enclave, enclaves typically utilize a library to handle the actual transitions. This is roughly analogous to how glibc implementations are used by most applications to wrap system calls.}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKyhjPhhubh)}(hAnother crucial characteristic of enclaves is that they can generate exceptions as part of their normal operation that need to be handled in the enclave or are unique to SGX.h]hAnother crucial characteristic of enclaves is that they can generate exceptions as part of their normal operation that need to be handled in the enclave or are unique to SGX.}(hjohhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjPhhubh)}(hXInstead of the traditional signal mechanism to handle these exceptions, SGX can leverage special exception fixup provided by the vDSO. The kernel-provided vDSO function wraps low-level transitions to/from the enclave like EENTER and ERESUME. The vDSO function intercepts exceptions that would otherwise generate a signal and return the fault information directly to its caller. This avoids the need to juggle signal handlers.h]hXInstead of the traditional signal mechanism to handle these exceptions, SGX can leverage special exception fixup provided by the vDSO. The kernel-provided vDSO function wraps low-level transitions to/from the enclave like EENTER and ERESUME. The vDSO function intercepts exceptions that would otherwise generate a signal and return the fault information directly to its caller. This avoids the need to juggle signal handlers.}(hj}hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjPhhubj)}(hhh]h}(h]h ]h"]h$]h&]entries](j"vdso_sgx_enter_enclave_t (C macro)c.vdso_sgx_enter_enclave_thNtauh1jhjPhhhNhNubj)}(hhh](j)}(hvdso_sgx_enter_enclave_th]j)}(hvdso_sgx_enter_enclave_th]j)}(hvdso_sgx_enter_enclave_th]j)}(hjh]hvdso_sgx_enter_enclave_t}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubah}(h]h ](jjeh"]h$]h&]hhuh1jhjhhh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKubah}(h]h ]h"]h$]h&]hhjuh1jjjhjhhhjhKubah}(h]jah ](jjeh"]h$]h&]jj)jhuh1jhjhKhjhhubj)}(hhh]h)}(h_**Typedef**: Prototype for __vdso_sgx_enter_enclave(), a vDSO function to enter an SGX enclave.h](j)}(h **Typedef**h]hTypedef}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhT: Prototype for __vdso_sgx_enter_enclave(), a vDSO function to enter an SGX enclave.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhjhhubah}(h]h ]h"]h$]h&]uh1jhjhhhjhKubeh}(h]h ](j5macroeh"]h$]h&]jj5jjjjjjjuh1jhhhjPhNhNubh)}(h **Syntax**h]j)}(hjh]hSyntax}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhjPhhubjZ)}(h``int vdso_sgx_enter_enclave_t (unsigned long rdi, unsigned long rsi, unsigned long rdx, unsigned int function, unsigned long r8, unsigned long r9, struct sgx_enclave_run *run)`` h]h)}(h``int vdso_sgx_enter_enclave_t (unsigned long rdi, unsigned long rsi, unsigned long rdx, unsigned int function, unsigned long r8, unsigned long r9, struct sgx_enclave_run *run)``h]jd)}(hjh]hint vdso_sgx_enter_enclave_t (unsigned long rdi, unsigned long rsi, unsigned long rdx, unsigned int function, unsigned long r8, unsigned long r9, struct sgx_enclave_run *run)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhj ubah}(h]h ]h"]h$]h&]uh1jYhj(hKhjPhhubj )}(hX**Parameters** ``unsigned long rdi`` Pass-through value for RDI ``unsigned long rsi`` Pass-through value for RSI ``unsigned long rdx`` Pass-through value for RDX ``unsigned int function`` ENCLU function, must be EENTER or ERESUME ``unsigned long r8`` Pass-through value for R8 ``unsigned long r9`` Pass-through value for R9 ``struct sgx_enclave_run *run`` struct sgx_enclave_run, must be non-NULL **NOTE** __vdso_sgx_enter_enclave() does not ensure full compliance with the x86-64 ABI, e.g. doesn't handle XSAVE state. Except for non-volatile general purpose registers, EFLAGS.DF, and RSP alignment, preserving/setting state in accordance with the x86-64 ABI is the responsibility of the enclave and its runtime, i.e. __vdso_sgx_enter_enclave() cannot be called from C code without careful consideration by both the enclave and its runtime. All general purpose registers except RAX, RBX and RCX are passed as-is to the enclave. RAX, RBX and RCX are consumed by EENTER and ERESUME and are loaded with **function**, asynchronous exit pointer, and **run.tcs** respectively. RBP and the stack are used to anchor __vdso_sgx_enter_enclave() to the pre-enclave state, e.g. to retrieve **run.exception** and **run.user_handler** after an enclave exit. All other registers are available for use by the enclave and its runtime, e.g. an enclave can push additional data onto the stack (and modify RSP) to pass information to the optional user handler (see below). Most exceptions reported on ENCLU, including those that occur within the enclave, are fixed up and reported synchronously instead of being delivered via a standard signal. Debug Exceptions (#DB) and Breakpoints (#BP) are never fixed up and are always delivered via standard signals. On synchronously reported exceptions, -EFAULT is returned and details about the exception are recorded in **run.exception**, the optional sgx_enclave_exception struct. **Return** - 0: ENCLU function was successfully executed. - -EINVAL: Invalid ENCL number (neither EENTER nor ERESUME).h](h)}(h**Parameters**h]j)}(hj5h]h Parameters}(hj7hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj3ubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhj/ubj)}(hhh](j)}(h1``unsigned long rdi`` Pass-through value for RDI h](j)}(h``unsigned long rdi``h]jd)}(hjTh]hunsigned long rdi}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjRubah}(h]h ]h"]h$]h&]uh1jh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhjNubj)}(hhh]h)}(hPass-through value for RDIh]hPass-through value for RDI}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjihKhjjubah}(h]h ]h"]h$]h&]uh1jhjNubeh}(h]h ]h"]h$]h&]uh1jhjihKhjKubj)}(h1``unsigned long rsi`` Pass-through value for RSI h](j)}(h``unsigned long rsi``h]jd)}(hjh]hunsigned long rsi}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubah}(h]h ]h"]h$]h&]uh1jh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhjubj)}(hhh]h)}(hPass-through value for RSIh]hPass-through value for RSI}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhKhjKubj)}(h1``unsigned long rdx`` Pass-through value for RDX h](j)}(h``unsigned long rdx``h]jd)}(hjh]hunsigned long rdx}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubah}(h]h ]h"]h$]h&]uh1jh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhjubj)}(hhh]h)}(hPass-through value for RDXh]hPass-through value for RDX}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhKhjKubj)}(hD``unsigned int function`` ENCLU function, must be EENTER or ERESUME h](j)}(h``unsigned int function``h]jd)}(hjh]hunsigned int function}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubah}(h]h ]h"]h$]h&]uh1jh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhjubj)}(hhh]h)}(h)ENCLU function, must be EENTER or ERESUMEh]h)ENCLU function, must be EENTER or ERESUME}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhKhjKubj)}(h/``unsigned long r8`` Pass-through value for R8 h](j)}(h``unsigned long r8``h]jd)}(hj8h]hunsigned long r8}(hj:hhhNhNubah}(h]h ]h"]h$]h&]uh1jchj6ubah}(h]h ]h"]h$]h&]uh1jh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhj2ubj)}(hhh]h)}(hPass-through value for R8h]hPass-through value for R8}(hjQhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjMhKhjNubah}(h]h ]h"]h$]h&]uh1jhj2ubeh}(h]h ]h"]h$]h&]uh1jhjMhKhjKubj)}(h/``unsigned long r9`` Pass-through value for R9 h](j)}(h``unsigned long r9``h]jd)}(hjqh]hunsigned long r9}(hjshhhNhNubah}(h]h ]h"]h$]h&]uh1jchjoubah}(h]h ]h"]h$]h&]uh1jh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhjkubj)}(hhh]h)}(hPass-through value for R9h]hPass-through value for R9}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubah}(h]h ]h"]h$]h&]uh1jhjkubeh}(h]h ]h"]h$]h&]uh1jhjhKhjKubj)}(hI``struct sgx_enclave_run *run`` struct sgx_enclave_run, must be non-NULL h](j)}(h``struct sgx_enclave_run *run``h]jd)}(hjh]hstruct sgx_enclave_run *run}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubah}(h]h ]h"]h$]h&]uh1jh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhjubj)}(hhh]h)}(h(struct sgx_enclave_run, must be non-NULLh]h(struct sgx_enclave_run, must be non-NULL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhKhjKubeh}(h]h ]h"]h$]h&]uh1jhj/ubh)}(h**NOTE**h]j)}(hjh]hNOTE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhj/ubh)}(hX__vdso_sgx_enter_enclave() does not ensure full compliance with the x86-64 ABI, e.g. doesn't handle XSAVE state. Except for non-volatile general purpose registers, EFLAGS.DF, and RSP alignment, preserving/setting state in accordance with the x86-64 ABI is the responsibility of the enclave and its runtime, i.e. __vdso_sgx_enter_enclave() cannot be called from C code without careful consideration by both the enclave and its runtime.h]hX__vdso_sgx_enter_enclave() does not ensure full compliance with the x86-64 ABI, e.g. doesn’t handle XSAVE state. Except for non-volatile general purpose registers, EFLAGS.DF, and RSP alignment, preserving/setting state in accordance with the x86-64 ABI is the responsibility of the enclave and its runtime, i.e. __vdso_sgx_enter_enclave() cannot be called from C code without careful consideration by both the enclave and its runtime.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhj/ubh)}(hAll general purpose registers except RAX, RBX and RCX are passed as-is to the enclave. RAX, RBX and RCX are consumed by EENTER and ERESUME and are loaded with **function**, asynchronous exit pointer, and **run.tcs** respectively.h](hAll general purpose registers except RAX, RBX and RCX are passed as-is to the enclave. RAX, RBX and RCX are consumed by EENTER and ERESUME and are loaded with }(hj hhhNhNubj)}(h **function**h]hfunction}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh!, asynchronous exit pointer, and }(hj hhhNhNubj)}(h **run.tcs**h]hrun.tcs}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh respectively.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhj/ubh)}(hX~RBP and the stack are used to anchor __vdso_sgx_enter_enclave() to the pre-enclave state, e.g. to retrieve **run.exception** and **run.user_handler** after an enclave exit. All other registers are available for use by the enclave and its runtime, e.g. an enclave can push additional data onto the stack (and modify RSP) to pass information to the optional user handler (see below).h](hkRBP and the stack are used to anchor __vdso_sgx_enter_enclave() to the pre-enclave state, e.g. to retrieve }(hj=hhhNhNubj)}(h**run.exception**h]h run.exception}(hjEhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj=ubh and }(hj=hhhNhNubj)}(h**run.user_handler**h]hrun.user_handler}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj=ubh after an enclave exit. All other registers are available for use by the enclave and its runtime, e.g. an enclave can push additional data onto the stack (and modify RSP) to pass information to the optional user handler (see below).}(hj=hhhNhNubeh}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhj/ubh)}(hXMost exceptions reported on ENCLU, including those that occur within the enclave, are fixed up and reported synchronously instead of being delivered via a standard signal. Debug Exceptions (#DB) and Breakpoints (#BP) are never fixed up and are always delivered via standard signals. On synchronously reported exceptions, -EFAULT is returned and details about the exception are recorded in **run.exception**, the optional sgx_enclave_exception struct.h](hXMost exceptions reported on ENCLU, including those that occur within the enclave, are fixed up and reported synchronously instead of being delivered via a standard signal. Debug Exceptions (#DB) and Breakpoints (#BP) are never fixed up and are always delivered via standard signals. On synchronously reported exceptions, -EFAULT is returned and details about the exception are recorded in }(hjphhhNhNubj)}(h**run.exception**h]h run.exception}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjpubh,, the optional sgx_enclave_exception struct.}(hjphhhNhNubeh}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhj/ubh)}(h **Return**h]j)}(hjh]hReturn}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhj/ubh)}(hhh](j)}(h40: ENCLU function was successfully executed.h]h)}(hjh]h40: ENCLU function was successfully executed.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(h<-EINVAL: Invalid ENCL number (neither EENTER nor ERESUME).h]h)}(hjh]h<-EINVAL: Invalid ENCL number (neither EENTER nor ERESUME).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]j;jHuh1hhjhKhj/ubeh}(h]h ] kernelindentah"]h$]h&]uh1jhjPhhhNhNubeh}(h] enclave-vdsoah ]h"] enclave vdsoah$]h&]uh1hhjLhhhhhKwubeh}(h]application-interfaceah ]h"]application interfaceah$]h&]uh1hhhhhhhhKUubh)}(hhh](h)}(hksgxdh]hksgxd}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(h4SGX support includes a kernel thread called *ksgxd*.h](h,SGX support includes a kernel thread called }(hj hhhNhNubj)}(h*ksgxd*h]hksgxd}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hhh](h)}(hEPC sanitizationh]hEPC sanitization}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj*hhhhhKubh)}(hXvksgxd is started when SGX initializes. Enclave memory is typically ready for use when the processor powers on or resets. However, if SGX has been in use since the reset, enclave pages may be in an inconsistent state. This might occur after a crash and kexec() cycle, for instance. At boot, ksgxd reinitializes all enclave pages so that they can be allocated and re-used.h]hXvksgxd is started when SGX initializes. Enclave memory is typically ready for use when the processor powers on or resets. However, if SGX has been in use since the reset, enclave pages may be in an inconsistent state. This might occur after a crash and kexec() cycle, for instance. At boot, ksgxd reinitializes all enclave pages so that they can be allocated and re-used.}(hj;hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj*hhubh)}(hX!The sanitization is done by going through EPC address space and applying the EREMOVE function to each physical page. Some enclave pages like SECS pages have hardware dependencies on other pages which prevents EREMOVE from functioning. Executing two EREMOVE passes removes the dependencies.h]hX!The sanitization is done by going through EPC address space and applying the EREMOVE function to each physical page. Some enclave pages like SECS pages have hardware dependencies on other pages which prevents EREMOVE from functioning. Executing two EREMOVE passes removes the dependencies.}(hjIhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj*hhubeh}(h]epc-sanitizationah ]h"]epc sanitizationah$]h&]uh1hhjhhhhhKubh)}(hhh](h)}(hPage reclaimerh]hPage reclaimer}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj_hhhhhKubh)}(hSimilar to the core kswapd, ksgxd, is responsible for managing the overcommitment of enclave memory. If the system runs out of enclave memory, *ksgxd* “swaps” enclave memory to normal memory.h](hSimilar to the core kswapd, ksgxd, is responsible for managing the overcommitment of enclave memory. If the system runs out of enclave memory, }(hjphhhNhNubj)}(h*ksgxd*h]hksgxd}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjpubh- “swaps” enclave memory to normal memory.}(hjphhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj_hhubeh}(h]page-reclaimerah ]h"]page reclaimerah$]h&]uh1hhjhhhhhKubeh}(h]ksgxdah ]h"]ksgxdah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hLaunch Controlh]hLaunch Control}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hSGX provides a launch control mechanism. After all enclave pages have been copied, kernel executes EINIT function, which initializes the enclave. Only after this the CPU can execute inside the enclave.h]hSGX provides a launch control mechanism. After all enclave pages have been copied, kernel executes EINIT function, which initializes the enclave. Only after this the CPU can execute inside the enclave.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXEINIT function takes an RSA-3072 signature of the enclave measurement. The function checks that the measurement is correct and signature is signed with the key hashed to the four **IA32_SGXLEPUBKEYHASH{0, 1, 2, 3}** MSRs representing the SHA256 of a public key.h](hEINIT function takes an RSA-3072 signature of the enclave measurement. The function checks that the measurement is correct and signature is signed with the key hashed to the four }(hjhhhNhNubj)}(h$**IA32_SGXLEPUBKEYHASH{0, 1, 2, 3}**h]h IA32_SGXLEPUBKEYHASH{0, 1, 2, 3}}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh. MSRs representing the SHA256 of a public key.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXThose MSRs can be configured by the BIOS to be either readable or writable. Linux supports only writable configuration in order to give full control to the kernel on launch control policy. Before calling EINIT function, the driver sets the MSRs to match the enclave's signing key.h]hXThose MSRs can be configured by the BIOS to be either readable or writable. Linux supports only writable configuration in order to give full control to the kernel on launch control policy. Before calling EINIT function, the driver sets the MSRs to match the enclave’s signing key.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]launch-controlah ]h"]launch controlah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hEncryption enginesh]hEncryption engines}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hIn order to conceal the enclave data while it is out of the CPU package, the memory controller has an encryption engine to transparently encrypt and decrypt enclave memory.h]hIn order to conceal the enclave data while it is out of the CPU package, the memory controller has an encryption engine to transparently encrypt and decrypt enclave memory.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXIn CPUs prior to Ice Lake, the Memory Encryption Engine (MEE) is used to encrypt pages leaving the CPU caches. MEE uses a n-ary Merkle tree with root in SRAM to maintain integrity of the encrypted data. This provides integrity and anti-replay protection but does not scale to large memory sizes because the time required to update the Merkle tree grows logarithmically in relation to the memory size.h]hXIn CPUs prior to Ice Lake, the Memory Encryption Engine (MEE) is used to encrypt pages leaving the CPU caches. MEE uses a n-ary Merkle tree with root in SRAM to maintain integrity of the encrypted data. This provides integrity and anti-replay protection but does not scale to large memory sizes because the time required to update the Merkle tree grows logarithmically in relation to the memory size.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXICPUs starting from Icelake use Total Memory Encryption (TME) in the place of MEE. TME-based SGX implementations do not have an integrity Merkle tree, which means integrity and replay-attacks are not mitigated. B, it includes additional changes to prevent cipher text from being returned and SW memory aliases from being created.h]hXICPUs starting from Icelake use Total Memory Encryption (TME) in the place of MEE. TME-based SGX implementations do not have an integrity Merkle tree, which means integrity and replay-attacks are not mitigated. B, it includes additional changes to prevent cipher text from being returned and SW memory aliases from being created.}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hdDMA to enclave memory is blocked by range registers on both MEE and TME systems (SDM section 41.10).h]hdDMA to enclave memory is blocked by range registers on both MEE and TME systems (SDM section 41.10).}(hj0hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]encryption-enginesah ]h"]encryption enginesah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h Usage Modelsh]h Usage Models}(hjIhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjFhhhhhKubh)}(hhh](h)}(hShared Libraryh]hShared Library}(hjZhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjWhhhhhKubh)}(hXSensitive data and the code that acts on it is partitioned from the application into a separate library. The library is then linked as a DSO which can be loaded into an enclave. The application can then make individual function calls into the enclave through special SGX instructions. A run-time within the enclave is configured to marshal function parameters into and out of the enclave and to call the correct library function.h]hXSensitive data and the code that acts on it is partitioned from the application into a separate library. The library is then linked as a DSO which can be loaded into an enclave. The application can then make individual function calls into the enclave through special SGX instructions. A run-time within the enclave is configured to marshal function parameters into and out of the enclave and to call the correct library function.}(hjhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjWhhubeh}(h]shared-libraryah ]h"]shared libraryah$]h&]uh1hhjFhhhhhKubh)}(hhh](h)}(hApplication Containerh]hApplication Container}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj~hhhhhKubh)}(hXAn application may be loaded into a container enclave which is specially configured with a library OS and run-time which permits the application to run. The enclave run-time and library OS work together to execute the application when a thread enters the enclave.h]hXAn application may be loaded into a container enclave which is specially configured with a library OS and run-time which permits the application to run. The enclave run-time and library OS work together to execute the application when a thread enters the enclave.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj~hhubeh}(h]application-containerah ]h"]application containerah$]h&]uh1hhjFhhhhhKubeh}(h] usage-modelsah ]h"] usage modelsah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h#Impact of Potential Kernel SGX Bugsh]h#Impact of Potential Kernel SGX Bugs}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hhh](h)}(h EPC leaksh]h EPC leaks}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hBWhen EPC page leaks happen, a WARNING like this is shown in dmesg:h]hBWhen EPC page leaks happen, a WARNING like this is shown in dmesg:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hN"EREMOVE returned ... and an EPC page was leaked. SGX may become unusable..."h]hR“EREMOVE returned ... and an EPC page was leaked. SGX may become unusable...”}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXThis is effectively a kernel use-after-free of an EPC page, and due to the way SGX works, the bug is detected at freeing. Rather than adding the page back to the pool of available EPC pages, the kernel intentionally leaks the page to avoid additional errors in the future.h]hXThis is effectively a kernel use-after-free of an EPC page, and due to the way SGX works, the bug is detected at freeing. Rather than adding the page back to the pool of available EPC pages, the kernel intentionally leaks the page to avoid additional errors in the future.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXWhen this happens, the kernel will likely soon leak more EPC pages, and SGX will likely become unusable because the memory available to SGX is limited. However, while this may be fatal to SGX, the rest of the kernel is unlikely to be impacted and should continue to work.h]hXWhen this happens, the kernel will likely soon leak more EPC pages, and SGX will likely become unusable because the memory available to SGX is limited. However, while this may be fatal to SGX, the rest of the kernel is unlikely to be impacted and should continue to work.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hAs a result, when this happens, user should stop running any new SGX workloads, (or just any new workloads), and migrate all valuable workloads. Although a machine reboot can recover all EPC memory, the bug should be reported to Linux developers.h]hAs a result, when this happens, user should stop running any new SGX workloads, (or just any new workloads), and migrate all valuable workloads. Although a machine reboot can recover all EPC memory, the bug should be reported to Linux developers.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h] epc-leaksah ]h"] epc leaksah$]h&]uh1hhjhhhhhKubeh}(h]#impact-of-potential-kernel-sgx-bugsah ]h"]#impact of potential kernel sgx bugsah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h Virtual EPCh]h Virtual EPC}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj%hhhhhKubh)}(hX The implementation has also a virtual EPC driver to support SGX enclaves in guests. Unlike the SGX driver, an EPC page allocated by the virtual EPC driver doesn't have a specific enclave associated with it. This is because KVM doesn't track how a guest uses EPC pages.h]hXThe implementation has also a virtual EPC driver to support SGX enclaves in guests. Unlike the SGX driver, an EPC page allocated by the virtual EPC driver doesn’t have a specific enclave associated with it. This is because KVM doesn’t track how a guest uses EPC pages.}(hj6hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj%hhubh)}(hXAs a result, the SGX core page reclaimer doesn't support reclaiming EPC pages allocated to KVM guests through the virtual EPC driver. If the user wants to deploy SGX applications both on the host and in guests on the same machine, the user should reserve enough EPC (by taking out total virtual EPC size of all SGX VMs from the physical EPC size) for host SGX applications so they can run with acceptable performance.h]hXAs a result, the SGX core page reclaimer doesn’t support reclaiming EPC pages allocated to KVM guests through the virtual EPC driver. If the user wants to deploy SGX applications both on the host and in guests on the same machine, the user should reserve enough EPC (by taking out total virtual EPC size of all SGX VMs from the physical EPC size) for host SGX applications so they can run with acceptable performance.}(hjDhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj%hhubh)}(hXCArchitectural behavior is to restore all EPC pages to an uninitialized state also after a guest reboot. Because this state can be reached only through the privileged ``ENCLS[EREMOVE]`` instruction, ``/dev/sgx_vepc`` provides the ``SGX_IOC_VEPC_REMOVE_ALL`` ioctl to execute the instruction on all pages in the virtual EPC.h](hArchitectural behavior is to restore all EPC pages to an uninitialized state also after a guest reboot. Because this state can be reached only through the privileged }(hjRhhhNhNubjd)}(h``ENCLS[EREMOVE]``h]hENCLS[EREMOVE]}(hjZhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjRubh instruction, }(hjRhhhNhNubjd)}(h``/dev/sgx_vepc``h]h /dev/sgx_vepc}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjRubh provides the }(hjRhhhNhNubjd)}(h``SGX_IOC_VEPC_REMOVE_ALL``h]hSGX_IOC_VEPC_REMOVE_ALL}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1jchjRubhB ioctl to execute the instruction on all pages in the virtual EPC.}(hjRhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM hj%hhubh)}(hv``EREMOVE`` can fail for three reasons. Userspace must pay attention to expected failures and handle them as follows:h](jd)}(h ``EREMOVE``h]hEREMOVE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubhk can fail for three reasons. Userspace must pay attention to expected failures and handle them as follows:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj%hhubj)}(hhh](j)}(hX3Page removal will always fail when any thread is running in the enclave to which the page belongs. In this case the ioctl will return ``EBUSY`` independent of whether it has successfully removed some pages; userspace can avoid these failures by preventing execution of any vcpu which maps the virtual EPC. h]h)}(hX2Page removal will always fail when any thread is running in the enclave to which the page belongs. In this case the ioctl will return ``EBUSY`` independent of whether it has successfully removed some pages; userspace can avoid these failures by preventing execution of any vcpu which maps the virtual EPC.h](hPage removal will always fail when any thread is running in the enclave to which the page belongs. In this case the ioctl will return }(hjhhhNhNubjd)}(h ``EBUSY``h]hEBUSY}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubh independent of whether it has successfully removed some pages; userspace can avoid these failures by preventing execution of any vcpu which maps the virtual EPC.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hX Page removal will cause a general protection fault if two calls to ``EREMOVE`` happen concurrently for pages that refer to the same "SECS" metadata pages. This can happen if there are concurrent invocations to ``SGX_IOC_VEPC_REMOVE_ALL``, or if a ``/dev/sgx_vepc`` file descriptor in the guest is closed at the same time as ``SGX_IOC_VEPC_REMOVE_ALL``; it will also be reported as ``EBUSY``. This can be avoided in userspace by serializing calls to the ioctl() and to close(), but in general it should not be a problem. h]h)}(hXPage removal will cause a general protection fault if two calls to ``EREMOVE`` happen concurrently for pages that refer to the same "SECS" metadata pages. This can happen if there are concurrent invocations to ``SGX_IOC_VEPC_REMOVE_ALL``, or if a ``/dev/sgx_vepc`` file descriptor in the guest is closed at the same time as ``SGX_IOC_VEPC_REMOVE_ALL``; it will also be reported as ``EBUSY``. This can be avoided in userspace by serializing calls to the ioctl() and to close(), but in general it should not be a problem.h](hCPage removal will cause a general protection fault if two calls to }(hjhhhNhNubjd)}(h ``EREMOVE``h]hEREMOVE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubh happen concurrently for pages that refer to the same “SECS” metadata pages. This can happen if there are concurrent invocations to }(hjhhhNhNubjd)}(h``SGX_IOC_VEPC_REMOVE_ALL``h]hSGX_IOC_VEPC_REMOVE_ALL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubh , or if a }(hjhhhNhNubjd)}(h``/dev/sgx_vepc``h]h /dev/sgx_vepc}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubh< file descriptor in the guest is closed at the same time as }(hjhhhNhNubjd)}(h``SGX_IOC_VEPC_REMOVE_ALL``h]hSGX_IOC_VEPC_REMOVE_ALL}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubh; it will also be reported as }(hjhhhNhNubjd)}(h ``EBUSY``h]hEBUSY}(hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1jchjubh. This can be avoided in userspace by serializing calls to the ioctl() and to close(), but in general it should not be a problem.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hXzFinally, page removal will fail for SECS metadata pages which still have child pages. Child pages can be removed by executing ``SGX_IOC_VEPC_REMOVE_ALL`` on all ``/dev/sgx_vepc`` file descriptors mapped into the guest. This means that the ioctl() must be called twice: an initial set of calls to remove child pages and a subsequent set of calls to remove SECS pages. The second set of calls is only required for those mappings that returned a nonzero value from the first call. It indicates a bug in the kernel or the userspace client if any of the second round of ``SGX_IOC_VEPC_REMOVE_ALL`` calls has a return code other than 0.h]h)}(hXzFinally, page removal will fail for SECS metadata pages which still have child pages. Child pages can be removed by executing ``SGX_IOC_VEPC_REMOVE_ALL`` on all ``/dev/sgx_vepc`` file descriptors mapped into the guest. This means that the ioctl() must be called twice: an initial set of calls to remove child pages and a subsequent set of calls to remove SECS pages. The second set of calls is only required for those mappings that returned a nonzero value from the first call. It indicates a bug in the kernel or the userspace client if any of the second round of ``SGX_IOC_VEPC_REMOVE_ALL`` calls has a return code other than 0.h](hFinally, page removal will fail for SECS metadata pages which still have child pages. Child pages can be removed by executing }(hjUhhhNhNubjd)}(h``SGX_IOC_VEPC_REMOVE_ALL``h]hSGX_IOC_VEPC_REMOVE_ALL}(hj]hhhNhNubah}(h]h ]h"]h$]h&]uh1jchjUubh on all }(hjUhhhNhNubjd)}(h``/dev/sgx_vepc``h]h /dev/sgx_vepc}(hjohhhNhNubah}(h]h ]h"]h$]h&]uh1jchjUubhX file descriptors mapped into the guest. This means that the ioctl() must be called twice: an initial set of calls to remove child pages and a subsequent set of calls to remove SECS pages. The second set of calls is only required for those mappings that returned a nonzero value from the first call. It indicates a bug in the kernel or the userspace client if any of the second round of }(hjUhhhNhNubjd)}(h``SGX_IOC_VEPC_REMOVE_ALL``h]hSGX_IOC_VEPC_REMOVE_ALL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jchjUubh& calls has a return code other than 0.}(hjUhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM%hjQubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]h ]h"]h$]h&]jjjhjjuh1jhj%hhhhhMubeh}(h] virtual-epcah ]h"] virtual epcah$]h&]uh1hhhhhhhhKubeh}(h]software-guard-extensions-sgxah ]h"]software guard extensions (sgx)ah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjerror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourcehnj _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(jjjjjIjFjjjAj>jjjj jMjJjjjjj\jYjjjjjCj@jjj{jxjjj"jjjjju nametypes}(jjjIjjAjjjMjjj\jjjCjj{jj"jjuh}(jhjhjFjjjj>jjjLj j]jjj\jaj j j j jJjj>jCjjjj jjPjjjjjYj*jj_jjj@jjjFjxjWjj~jjjjjj%u footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}Rparse_messages]transform_messages] transformerN include_log] decorationNhhub.