# EPA — Add Version Array

Opcode/Instruction | Op/En | 64/32 bit Mode Support | CPUID Feature Flag | Description
--- | --- | --- | --- | ---
EAX = 0AH ENCLS[EPA] | IR | V/V | SGX1 | This leaf function adds a Version Array to the EPC.

## Instruction Operand Encoding ¶

Op/En | EAX | RBX | RCX
IR | EPA (In) | PT_VA (In, Constant) | Effective address of the EPC page (In)

### Description ¶

This leaf function creates an empty version array in the EPC page whose logical address is given by DS:RCX, and sets up EPCM attributes for that page. At the time of execution of this instruction, the register RBX must be set to PT_VA.

The table below provides additional information on the memory parameter of EPA leaf function.

## EPA Memory Parameter Semantics ¶

EPCPAGE
Write access permitted by Enclave

### Concurrency Restrictions ¶

Leaf | Parameter | Base Concurrency Restrictions
--- | --- | ---
| On Conflict |
EPA EPA VA [DS:RCX] Exclusive #GP EPA VA [DS:RCX] | VA [DS:RCX] |  |  |

Table 38-37. Base Concurrency Restrictions of EPA

Leaf Access On Conflict Access On Conflict EPA VA [DS:RCX] Concurrent Access On Conflict Access On Conflict EPA VA [DS:RCX] | 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 |  |  |  |  |
EPA | VA [DS:RCX] |  |  | Concurrent |  | Concurrent |

Table 38-38. Additional Concurrency Restrictions of EPA

### Operation ¶

    IF (RBX ≠ PT_VA or DS:RCX is not 4KByte Aligned)
        THEN #GP(0); FI;
    IF (DS:RCX does not resolve within an EPC)
        THEN #PF(DS:RCX); FI;
    (* Check concurrency with other Intel SGX instructions *)
    IF (Other Intel SGX instructions accessing the page)
        THEN
            IF (<<VMX non-root operation>> AND <<ENABLE_EPC_VIRTUALIZATION_EXTENSIONS>>)
                THEN
                    VMCS.Exit_reason := SGX_CONFLICT;
                    VMCS.Exit_qualification.code := EPC_PAGE_CONFLICT_EXCEPTION;
                    VMCS.Exit_qualification.error := 0;
                    VMCS.Guest-physical_address := << translation of DS:RCX produced by paging >>;
                    VMCS.Guest-linear_address := DS:RCX;
                Deliver VMEXIT;
                ELSE
                    #GP(0);
            FI;
    FI;
    (* Check EPC page must be empty *)
    IF (EPCM(DS:RCX). VALID ≠ 0)
        THEN #PF(DS:RCX); FI;
    (* Clears EPC page *)
    DS:RCX[32767:0] := 0;
    EPCM(DS:RCX).PT := PT_VA;
    EPCM(DS:RCX).ENCLAVEADDRESS := 0;
    EPCM(DS:RCX).BLOCKED := 0;
    EPCM(DS:RCX).PENDING := 0;
    EPCM(DS:RCX).MODIFIED := 0;
    EPCM(DS:RCX).PR := 0;
    EPCM(DS:RCX).RWX := 0;
    EPCM(DS:RCX).VALID := 1;

### Flags Affected ¶

None

### 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 another Intel SGX instruction is accessing the EPC page.
If RBX is not set to PT_VA.
#PF(error | code) If a page fault occurs in accessing memory operands.
If a memory operand is not an EPC page.
If the EPC page is valid.

### 64-Bit Mode Exceptions ¶

#GP(0) | If a memory operand is non-canonical form.
If a memory operand is not properly aligned.
If another Intel SGX instruction is accessing the EPC page.
If RBX is not set to PT_VA.
#PF(error | code) If a page fault occurs in accessing memory operands.
If a memory operand is not an EPC page.
If the EPC page is valid.