Opcode/Instruction | Op/En | 64/32 bit Mode Support | CPUID Feature Flag | Description |
---|---|---|---|---|
EAX = 10H ENCLS[ERDINFO] | IR | V/V | EAX[6] | This leaf function returns type and status information about an EPC page. |
Op/En | EAX | RBX | RCX | |
IR | ERDINFO (In) | Return error code (Out) | Address of a RDINFO structure (In) | Address of the destination EPC page (In) |
This instruction reads type and status information about an EPC page and returns it in a RDINFO structure. The STATUS field of the structure describes the status of the page and determines the validity of the remaining fields. The FLAGS field returns the EPCM permissions of the page; the page type; and the BLOCKED, PENDING, MODIFIED, and PR status of the page. For enclave pages, the ENCLAVECONTEXT field of the structure returns the value of SECS.ENCLAVECONTEXT. For non-enclave pages (e.g., VA) ENCLAVECONTEXT returns 0.
For invalid or non-EPC pages, the instruction returns an information code indicating the page's status, in addition to populating the STATUS field.
ERDINFO returns an error code if the destination EPC page is being modified by a concurrent SGX instruction.
RBX contains the effective address of a RDINFO structure while RCX contains the effective address of an EPC page. The table below provides additional information on the memory parameter of ERDINFO leaf function.
RDINFO | EPCPAGE |
Read/Write access permitted by Non Enclave | Read access permitted by Enclave |
The instruction faults if any of the following:
A memory operand effective address is outside the DS segment limit (32b mode). | A memory operand is not properly aligned. |
DS segment is unusable (32b mode). | A page fault occurs in accessing memory operands. |
A memory address is in a non-canonical form (64b mode). |
The error codes are:
Error Code | Value | Description |
---|---|---|
No Error | 0 | ERDINFO successful. |
SGX_EPC_PAGE_CONFLICT | Failure due to concurrent operation of another SGX instruction. | |
SGX_PG_INVLD | Target page is not a valid EPC page. | |
SGX_PG_NONEPC | Page is not an EPC page. |
Leaf | Parameter | Base Concurrency Restrictions | ||
---|---|---|---|---|
Access | On Conflict | SGX_CONFLICT VM Exit Qualification | ||
ERDINFO | Target [DS:RCX] | Shared | SGX_EPC_PAGE_ CONFLICT |
Leaf | Parameter | Additional Concurrency Restrictions | |||||
---|---|---|---|---|---|---|---|
vs. EACCEPT, EACCEPTCOPY, vs. EADD, EEXTEND, EINIT vs. ETRACK, ETRACKC Access vs. ETRACK, ETRACKC Access On Conflict Access vs. ETRACK, ETRACKC Access On Conflict EMODPE, EMODPR, EMODT | vs. EADD, EEXTEND, EINIT vs. EADD, EEXTEND, EINIT vs. ETRACK, ETRACKC | vs. ETRACK, ETRACKC | |||||
Access On Conflict Access On Conflict Access Access On Conflict Access On Conflict | |||||||
ERDINFO | Target [DS:RCX] | Concurrent | Concurrent | Concurrent |
Name Type Size (Bits) Description |
---|
TMP_SECS Physical Address 64 Physical address of the SECS of the page being modified. |
TMP_RDINFO Linear Address 64 Address of the RDINFO structure. |
(* check alignment of RDINFO structure (RBX) *)
IF (DS:RBX is not 32Byte Aligned) THEN
#GP(0); FI;
(* check alignment of the EPCPAGE (RCX) *)
IF (DS:RCX is not 4KByte Aligned) THEN
#GP(0); FI;
(* check that EPCPAGE (DS:RCX) is the address of an EPC page *)
IF (DS:RCX does not resolve within EPC) THEN
RFLAGS.CF := 1;
RFLAGS.ZF := 0;
RAX := SGX_PG_NONEPC;
goto DONE;
FI;
(* Check the EPC page for concurrency *)
IF (EPC page is being modified) THEN
RFLAGS.ZF = 1;
RFLAGS.CF = 0;
RAX = SGX_EPC_PAGE_CONFLICT;
goto DONE;
FI;
(* check page validity *)
IF (EPCM(DS:RCX).VALID = 0) THEN
RFLAGS.CF = 1;
RFLAGS.ZF = 0;
RAX = SGX_PG_INVLD;
goto DONE;
FI;
(* clear the fields of the RDINFO structure *)
TMP_RDINFO := DS:RBX;
TMP_RDINFO.STATUS := 0;
TMP_RDINFO.FLAGS := 0;
TMP_RDINFO.ENCLAVECONTEXT := 0;
(* store page info in RDINFO structure *)
TMP_RDINFO.FLAGS.RWX := EPCM(DS:RCX).RWX;
TMP_RDINFO.FLAGS.PENDING := EPCM(DS:RCX).PENDING;
TMP_RDINFO.FLAGS.MODIFIED := EPCM(DS:RCX).MODIFIED;
TMP_RDINFO.FLAGS.PR := EPCM(DS:RCX).PR;
TMP_RDINFO.FLAGS.PAGE_TYPE := EPCM(DS:RCX).PAGE_TYPE;
TMP_RDINFO.FLAGS.BLOCKED := EPCM(DS:RCX).BLOCKED;
(* read SECS.ENCLAVECONTEXT for enclave child pages *)
IF ((EPCM(DS:RCX).PAGE_TYPE = PT_REG) or
(EPCM(DS:RCX).PAGE_TYPE = PT_TCS) or
(EPCM(DS:RCX).PAGE_TYPE = PT_TRIM) or
(EPCM(DS:RCX).PAGE_TYPE = PT_SS_FIRST) or
(EPCM(DS:RCX).PAGE_TYPE = PT_SS_REST)
) THEN
TMP_SECS := Address of SECS for (DS:RCX);
TMP_RDINFO.ENCLAVECONTEXT := SECS(TMP_SECS).ENCLAVECONTEXT;
FI;
(* populate enclave information for SECS pages *)
IF (EPCM(DS:RCX).PAGE_TYPE = PT_SECS) THEN
IF ((VMX non-root mode) and
(ENABLE_EPC_VIRTUALIZATION_EXTENSIONS Execution Control = 1)
) THEN
TMP_RDINFO.STATUS.CHILDPRESENT :=
((SECS(DS:RCX).CHLDCNT ≠ 0) or
SECS(DS:RCX).VIRTCHILDCNT ≠ 0);
ELSE
TMP_RDINFO.STATUS.CHILDPRESENT := (SECS(DS:RCX).CHLDCNT ≠ 0);
TMP_RDINFO.STATUS.VIRTCHILDPRESENT :=
(SECS(DS:RCX).VIRTCHILDCNT ≠ 0);
TMP_RDINFO.ENCLAVECONTEXT := SECS(DS_RCX).ENCLAVECONTEXT;
FI;
FI;
RAX := 0;
RFLAGS.ZF := 0;
RFLAGS.CF := 0;
DONE:
(* clear flags *)
RFLAGS.PF := 0;
RFLAGS.AF := 0;
RFLAGS.OF := 0;
RFLAGS.SF := ?0;
ZF is set if ERDINFO fails due to concurrent operation with another SGX instruction; otherwise cleared.
CF is set if page is not a valid EPC page or not an EPC page; otherwise cleared.
PF, AF, OF, and SF are cleared.
#GP(0) | If a memory operand effective address is outside the DS segment limit. |
If DS segment is unusable. | |
If a memory operand is not properly aligned. | |
#PF(error | code) If a page fault occurs in accessing memory operands. |
#GP(0) | If the memory address is in a non-canonical form. |
If a memory operand is not properly aligned. | |
#PF(error | code) If a page fault occurs in accessing memory operands. |