Opcode/Instruction | Op/En | 64/32 bit Mode Support | CPUID Feature Flag | Description |
---|---|---|---|---|
EAX = 0EH ENCLS[EMODPR] | IR | V/V | SGX2 | This leaf function restricts the access rights associated with a EPC page in an initialized enclave. |
Op/En | EAX | RBX | RCX | |
IR | EMODPR (In) | Return Error Code (Out) | Address of a SECINFO (In) | Address of the destination EPC page (In) |
This leaf function restricts the access rights associated with an EPC page in an initialized enclave. THE RWX bits of the SECINFO parameter are treated as a permissions mask; supplying a value that does not restrict the page permissions will have no effect. This instruction can only be executed when current privilege level is 0.
RBX contains the effective address of a SECINFO structure while RCX contains the effective address of an EPC page. The table below provides additional information on the memory parameter of the EMODPR leaf function.
SECINFO | EPCPAGE |
Read access permitted by Non Enclave | Read/Write access permitted by Enclave |
The instruction faults if any of the following:
The operands are not properly aligned. | If unsupported security attributes are set. |
The Enclave is not initialized. | SECS is locked by another thread. |
The EPC page is locked by another thread. | RCX does not contain an effective address of an EPC page in the running enclave. |
The EPC page is not valid. |
The error codes are:
Error Code (see Table 40-4) | Description |
---|---|
No Error | EMODPR successful. |
SGX_PAGE_NOT_MODIFIABLE | The EPC page cannot be modified because it is in the PENDING or MODIFIED state. |
SGX_EPC_PAGE_CONFLICT | Page is being written by EADD, EAUG, ECREATE, ELDU/B, EMODT, or EWB. |
Leaf | Parameter | Base Concurrency Restrictions | ||
---|---|---|---|---|
Access | On Conflict | SGX_CONFLICT VM Exit Qualification | ||
EMODPR | Target [DS:RCX] | Shared | #GP |
Leaf | Parameter | Additional Concurrency Restrictions | |||||
---|---|---|---|---|---|---|---|
vs. EACCEPT, EACCEPTCOPY, EMODPE, EMODPR, EMODT | vs. EADD, EEXTEND, EINIT | vs. ETRACK, ETRACKC | |||||
Access | On Conflict | Access | On Conflict | Access | On Conflict | ||
EMODPR | Target [DS:RCX] | Exclusive | SGX_EPC_PAGE _CONFLICT | Concurrent | Concurrent |
Name | Type | Size (bits) | Description |
---|---|---|---|
TMP_SECS | Effective Address | 32/64 | Physical address of SECS to which EPC operand belongs. |
SCRATCH_SECINFO | SECINFO | 512 | Scratch storage for holding the contents of DS:RBX. |
IF (DS:RBX is not 64Byte Aligned)
THEN #GP(0); FI;
IF (DS:RCX is not 4KByte Aligned)
THEN #GP(0); FI;
IF (DS:RCX does not resolve within an EPC)
THEN #PF(DS:RCX); FI;
SCRATCH_SECINFO ← DS:RBX;
(* Check for misconfigured SECINFO flags*)
IF ( (SCRATCH_SECINFO reserved fields are not zero ) or
(SCRATCH_SECINFO.FLAGS.R is 0 and SCRATCH_SECINFO.FLAGS.W is not 0) )
THEN #GP(0); FI;
(* Check concurrency with SGX1 or SGX2 instructions on the EPC page *)
IF (SGX1 or other SGX2 instructions accessing EPC page)
THEN #GP(0); FI;
IF (EPCM(DS:RCX).VALID is 0 )
THEN #PF(DS:RCX); FI;
(* Check the EPC page for concurrency *)
IF (EPC page in use by another SGX2 instruction)
THEN
RFLAGS.ZF ← 1;
RAX ← SGX_EPC_PAGE_CONFLICT;
GOTO DONE;
FI;
IF (EPCM(DS:RCX).PENDING is not 0 or (EPCM(DS:RCX).MODIFIED is not 0) )
THEN
RFLAGS.ZF ← 1;
RAX ← SGX_PAGE_NOT_MODIFIABLE;
GOTO DONE;
FI;
IF (EPCM(DS:RCX).PT is not PT_REG)
THEN #PF(DS:RCX); FI;
TMP_SECS ← GET_SECS_ADDRESS
IF (TMP_SECS.ATTRIBUTES.INIT = 0)
THEN #GP(0); FI;
(* Set the PR bit to indicate that permission restriction is in progress *)
EPCM(DS:RCX).PR ← 1;
(* Update EPCM permissions *)
EPCM(DS:RCX).R←EPCM(DS:RCX).R & SCRATCH_SECINFO.FLAGS.R;
EPCM(DS:RCX).W←EPCM(DS:RCX).W & SCRATCH_SECINFO.FLAGS.W;
EPCM(DS:RCX).X←EPCM(DS:RCX).X & SCRATCH_SECINFO.FLAGS.X;
RFLAGS.ZF ← 0;
RAX←0;
DONE:
RFLAGS.CF,PF,AF,OF,SF ← 0;
Sets ZF if page is not modifiable or if other SGX2 instructions are executing concurrently, otherwise cleared. Clears CF, PF, AF, OF, SF.
#GP(0) | If a memory operand effective address is outside the DS segment limit. |
If a memory operand is not properly aligned. | |
If a memory operand is locked. | |
#PF(error | code) If a page fault occurs in accessing memory operands. |
If a memory operand is not an EPC page. |
#GP(0) | If a memory operand is non-canonical form. |
If a memory operand is not properly aligned. | |
If a memory operand is locked. | |
#PF(error | code) If a page fault occurs in accessing memory operands. |
If a memory operand is not an EPC page. |