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]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.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh)}(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&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubeh}(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}(hj7hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh block_quote)}(h``grep sgx /proc/cpuinfo`` h]h)}(h``grep sgx /proc/cpuinfo``h]hliteral)}(hjMh]hgrep sgx /proc/cpuinfo}(hjQhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjKubah}(h]h ]h"]h$]h&]uh1hhhhKhjGubah}(h]h ]h"]h$]h&]uh1jEhhhKhhhhubh)}(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”.}(hjjhhhNhNubah}(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.}(hj hhhNhNubah}(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)}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj)ubah}(h]h ]h"]h$]h&]uh1jhhhK8hj%ubj)}(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.}(hjChhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK8hj@ubah}(h]h ]h"]h$]h&]uh1jhj%ubeh}(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)}(hjch]hThread Control Structure (TCS)}(hjehhhNhNubah}(h]h ]h"]h$]h&]uh1jhjaubah}(h]h ]h"]h$]h&]uh1jhhhK h]h<-EACCES: The source page is located in a noexec partition.}(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&]uh1hhj! ubh)}(h-ENOMEM: Out of EPC pages.h]h)}(hjV h]h-ENOMEM: Out of EPC pages.}(hjX hhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjT ubah}(h]h ]h"]h$]h&]uh1hhj! ubh)}(h>-EINTR: The call was interrupted before data was processed.h]h)}(hjn h]h>-EINTR: The call was interrupted before data was processed.}(hjp hhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjl ubah}(h]h ]h"]h$]h&]uh1hhj! ubh)}(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&]uh1hhj! ubh)}(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&]uh1hhj! ubeh}(h]h ]h"]h$]h&]j'j4uh1hhj5 hMhjubeh}(h]h ] kernelindentah"]h$]h&]uh1j hjIhhhNhNubj{)}(hhh]h}(h]h ]h"]h$]h&]entries](j!sgx_ioc_enclave_init (C function)c.sgx_ioc_enclave_inithNtauh1jzhjIhhhNhNubj)}(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.chMWubj)}(h h]h }(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj hhhj hMWubj)}(hsgx_ioc_enclave_inith]j)}(hsgx_ioc_enclave_inith]hsgx_ioc_enclave_init}(hj' hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj# ubah}(h]h ](jjeh"]h$]h&]hhuh1jhj hhhj hMWubj)}(h)(struct sgx_encl *encl, void __user *arg)h](j)}(hstruct sgx_encl *enclh](j)}(hjh]hstruct}(hjC hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj? ubj)}(h h]h }(hjP hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj? ubh)}(hhh]j)}(hsgx_enclh]hsgx_encl}(hja hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj^ ubah}(h]h ]h"]h$]h&] refdomainj!reftypej# reftargetjc modnameN classnameNj'j*)}j-]j0)}j#j) sbc.sgx_ioc_enclave_initasbuh1hhj? ubj)}(h h]h }(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj? ubjD)}(hj(h]h*}(hj hhhNhNubah}(h]h ]jOah"]h$]h&]uh1jChj? ubj)}(henclh]hencl}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj? ubeh}(h]h ]h"]h$]h&]noemphhhuh1jhj; 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 ubjD)}(hj(h]h*}(hj hhhNhNubah}(h]h ]jOah"]h$]h&]uh1jChj ubj)}(hargh]harg}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]noemphhhuh1jhj; ubeh}(h]h ]h"]h$]h&]hhuh1jhj hhhj hMWubeh}(h]h ]h"]h$]h&]hhjuh1jjjhj hhhj hMWubah}(h]j ah ](jjeh"]h$]h&]jj)jhuh1jhj hMWhj hhubj)}(hhh]h)}(h$handler for ``SGX_IOC_ENCLAVE_INIT``h](h handler for }(hj hhhNhNubjP)}(h``SGX_IOC_ENCLAVE_INIT``h]hSGX_IOC_ENCLAVE_INIT}(hj" hhhNhNubah}(h]h ]h"]h$]h&]uh1jOhj ubeh}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMIhj hhubah}(h]h ]h"]h$]h&]uh1jhj hhhj hMWubeh}(h]h ](j!functioneh"]h$]h&]jj!jj@ jj@ jj j uh1jhhhjIhNhNubj )}(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)}(hjJ h]h Parameters}(hjL hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjH ubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMMhjD ubj)}(hhh](j)}(h-``struct sgx_encl *encl`` an enclave pointer h](j)}(h``struct sgx_encl *encl``h]jP)}(hji h]hstruct sgx_encl *encl}(hjk hhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjg ubah}(h]h ]h"]h$]h&]uh1jh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMJhjc ubj)}(hhh]h)}(han enclave pointerh]han enclave pointer}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj~ hMJhj ubah}(h]h ]h"]h$]h&]uh1jhjc ubeh}(h]h ]h"]h$]h&]uh1jhj~ hMJhj` ubj)}(hM``void __user *arg`` userspace pointer to a struct sgx_enclave_init instance h](j)}(h``void __user *arg``h]jP)}(hj h]hvoid __user *arg}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jOhj ubah}(h]h ]h"]h$]h&]uh1jh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMKhj 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 hMKhj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj hMKhj` ubeh}(h]h ]h"]h$]h&]uh1jhjD 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.chMMhjD 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.chMMhjD 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.chMQhjD ubh)}(hhh](h)}(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.chMQhj ubah}(h]h ]h"]h$]h&]uh1hhj ubh)}(h-EPERM: Invalid SIGSTRUCT.h]h)}(hj7 h]h-EPERM: Invalid SIGSTRUCT.}(hj9 hhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMRhj5 ubah}(h]h ]h"]h$]h&]uh1hhj ubh)}(h1-EIO: EINIT failed because of a power cycle.h]h)}(hjO h]h1-EIO: EINIT failed because of a power cycle.}(hjQ hhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMShjM ubah}(h]h ]h"]h$]h&]uh1hhj ubh)}(h-errno: POSIX error.h]h)}(hjg h]h-errno: POSIX error.}(hji hhhNhNubah}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMThje ubah}(h]h ]h"]h$]h&]uh1hhj ubeh}(h]h ]h"]h$]h&]j'j4uh1hhj. hMQhjD ubeh}(h]h ] kernelindentah"]h$]h&]uh1j hjIhhhNhNubj{)}(hhh]h}(h]h ]h"]h$]h&]entries](j&sgx_ioc_enclave_provision (C function)c.sgx_ioc_enclave_provisionhNtauh1jzhjIhhhNhNubj)}(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.chMubj)}(h h]h }(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj hhhj hMubj)}(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 hMubj)}(h)(struct sgx_encl *encl, void __user *arg)h](j)}(hstruct sgx_encl *enclh](j)}(hjh]hstruct}(hj hhhNhNubah}(h]h ]jah"]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&] refdomainj!reftypej# reftargetj modnameN classnameNj'j*)}j-]j0)}j#j sbc.sgx_ioc_enclave_provisionasbuh1hhj ubj)}(h h]h }(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj ubjD)}(hj(h]h*}(hj, hhhNhNubah}(h]h ]jOah"]h$]h&]uh1jChj ubj)}(henclh]hencl}(hj9 hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]noemphhhuh1jhj ubj)}(hvoid __user *argh](j)}(hvoidh]hvoid}(hjR hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjN ubj)}(h h]h }(hj` hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjN ubh__user}(hjN hhhNhNubj)}(h h]h }(hjr hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjN ubjD)}(hj(h]h*}(hj hhhNhNubah}(h]h ]jOah"]h$]h&]uh1jChjN ubj)}(hargh]harg}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjN ubeh}(h]h ]h"]h$]h&]noemphhhuh1jhj ubeh}(h]h ]h"]h$]h&]hhuh1jhj hhhj hMubeh}(h]h ]h"]h$]h&]hhjuh1jjjhj hhhj hMubah}(h]j ah ](jjeh"]h$]h&]jj)jhuh1jhj hMhj hhubj)}(hhh]h)}(h)handler for ``SGX_IOC_ENCLAVE_PROVISION``h](h handler for }(hj hhhNhNubjP)}(h``SGX_IOC_ENCLAVE_PROVISION``h]hSGX_IOC_ENCLAVE_PROVISION}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jOhj ubeh}(h]h ]h"]h$]h&]uh1hh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMhj hhubah}(h]h ]h"]h$]h&]uh1jhj hhhj hMubeh}(h]h ](j!functioneh"]h$]h&]jj!jj jj jj j uh1jhhhjIhNhNubj )}(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.chMhj ubj)}(hhh](j)}(h-``struct sgx_encl *encl`` an enclave pointer h](j)}(h``struct sgx_encl *encl``h]jP)}(hjh]hstruct sgx_encl *encl}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjubah}(h]h ]h"]h$]h&]uh1jh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./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&]uh1jhjhMhj ubj)}(hR``void __user *arg`` userspace pointer to a struct sgx_enclave_provision instance h](j)}(h``void __user *arg``h]jP)}(hj?h]hvoid __user *arg}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhj=ubah}(h]h ]h"]h$]h&]uh1jh\/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:97: ./arch/x86/kernel/cpu/sgx/ioctl.chMhj9ubj)}(hhh]h)}(hhjHhhubah}(h]h ]h"]h$]h&]uh1jhj,hhhjEhMQubeh}(h]h ](j!functioneh"]h$]h&]jj!jjqjjqjj j uh1jhhhjhNhNubj )}(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)}(hj{h]h Parameters}(hj}hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjyubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMBhjuubj)}(hhh](j)}(h-``struct sgx_encl *encl`` an enclave pointer h](j)}(h``struct sgx_encl *encl``h]jP)}(hjh]hstruct sgx_encl *encl}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjubah}(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]jP)}(hjh]hvoid __user *arg}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjubah}(h]h ]h"]h$]h&]uh1jh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMBhjubj)}(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]jP)}(hjh]h'struct sgx_enclave_restrict_permissions}(hjhhhNhNubah}(h]h ](xrefj!c-typeeh"]h$]h&]uh1jOhjubah}(h]h ]h"]h$]h&]refdoc arch/x86/sgx refdomainj!reftypetype refexplicitrefwarnj'j*)}j-]sb reftarget sgx_enclave_restrict_permissionsuh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMAhjubh instance}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMAhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhMBhjubeh}(h]h ]h"]h$]h&]uh1jhjuubh)}(h**Description**h]j)}(hj8h]h Description}(hj:hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj6ubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMDhjuubh)}(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).}(hjNhhhNhNubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMDhjuubh)}(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.}(hj]hhhNhNubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMHhjuubh)}(h **Return**h]j)}(hjnh]hReturn}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1jhjlubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMMhjuubh)}(hhh](h)}(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.chMMhjubah}(h]h ]h"]h$]h&]uh1hhjubh)}(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.chMNhjubah}(h]h ]h"]h$]h&]uh1hhjubeh}(h]h ]h"]h$]h&]j'j4uh1hhjhMMhjuubeh}(h]h ] kernelindentah"]h$]h&]uh1j hjhhhNhNubj{)}(hhh]h}(h]h ]h"]h$]h&]entries](j)sgx_ioc_enclave_modify_types (C function)c.sgx_ioc_enclave_modify_typeshNtauh1jzhjhhhNhNubj)}(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.chM"ubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjhhhjhM"ubj)}(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&]hhuh1jhjhhhjhM"ubj)}(h)(struct sgx_encl *encl, void __user *arg)h](j)}(hstruct sgx_encl *enclh](j)}(hjh]hstruct}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubj)}(h h]h }(hj'hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubh)}(hhh]j)}(hsgx_enclh]hsgx_encl}(hj8hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj5ubah}(h]h ]h"]h$]h&] refdomainj!reftypej# reftargetj:modnameN classnameNj'j*)}j-]j0)}j#jsbc.sgx_ioc_enclave_modify_typesasbuh1hhjubj)}(h h]h }(hjXhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubjD)}(hj(h]h*}(hjfhhhNhNubah}(h]h ]jOah"]h$]h&]uh1jChjubj)}(henclh]hencl}(hjshhhNhNubah}(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&]uh1jhjubjD)}(hj(h]h*}(hjhhhNhNubah}(h]h ]jOah"]h$]h&]uh1jChjubj)}(hargh]harg}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]noemphhhuh1jhjubeh}(h]h ]h"]h$]h&]hhuh1jhjhhhjhM"ubeh}(h]h ]h"]h$]h&]hhjuh1jjjhjhhhjhM"ubah}(h]jah ](jjeh"]h$]h&]jj)jhuh1jhjhM"hjhhubj)}(hhh]h)}(h,handler for ``SGX_IOC_ENCLAVE_MODIFY_TYPES``h](h handler for }(hjhhhNhNubjP)}(h ``SGX_IOC_ENCLAVE_MODIFY_TYPES``h]hSGX_IOC_ENCLAVE_MODIFY_TYPES}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjubeh}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chM hjhhubah}(h]h ]h"]h$]h&]uh1jhjhhhjhM"ubeh}(h]h ](j!functioneh"]h$]h&]jj!jjjjjj j uh1jhhhjhNhNubj )}(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)}(hj!h]h Parameters}(hj#hhhNhNubah}(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.chMhjubj)}(hhh](j)}(h-``struct sgx_encl *encl`` an enclave pointer h](j)}(h``struct sgx_encl *encl``h]jP)}(hj@h]hstruct sgx_encl *encl}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhj>ubah}(h]h ]h"]h$]h&]uh1jh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chM hj:ubj)}(hhh]h)}(han enclave pointerh]han enclave pointer}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjUhM hjVubah}(h]h ]h"]h$]h&]uh1jhj:ubeh}(h]h ]h"]h$]h&]uh1jhjUhM hj7ubj)}(hz``void __user *arg`` userspace pointer to a :c:type:`struct sgx_enclave_modify_types ` instance h](j)}(h``void __user *arg``h]jP)}(hjyh]hvoid __user *arg}(hj{hhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjwubah}(h]h ]h"]h$]h&]uh1jh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjsubj)}(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]jP)}(hjh]hstruct sgx_enclave_modify_types}(hjhhhNhNubah}(h]h ](jj!c-typeeh"]h$]h&]uh1jOhjubah}(h]h ]h"]h$]h&]refdocj refdomainj!reftypetype refexplicitrefwarnj'jjsgx_enclave_modify_typesuh1hhjhMhjubh instance}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1jhjsubeh}(h]h ]h"]h$]h&]uh1jhjhMhj7ubeh}(h]h ]h"]h$]h&]uh1jhjubh)}(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.chMhjubh)}(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.chMhjubh)}(hhh](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]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 (}(hjhhhNhNubjP)}(h``SGX_PAGE_TYPE_REG``h]hSGX_PAGE_TYPE_REG}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjubh ) to TCS (}(hjhhhNhNubjP)}(h``SGX_PAGE_TYPE_TCS``h]hSGX_PAGE_TYPE_TCS}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjubhr) 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&]uh1hhjubh)}(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 }(hj@hhhNhNubjP)}(h``SGX_PAGE_TYPE_TRIM``h]hSGX_PAGE_TYPE_TRIM}(hjHhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhj@ubh. Changing the page type to }(hj@hhhNhNubjP)}(h``SGX_PAGE_TYPE_TRIM``h]hSGX_PAGE_TYPE_TRIM}(hjZhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhj@ubhC marks the page for removal with actual removal done by handler of }(hj@hhhNhNubjP)}(h ``SGX_IOC_ENCLAVE_REMOVE_PAGES``h]hSGX_IOC_ENCLAVE_REMOVE_PAGES}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhj@ubh/ ioctl() called after ENCLU[EACCEPT] is run on }(hj@hhhNhNubjP)}(h``SGX_PAGE_TYPE_TRIM``h]hSGX_PAGE_TYPE_TRIM}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1jOhj@ubh page from within the enclave.}(hj@hhhNhNubeh}(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&]uh1hhjubeh}(h]h ]h"]h$]h&]j'j(uh1hhj5hMhjubh)}(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.chMhjubh)}(hhh](h)}(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&]uh1hhjubh)}(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&]uh1hhjubeh}(h]h ]h"]h$]h&]j'j4uh1hhjhMhjubeh}(h]h ] kernelindentah"]h$]h&]uh1j hjhhhNhNubj{)}(hhh]h}(h]h ]h"]h$]h&]entries](j)sgx_ioc_enclave_remove_pages (C function)c.sgx_ioc_enclave_remove_pageshNtauh1jzhjhhhNhNubj)}(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}(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 }(hj#hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjhhhj"hMubj)}(hsgx_ioc_enclave_remove_pagesh]j)}(hsgx_ioc_enclave_remove_pagesh]hsgx_ioc_enclave_remove_pages}(hj5hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj1ubah}(h]h ](jjeh"]h$]h&]hhuh1jhjhhhj"hMubj)}(h)(struct sgx_encl *encl, void __user *arg)h](j)}(hstruct sgx_encl *enclh](j)}(hjh]hstruct}(hjQhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjMubj)}(h h]h }(hj^hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjMubh)}(hhh]j)}(hsgx_enclh]hsgx_encl}(hjohhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjlubah}(h]h ]h"]h$]h&] refdomainj!reftypej# reftargetjqmodnameN classnameNj'j*)}j-]j0)}j#j7sbc.sgx_ioc_enclave_remove_pagesasbuh1hhjMubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjMubjD)}(hj(h]h*}(hjhhhNhNubah}(h]h ]jOah"]h$]h&]uh1jChjMubj)}(henclh]hencl}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjMubeh}(h]h ]h"]h$]h&]noemphhhuh1jhjIubj)}(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&]uh1jhjubjD)}(hj(h]h*}(hjhhhNhNubah}(h]h ]jOah"]h$]h&]uh1jChjubj)}(hargh]harg}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]noemphhhuh1jhjIubeh}(h]h ]h"]h$]h&]hhuh1jhjhhhj"hMubeh}(h]h ]h"]h$]h&]hhjuh1jjjhj hhhj"hMubah}(h]jah ](jjeh"]h$]h&]jj)jhuh1jhj"hMhj hhubj)}(hhh]h)}(h,handler for ``SGX_IOC_ENCLAVE_REMOVE_PAGES``h](h handler for }(hj(hhhNhNubjP)}(h ``SGX_IOC_ENCLAVE_REMOVE_PAGES``h]hSGX_IOC_ENCLAVE_REMOVE_PAGES}(hj0hhhNhNubah}(h]h ]h"]h$]h&]uh1jOhj(ubeh}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhj%hhubah}(h]h ]h"]h$]h&]uh1jhj hhhj"hMubeh}(h]h ](j!functioneh"]h$]h&]jj!jjNjjNjj j uh1jhhhjhNhNubj )}(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)}(hjXh]h Parameters}(hjZhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjVubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjRubj)}(hhh](j)}(h-``struct sgx_encl *encl`` an enclave pointer h](j)}(h``struct sgx_encl *encl``h]jP)}(hjwh]hstruct sgx_encl *encl}(hjyhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjuubah}(h]h ]h"]h$]h&]uh1jh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjqubj)}(hhh]h)}(han enclave pointerh]han enclave pointer}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1jhjqubeh}(h]h ]h"]h$]h&]uh1jhjhMhjnubj)}(hx``void __user *arg`` userspace pointer to :c:type:`struct sgx_enclave_remove_pages ` instance h](j)}(h``void __user *arg``h]jP)}(hjh]hvoid __user *arg}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjubah}(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]jP)}(hjh]hstruct sgx_enclave_remove_pages}(hjhhhNhNubah}(h]h ](jj!c-typeeh"]h$]h&]uh1jOhjubah}(h]h ]h"]h$]h&]refdocj refdomainj!reftypetype refexplicitrefwarnj'jjsgx_enclave_remove_pagesuh1hhjhMhjubh instance}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhMhjnubeh}(h]h ]h"]h$]h&]uh1jhjRubh)}(h**Description**h]j)}(hjh]h Description}(hjhhhNhNubah}(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.chMhjRubh)}(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:}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjRubjp)}(hhh](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]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 }(hj:hhhNhNubjP)}(h``SGX_PAGE_TYPE_TRIM``h]hSGX_PAGE_TYPE_TRIM}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhj:ubh using the }(hj:hhhNhNubjP)}(h ``SGX_IOC_ENCLAVE_MODIFY_TYPES``h]hSGX_IOC_ENCLAVE_MODIFY_TYPES}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1jOhj:ubh ioctl().}(hj:hhhNhNubeh}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhj6ubah}(h]h ]h"]h$]h&]uh1hhj3ubh)}(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.}(hjwhhhNhNubah}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:113: ./arch/x86/kernel/cpu/sgx/ioctl.chMhjsubah}(h]h ]h"]h$]h&]uh1hhj3ubh)}(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 }(hjhhhNhNubjP)}(h ``SGX_IOC_ENCLAVE_REMOVE_PAGES``h]hSGX_IOC_ENCLAVE_REMOVE_PAGES}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjubh 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&]uh1hhj3ubeh}(h]h ]h"]h$]h&]jjjhj)uh1johjRubh)}(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.chMhjRubh)}(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.chMhjRubh)}(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.chMhjRubh)}(hhh](h)}(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&]uh1hhjubh)}(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&]uh1hhjubeh}(h]h ]h"]h$]h&]j'j4uh1hhjhMhjRubeh}(h]h ] kernelindentah"]h$]h&]uh1j hjhhhNhNubeh}(h]enclave-runtime-managementah ]h"]enclave runtime managementah$]h&]uh1hhj8hhhhhKhubh)}(hhh](h)}(h Enclave vDSOh]h Enclave vDSO}(hj?hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj<hhhhhKwubh)}(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.}(hjMhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKyhj<hhubh)}(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.}(hj[hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj<hhubh)}(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.}(hjihhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj<hhubj{)}(hhh]h}(h]h ]h"]h$]h&]entries](j"vdso_sgx_enter_enclave_t (C macro)c.vdso_sgx_enter_enclave_thNtauh1jzhj<hhhNhNubj)}(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 ](j!macroeh"]h$]h&]jj!jjjjjj j uh1jhhhj<hNhNubh)}(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.hhKhj<hhubjF)}(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]jP)}(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&]uh1jOhjubah}(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&]uh1jEhjhKhj<hhubj )}(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. **Description** 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)}(hj!h]h Parameters}(hj#hhhNhNubah}(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.hhKhjubj)}(hhh](j)}(h1``unsigned long rdi`` Pass-through value for RDI h](j)}(h``unsigned long rdi``h]jP)}(hj@h]hunsigned long rdi}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhj>ubah}(h]h ]h"]h$]h&]uh1jh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhj:ubj)}(hhh]h)}(hPass-through value for RDIh]hPass-through value for RDI}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjUhKhjVubah}(h]h ]h"]h$]h&]uh1jhj:ubeh}(h]h ]h"]h$]h&]uh1jhjUhKhj7ubj)}(h1``unsigned long rsi`` Pass-through value for RSI h](j)}(h``unsigned long rsi``h]jP)}(hjyh]hunsigned long rsi}(hj{hhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjwubah}(h]h ]h"]h$]h&]uh1jh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhjsubj)}(hhh]h)}(hPass-through value for RSIh]hPass-through value for RSI}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubah}(h]h ]h"]h$]h&]uh1jhjsubeh}(h]h ]h"]h$]h&]uh1jhjhKhj7ubj)}(h1``unsigned long rdx`` Pass-through value for RDX h](j)}(h``unsigned long rdx``h]jP)}(hjh]hunsigned long rdx}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjubah}(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&]uh1jhjhKhj7ubj)}(hD``unsigned int function`` ENCLU function, must be EENTER or ERESUME h](j)}(h``unsigned int function``h]jP)}(hjh]hunsigned int function}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjubah}(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&]uh1jhjhKhj7ubj)}(h/``unsigned long r8`` Pass-through value for R8 h](j)}(h``unsigned long r8``h]jP)}(hj$h]hunsigned long r8}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1jOhj"ubah}(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 R8h]hPass-through value for R8}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj9hKhj:ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhj9hKhj7ubj)}(h/``unsigned long r9`` Pass-through value for R9 h](j)}(h``unsigned long r9``h]jP)}(hj]h]hunsigned long r9}(hj_hhhNhNubah}(h]h ]h"]h$]h&]uh1jOhj[ubah}(h]h ]h"]h$]h&]uh1jh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhjWubj)}(hhh]h)}(hPass-through value for R9h]hPass-through value for R9}(hjvhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjrhKhjsubah}(h]h ]h"]h$]h&]uh1jhjWubeh}(h]h ]h"]h$]h&]uh1jhjrhKhj7ubj)}(hI``struct sgx_enclave_run *run`` struct sgx_enclave_run, must be non-NULL h](j)}(h``struct sgx_enclave_run *run``h]jP)}(hjh]hstruct sgx_enclave_run *run}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjubah}(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&]uh1jhjhKhj7ubeh}(h]h ]h"]h$]h&]uh1jhjubh)}(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.hhKhjubh)}(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.hhKhjubh)}(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:138: ./arch/x86/include/uapi/asm/sgx.hhKhjubh)}(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 }(hjhhhNhNubj)}(h **function**h]hfunction}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh!, asynchronous exit pointer, and }(hjhhhNhNubj)}(h **run.tcs**h]hrun.tcs}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh respectively.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhjubh)}(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 }(hjAhhhNhNubj)}(h**run.exception**h]h run.exception}(hjIhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjAubh and }(hjAhhhNhNubj)}(h**run.user_handler**h]hrun.user_handler}(hj[hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjAubh 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).}(hjAhhhNhNubeh}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhjubh)}(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 }(hjthhhNhNubj)}(h**run.exception**h]h run.exception}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjtubh,, the optional sgx_enclave_exception struct.}(hjthhhNhNubeh}(h]h ]h"]h$]h&]uh1hh]/var/lib/git/docbuild/linux/Documentation/arch/x86/sgx:138: ./arch/x86/include/uapi/asm/sgx.hhKhjubh)}(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.hhKhjubh)}(hhh](h)}(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&]uh1hhjubh)}(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&]uh1hhjubeh}(h]h ]h"]h$]h&]j'j4uh1hhjhKhjubeh}(h]h ] kernelindentah"]h$]h&]uh1j hj<hhhNhNubeh}(h] enclave-vdsoah ]h"] enclave vdsoah$]h&]uh1hhj8hhhhhKwubeh}(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 }(hjhhhNhNubj)}(h*ksgxd*h]hksgxd}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hhh](h)}(hEPC sanitizationh]hEPC sanitization}(hj1hhhNhNubah}(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.}(hjMhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj.hhubeh}(h]epc-sanitizationah ]h"]epc sanitizationah$]h&]uh1hhjhhhhhKubh)}(hhh](h)}(hPage reclaimerh]hPage reclaimer}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjchhhhhKubh)}(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, }(hjthhhNhNubj)}(h*ksgxd*h]hksgxd}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjtubh- “swaps” enclave memory to normal memory.}(hjthhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjchhubeh}(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.}(hj hhhNhNubah}(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).}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]encryption-enginesah ]h"]encryption enginesah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h Usage Modelsh]h Usage Models}(hjMhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjJhhhhhKubh)}(hhh](h)}(hShared Libraryh]hShared Library}(hj^hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj[hhhhhKubh)}(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.}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj[hhubeh}(h]shared-libraryah ]h"]shared libraryah$]h&]uh1hhjJhhhhhKubh)}(hhh](h)}(hApplication Containerh]hApplication Container}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(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&]uh1hhhhKhjhhubeh}(h]application-containerah ]h"]application containerah$]h&]uh1hhjJhhhhhKubeh}(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.}(hj hhhNhNubah}(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.}(hj:hhhNhNubah}(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.}(hjHhhhNhNubah}(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 }(hjVhhhNhNubjP)}(h``ENCLS[EREMOVE]``h]hENCLS[EREMOVE]}(hj^hhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjVubh instruction, }(hjVhhhNhNubjP)}(h``/dev/sgx_vepc``h]h /dev/sgx_vepc}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjVubh provides the }(hjVhhhNhNubjP)}(h``SGX_IOC_VEPC_REMOVE_ALL``h]hSGX_IOC_VEPC_REMOVE_ALL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjVubhB ioctl to execute the instruction on all pages in the virtual EPC.}(hjVhhhNhNubeh}(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](jP)}(h ``EREMOVE``h]hEREMOVE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjubhk can fail for three reasons. Userspace must pay attention to expected failures and handle them as follows:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj)hhubjp)}(hhh](h)}(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 }(hjhhhNhNubjP)}(h ``EBUSY``h]hEBUSY}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjubh 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&]uh1hhjhhhhhNubh)}(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 }(hjhhhNhNubjP)}(h ``EREMOVE``h]hEREMOVE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjubh happen concurrently for pages that refer to the same “SECS” metadata pages. This can happen if there are concurrent invocations to }(hjhhhNhNubjP)}(h``SGX_IOC_VEPC_REMOVE_ALL``h]hSGX_IOC_VEPC_REMOVE_ALL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjubh , or if a }(hjhhhNhNubjP)}(h``/dev/sgx_vepc``h]h /dev/sgx_vepc}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjubh< file descriptor in the guest is closed at the same time as }(hjhhhNhNubjP)}(h``SGX_IOC_VEPC_REMOVE_ALL``h]hSGX_IOC_VEPC_REMOVE_ALL}(hj%hhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjubh; it will also be reported as }(hjhhhNhNubjP)}(h ``EBUSY``h]hEBUSY}(hj7hhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjubh. 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&]uh1hhjhhhhhNubh)}(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 }(hjYhhhNhNubjP)}(h``SGX_IOC_VEPC_REMOVE_ALL``h]hSGX_IOC_VEPC_REMOVE_ALL}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjYubh on all }(hjYhhhNhNubjP)}(h``/dev/sgx_vepc``h]h /dev/sgx_vepc}(hjshhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjYubhX 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 }(hjYhhhNhNubjP)}(h``SGX_IOC_VEPC_REMOVE_ALL``h]hSGX_IOC_VEPC_REMOVE_ALL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jOhjYubh& calls has a return code other than 0.}(hjYhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM%hjUubah}(h]h ]h"]h$]h&]uh1hhjhhhhhNubeh}(h]h ]h"]h$]h&]jjjhjjuh1johj)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_sourceh _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}(jjj}jzj5j2jjj-j*jjjjj9j6jjjjj`j]jjjjjGjDjjjj|jjj&j#jjjju nametypes}(jj}j5jj-jjj9jjj`jjjGjjjj&jjuh}(jhjzhj2jjjj*jjj8jjIjjjHjMj j j j j6jj*j/jjjj jj<jjjjj]j.jjcjjjDjjjJj|j[jjj#jjjjj)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.