# EMODPR — Restrict the Permissions of an EPC Page

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.

## Instruction Operand Encoding ¶

Op/En | EAX | RBX | RCX
IR | EMODPR (In) | Return Error Code (Out) | Address of a SECINFO (In) | Address of the destination EPC page (In)

### Description ¶

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.

## EMODPR Memory Parameter Semantics ¶

SECINFO | EPCPAGE
Read access permitted by Non Enclave | Read/Write access permitted by Enclave

The instruction faults if any of the following:

## EMODPR Faulting Conditions ¶

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 38-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.

Table 38-31. EMODPR Return Value in RAX

### Concurrency Restrictions ¶

Leaf | Parameter | Base Concurrency Restrictions
--- | --- | ---
| On Conflict |
EMODPR EMODPR Target [DS:RCX] Shared EMODPR Target [DS:RCX] | Target [DS:RCX] |  |  |

Table 38-32. Base Concurrency Restrictions of EMODPR

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 |

Table 38-33. Additional Concurrency Restrictions of EMODPR

### Operation ¶

## Temp Variables in EMODPR Operational Flow ¶

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;

### Flags Affected ¶

Sets ZF if page is not modifiable or if other SGX2 instructions are executing concurrently, otherwise cleared. Clears CF, PF, AF, OF, SF.

### Protected Mode Exceptions ¶

#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.

### 64-Bit Mode Exceptions ¶

#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.