Esempio n. 1
0
File: tcb.c Progetto: KGG814/AOS
exception_t
decodeReadRegisters(cap_t cap, unsigned int length, bool_t call,
                    word_t *buffer)
{
    word_t transferArch, flags, n;

    if (length < 2) {
        userError("TCB ReadRegisters: Truncated message.");
        current_syscall_error.type = seL4_TruncatedMessage;
        return EXCEPTION_SYSCALL_ERROR;
    }

    flags = getSyscallArg(0, buffer);
    n     = getSyscallArg(1, buffer);

    if (n < 1 || n > n_frameRegisters + n_gpRegisters) {
        userError("TCB ReadRegisters: Attempted to read an invalid number of registers (%d).",
                  (int)n);
        current_syscall_error.type = seL4_RangeError;
        current_syscall_error.rangeErrorMin = 1;
        current_syscall_error.rangeErrorMax = n_frameRegisters +
                                              n_gpRegisters;
        return EXCEPTION_SYSCALL_ERROR;
    }

    transferArch = Arch_decodeTransfer(flags >> 8);

    setThreadState(ksCurThread, ThreadState_Restart);
    return invokeTCB_ReadRegisters(
               TCB_PTR(cap_thread_cap_get_capTCBPtr(cap)),
               flags & BIT(ReadRegisters_suspend),
               n, transferArch, call);
}
Esempio n. 2
0
File: tcb.c Progetto: KGG814/AOS
exception_t
decodeWriteRegisters(cap_t cap, unsigned int length, word_t *buffer)
{
    word_t flags, w;
    word_t transferArch;
    tcb_t* thread;

    if (length < 2) {
        userError("TCB WriteRegisters: Truncated message.");
        current_syscall_error.type = seL4_TruncatedMessage;
        return EXCEPTION_SYSCALL_ERROR;
    }

    flags = getSyscallArg(0, buffer);
    w     = getSyscallArg(1, buffer);

    if (length - 2 < w) {
        userError("TCB WriteRegisters: Message too short for requested write size (%d/%d).",
                  (int)(length - 2), (int)w);
        current_syscall_error.type = seL4_TruncatedMessage;
        return EXCEPTION_SYSCALL_ERROR;
    }

    transferArch = Arch_decodeTransfer(flags >> 8);

    thread = TCB_PTR(cap_thread_cap_get_capTCBPtr(cap));

    setThreadState(ksCurThread, ThreadState_Restart);
    return invokeTCB_WriteRegisters(thread,
                                    flags & BIT(WriteRegisters_resume),
                                    w, transferArch, buffer);
}
Esempio n. 3
0
File: vcpu.c Progetto: gapry/AOS
exception_t
decodeSetIOPortMask(cap_t cap, unsigned int length, word_t *buffer)
{
    uint32_t low, high;
    int mask;
    vcpu_t *vcpu;
    if (length < 3) {
        userError("VCPU SetIOPortMask: Truncated message.");
        current_syscall_error.type = seL4_TruncatedMessage;
        return EXCEPTION_SYSCALL_ERROR;
    }
    low = getSyscallArg(0, buffer);
    high = getSyscallArg(1, buffer);
    mask = getSyscallArg(2, buffer) == 0 ? 0 : 1;
    vcpu = VCPU_PTR(cap_vcpu_cap_get_capVCPUPtr(cap));
    if (low < vcpu->io_min || high > vcpu->io_max) {
        userError("VCPU SetIOPortMask: Invalid range.");
        current_syscall_error.type = seL4_IllegalOperation;
        return EXCEPTION_SYSCALL_ERROR;
    }
    if (vcpu->io_min == -1 || vcpu->io_max == -1) {
        userError("VCPU SetIOPortMask: No IO port set.");
        current_syscall_error.type = seL4_IllegalOperation;
        return EXCEPTION_SYSCALL_ERROR;
    }
    setThreadState(ksCurThread, ThreadState_Restart);
    return invokeSetIOPortMask(vcpu, low, high, mask);
}
Esempio n. 4
0
exception_t
decodeIRQControlInvocation(word_t invLabel, word_t length,
                           cte_t *srcSlot, extra_caps_t excaps,
                           word_t *buffer)
{
    if (invLabel == IRQIssueIRQHandler) {
        word_t index, depth, irq_w;
        irq_t irq;
        cte_t *destSlot;
        cap_t cnodeCap;
        lookupSlot_ret_t lu_ret;
        exception_t status;

        if (length < 3 || excaps.excaprefs[0] == NULL) {
            current_syscall_error.type = seL4_TruncatedMessage;
            return EXCEPTION_SYSCALL_ERROR;
        }
        irq_w = getSyscallArg(0, buffer);
        irq = (irq_t) irq_w;
        index = getSyscallArg(1, buffer);
        depth = getSyscallArg(2, buffer);

        cnodeCap = excaps.excaprefs[0]->cap;

        status = Arch_checkIRQ(irq);
        if (status != EXCEPTION_NONE) {
            return status;
        }

        if (isIRQActive(irq)) {
            current_syscall_error.type = seL4_RevokeFirst;
            userError("Rejecting request for IRQ %u. Already active.", (int)irq);
            return EXCEPTION_SYSCALL_ERROR;
        }

        lu_ret = lookupTargetSlot(cnodeCap, index, depth);
        if (lu_ret.status != EXCEPTION_NONE) {
            userError("Target slot for new IRQ Handler cap invalid: cap %lu, IRQ %u.",
                      getExtraCPtr(buffer, 0), (int)irq);
            return lu_ret.status;
        }
        destSlot = lu_ret.slot;

        status = ensureEmptySlot(destSlot);
        if (status != EXCEPTION_NONE) {
            userError("Target slot for new IRQ Handler cap not empty: cap %lu, IRQ %u.",
                      getExtraCPtr(buffer, 0), (int)irq);
            return status;
        }

        setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
        return invokeIRQControl(irq, destSlot, srcSlot);
    } else {
        return Arch_decodeIRQControlInvocation(invLabel, length, srcSlot, excaps, buffer);
    }
}
Esempio n. 5
0
File: tcb.c Progetto: KGG814/AOS
exception_t
decodeSetPriority(cap_t cap, unsigned int length, word_t *buffer)
{
    prio_t newPrio;

    if (length < 1) {
        userError("TCB SetPriority: Truncated message.");
        current_syscall_error.type = seL4_TruncatedMessage;
        return EXCEPTION_SYSCALL_ERROR;
    }

    newPrio = getSyscallArg(0, buffer);

    /* assuming here seL4_MaxPrio is of form 2^n - 1 */
    newPrio = newPrio & MASK(8);

    if (newPrio > ksCurThread->tcbPriority) {
        userError("TCB SetPriority: Requested priority %d too high (max %d).",
                  (int)newPrio, (int)ksCurThread->tcbPriority);
        current_syscall_error.type = seL4_IllegalOperation;
        return EXCEPTION_SYSCALL_ERROR;
    }

    setThreadState(ksCurThread, ThreadState_Restart);
    return invokeTCB_ThreadControl(
               TCB_PTR(cap_thread_cap_get_capTCBPtr(cap)), NULL,
               0, newPrio,
               cap_null_cap_new(), NULL,
               cap_null_cap_new(), NULL,
               0, cap_null_cap_new(),
               NULL, thread_control_update_priority);
}
Esempio n. 6
0
File: tcb.c Progetto: KGG814/AOS
exception_t
invokeTCB_WriteRegisters(tcb_t *dest, bool_t resumeTarget,
                         unsigned int n, word_t arch, word_t *buffer)
{
    unsigned int i;
    word_t pc;
    exception_t e;

    e = Arch_performTransfer(arch, ksCurThread, dest);
    if (e != EXCEPTION_NONE) {
        return e;
    }

    if (n > n_frameRegisters + n_gpRegisters) {
        n = n_frameRegisters + n_gpRegisters;
    }

    for (i = 0; i < n_frameRegisters && i < n; i++) {
        /* Offset of 2 to get past the initial syscall arguments */
        setRegister(dest, frameRegisters[i],
                    sanitiseRegister(frameRegisters[i],
                                     getSyscallArg(i + 2, buffer)));
    }

    for (i = 0; i < n_gpRegisters && i + n_frameRegisters < n; i++) {
        setRegister(dest, gpRegisters[i],
                    sanitiseRegister(gpRegisters[i],
                                     getSyscallArg(i + n_frameRegisters + 2,
                                                   buffer)));
    }

    pc = getRestartPC(dest);
    setNextPC(dest, pc);

    if (resumeTarget) {
        restart(dest);
    }

    return EXCEPTION_NONE;
}
Esempio n. 7
0
File: tcb.c Progetto: KGG814/AOS
exception_t
decodeSetIPCBuffer(cap_t cap, unsigned int length, cte_t* slot,
                   extra_caps_t extraCaps, word_t *buffer)
{
    cptr_t cptr_bufferPtr;
    cap_t bufferCap;
    cte_t *bufferSlot;

    if (length < 1 || extraCaps.excaprefs[0] == NULL) {
        userError("TCB SetIPCBuffer: Truncated message.");
        current_syscall_error.type = seL4_TruncatedMessage;
        return EXCEPTION_SYSCALL_ERROR;
    }

    cptr_bufferPtr  = getSyscallArg(0, buffer);
    bufferSlot = extraCaps.excaprefs[0];
    bufferCap  = extraCaps.excaprefs[0]->cap;

    if (cptr_bufferPtr == 0) {
        bufferSlot = NULL;
    } else {
        exception_t e;
        deriveCap_ret_t dc_ret;

        dc_ret = deriveCap(bufferSlot, bufferCap);
        if (dc_ret.status != EXCEPTION_NONE) {
            return dc_ret.status;
        }
        bufferCap = dc_ret.cap;
        e = checkValidIPCBuffer(cptr_bufferPtr, bufferCap);
        if (e != EXCEPTION_NONE) {
            return e;
        }
    }

    setThreadState(ksCurThread, ThreadState_Restart);
    return invokeTCB_ThreadControl(
               TCB_PTR(cap_thread_cap_get_capTCBPtr(cap)), slot,
               0,
               0, /* used to be prioInvalid, but it doesn't matter */
               cap_null_cap_new(), NULL,
               cap_null_cap_new(), NULL,
               cptr_bufferPtr, bufferCap,
               bufferSlot, thread_control_update_ipc_buffer);
}
Esempio n. 8
0
File: tcb.c Progetto: KGG814/AOS
exception_t
decodeDomainInvocation(word_t label, unsigned int length, extra_caps_t extraCaps, word_t *buffer)
{
    word_t domain;
    cap_t tcap;

    if (unlikely(label != DomainSetSet)) {
        current_syscall_error.type = seL4_IllegalOperation;
        return EXCEPTION_SYSCALL_ERROR;
    }

    if (unlikely(length == 0)) {
        userError("Domain Configure: Truncated message.");
        current_syscall_error.type = seL4_TruncatedMessage;
        return EXCEPTION_SYSCALL_ERROR;
    } else {
        domain = getSyscallArg(0, buffer);
        if (domain >= CONFIG_NUM_DOMAINS) {
            userError("Domain Configure: invalid domain (%u >= %u).",
                      domain, CONFIG_NUM_DOMAINS);
            current_syscall_error.type = seL4_InvalidArgument;
            current_syscall_error.invalidArgumentNumber = 0;
            return EXCEPTION_SYSCALL_ERROR;
        }
    }

    if (unlikely(extraCaps.excaprefs[0] == NULL)) {
        userError("Domain Configure: Truncated message.");
        current_syscall_error.type = seL4_TruncatedMessage;
        return EXCEPTION_SYSCALL_ERROR;
    }

    tcap = extraCaps.excaprefs[0]->cap;
    if (unlikely(cap_get_capType(tcap) != cap_thread_cap)) {
        userError("Domain Configure: thread cap required.");
        current_syscall_error.type = seL4_InvalidArgument;
        current_syscall_error.invalidArgumentNumber = 1;
        return EXCEPTION_SYSCALL_ERROR;
    }

    setThreadState(ksCurThread, ThreadState_Restart);
    setDomain(TCB_PTR(cap_thread_cap_get_capTCBPtr(tcap)), domain);
    return EXCEPTION_NONE;
}
Esempio n. 9
0
File: tcb.c Progetto: KGG814/AOS
exception_t
decodeCopyRegisters(cap_t cap, unsigned int length,
                    extra_caps_t extraCaps, word_t *buffer)
{
    word_t transferArch;
    tcb_t *srcTCB;
    cap_t source_cap;
    word_t flags;

    if (length < 1 || extraCaps.excaprefs[0] == NULL) {
        userError("TCB CopyRegisters: Truncated message.");
        current_syscall_error.type = seL4_TruncatedMessage;
        return EXCEPTION_SYSCALL_ERROR;
    }

    flags = getSyscallArg(0, buffer);

    transferArch = Arch_decodeTransfer(flags >> 8);

    source_cap = extraCaps.excaprefs[0]->cap;

    if (cap_get_capType(source_cap) == cap_thread_cap) {
        srcTCB = TCB_PTR(cap_thread_cap_get_capTCBPtr(source_cap));
    } else {
        userError("TCB CopyRegisters: Invalid source TCB.");
        current_syscall_error.type = seL4_InvalidCapability;
        current_syscall_error.invalidCapNumber = 1;
        return EXCEPTION_SYSCALL_ERROR;
    }

    setThreadState(ksCurThread, ThreadState_Restart);
    return invokeTCB_CopyRegisters(
               TCB_PTR(cap_thread_cap_get_capTCBPtr(cap)), srcTCB,
               flags & BIT(CopyRegisters_suspendSource),
               flags & BIT(CopyRegisters_resumeTarget),
               flags & BIT(CopyRegisters_transferFrame),
               flags & BIT(CopyRegisters_transferInteger),
               transferArch);

}
Esempio n. 10
0
File: tcb.c Progetto: KGG814/AOS
exception_t
decodeSetSpace(cap_t cap, unsigned int length, cte_t* slot,
               extra_caps_t extraCaps, word_t *buffer)
{
    cptr_t faultEP;
    word_t cRootData, vRootData;
    cte_t *cRootSlot, *vRootSlot;
    cap_t cRootCap, vRootCap;
    deriveCap_ret_t dc_ret;

    if (length < 3 || extraCaps.excaprefs[0] == NULL
            || extraCaps.excaprefs[1] == NULL) {
        userError("TCB SetSpace: Truncated message.");
        current_syscall_error.type = seL4_TruncatedMessage;
        return EXCEPTION_SYSCALL_ERROR;
    }

    faultEP   = getSyscallArg(0, buffer);
    cRootData = getSyscallArg(1, buffer);
    vRootData = getSyscallArg(2, buffer);

    cRootSlot  = extraCaps.excaprefs[0];
    cRootCap   = extraCaps.excaprefs[0]->cap;
    vRootSlot  = extraCaps.excaprefs[1];
    vRootCap   = extraCaps.excaprefs[1]->cap;

    if (slotCapLongRunningDelete(
                TCB_PTR_CTE_PTR(cap_thread_cap_get_capTCBPtr(cap), tcbCTable)) ||
            slotCapLongRunningDelete(
                TCB_PTR_CTE_PTR(cap_thread_cap_get_capTCBPtr(cap), tcbVTable))) {
        userError("TCB SetSpace: CSpace or VSpace currently being deleted.");
        current_syscall_error.type = seL4_IllegalOperation;
        return EXCEPTION_SYSCALL_ERROR;
    }

    if (cRootData != 0) {
        cRootCap = updateCapData(false, cRootData, cRootCap);
    }

    dc_ret = deriveCap(cRootSlot, cRootCap);
    if (dc_ret.status != EXCEPTION_NONE) {
        return dc_ret.status;
    }
    cRootCap = dc_ret.cap;

    if (cap_get_capType(cRootCap) != cap_cnode_cap &&
            (!config_set(CONFIG_ALLOW_NULL_CSPACE) ||
             cap_get_capType(cRootCap) != cap_null_cap)) {
        userError("TCB SetSpace: Invalid CNode cap.");
        current_syscall_error.type = seL4_IllegalOperation;
        return EXCEPTION_SYSCALL_ERROR;
    }

    if (vRootData != 0) {
        vRootCap = updateCapData(false, vRootData, vRootCap);
    }

    dc_ret = deriveCap(vRootSlot, vRootCap);
    if (dc_ret.status != EXCEPTION_NONE) {
        return dc_ret.status;
    }
    vRootCap = dc_ret.cap;

    if (!isValidVTableRoot(vRootCap)) {
        userError("TCB SetSpace: Invalid VSpace cap.");
        current_syscall_error.type = seL4_IllegalOperation;
        return EXCEPTION_SYSCALL_ERROR;
    }

    setThreadState(ksCurThread, ThreadState_Restart);
    return invokeTCB_ThreadControl(
               TCB_PTR(cap_thread_cap_get_capTCBPtr(cap)), slot,
               faultEP,
               0, /* used to be prioInvalid, but it doesn't matter */
               cRootCap, cRootSlot,
               vRootCap, vRootSlot,
               0, cap_null_cap_new(), NULL, thread_control_update_space);
}
Esempio n. 11
0
File: tcb.c Progetto: KGG814/AOS
exception_t
decodeTCBConfigure(cap_t cap, unsigned int length, cte_t* slot,
                   extra_caps_t rootCaps, word_t *buffer)
{
    cte_t *bufferSlot, *cRootSlot, *vRootSlot;
    cap_t bufferCap, cRootCap, vRootCap;
    deriveCap_ret_t dc_ret;
    cptr_t faultEP;
    unsigned int prio;
    word_t cRootData, vRootData, bufferAddr;

    if (length < 5 || rootCaps.excaprefs[0] == NULL
            || rootCaps.excaprefs[1] == NULL
            || rootCaps.excaprefs[2] == NULL) {
        userError("TCB Configure: Truncated message.");
        current_syscall_error.type = seL4_TruncatedMessage;
        return EXCEPTION_SYSCALL_ERROR;
    }

    faultEP    = getSyscallArg(0, buffer);
    prio       = getSyscallArg(1, buffer);
    cRootData  = getSyscallArg(2, buffer);
    vRootData  = getSyscallArg(3, buffer);
    bufferAddr = getSyscallArg(4, buffer);

    cRootSlot  = rootCaps.excaprefs[0];
    cRootCap   = rootCaps.excaprefs[0]->cap;
    vRootSlot  = rootCaps.excaprefs[1];
    vRootCap   = rootCaps.excaprefs[1]->cap;
    bufferSlot = rootCaps.excaprefs[2];
    bufferCap  = rootCaps.excaprefs[2]->cap;

    prio = prio & MASK(8);

    if (prio > ksCurThread->tcbPriority) {
        userError("TCB Configure: Requested priority %d too high (max %d).",
                  (int)prio, (int)(ksCurThread->tcbPriority));
        current_syscall_error.type = seL4_IllegalOperation;
        return EXCEPTION_SYSCALL_ERROR;
    }

    if (bufferAddr == 0) {
        bufferSlot = NULL;
    } else {
        exception_t e;

        dc_ret = deriveCap(bufferSlot, bufferCap);
        if (dc_ret.status != EXCEPTION_NONE) {
            return dc_ret.status;
        }
        bufferCap = dc_ret.cap;
        e = checkValidIPCBuffer(bufferAddr, bufferCap);
        if (e != EXCEPTION_NONE) {
            return e;
        }
    }

    if (slotCapLongRunningDelete(
                TCB_PTR_CTE_PTR(cap_thread_cap_get_capTCBPtr(cap), tcbCTable)) ||
            slotCapLongRunningDelete(
                TCB_PTR_CTE_PTR(cap_thread_cap_get_capTCBPtr(cap), tcbVTable))) {
        userError("TCB Configure: CSpace or VSpace currently being deleted.");
        current_syscall_error.type = seL4_IllegalOperation;
        return EXCEPTION_SYSCALL_ERROR;
    }

    if (cRootData != 0) {
        cRootCap = updateCapData(false, cRootData, cRootCap);
    }

    dc_ret = deriveCap(cRootSlot, cRootCap);
    if (dc_ret.status != EXCEPTION_NONE) {
        return dc_ret.status;
    }
    cRootCap = dc_ret.cap;

    if (cap_get_capType(cRootCap) != cap_cnode_cap &&
            (!config_set(CONFIG_ALLOW_NULL_CSPACE) ||
             cap_get_capType(cRootCap) != cap_null_cap)) {
        userError("TCB Configure: CSpace cap is invalid.");
        current_syscall_error.type = seL4_IllegalOperation;
        return EXCEPTION_SYSCALL_ERROR;
    }

    if (vRootData != 0) {
        vRootCap = updateCapData(false, vRootData, vRootCap);
    }

    dc_ret = deriveCap(vRootSlot, vRootCap);
    if (dc_ret.status != EXCEPTION_NONE) {
        return dc_ret.status;
    }
    vRootCap = dc_ret.cap;

    if (!isValidVTableRoot(vRootCap)) {
        userError("TCB Configure: VSpace cap is invalid.");
        current_syscall_error.type = seL4_IllegalOperation;
        return EXCEPTION_SYSCALL_ERROR;
    }

    setThreadState(ksCurThread, ThreadState_Restart);
    return invokeTCB_ThreadControl(
               TCB_PTR(cap_thread_cap_get_capTCBPtr(cap)), slot,
               faultEP, prio,
               cRootCap, cRootSlot,
               vRootCap, vRootSlot,
               bufferAddr, bufferCap,
               bufferSlot, thread_control_update_all);
}
Esempio n. 12
0
File: vcpu.c Progetto: gapry/AOS
exception_t
decodeReadVMCS(cap_t cap, unsigned int length, word_t* buffer)
{
    uint32_t fields[MAX_VMCS_FIELDS];
    int num_fields;
    int i;
    if (length > MAX_VMCS_FIELDS) {
        userError("VCPU ReadVMCS: Too many arguments.");
        current_syscall_error.type = seL4_IllegalOperation;
        return EXCEPTION_SYSCALL_ERROR;
    }
    num_fields = length;
    for (i = 0; i < num_fields; i++) {
        uint32_t field = getSyscallArg(i, buffer);
        switch (field) {
        case VMX_GUEST_ES_SELECTOR:
        case VMX_GUEST_CS_SELECTOR:
        case VMX_GUEST_SS_SELECTOR:
        case VMX_GUEST_DS_SELECTOR:
        case VMX_GUEST_FS_SELECTOR:
        case VMX_GUEST_GS_SELECTOR:
        case VMX_GUEST_LDTR_SELECTOR:
        case VMX_GUEST_TR_SELECTOR:
        case VMX_GUEST_DEBUGCTRL:
        case VMX_GUEST_PAT:
        case VMX_GUEST_EFER:
        case VMX_GUEST_PERF_GLOBAL_CTRL:
        case VMX_GUEST_PDPTE0:
        case VMX_GUEST_PDPTE1:
        case VMX_GUEST_PDPTE2:
        case VMX_GUEST_PDPTE3:
        case VMX_GUEST_ES_LIMIT:
        case VMX_GUEST_CS_LIMIT:
        case VMX_GUEST_SS_LIMIT:
        case VMX_GUEST_DS_LIMIT:
        case VMX_GUEST_FS_LIMIT:
        case VMX_GUEST_GS_LIMIT:
        case VMX_GUEST_LDTR_LIMIT:
        case VMX_GUEST_TR_LIMIT:
        case VMX_GUEST_GDTR_LIMIT:
        case VMX_GUEST_IDTR_LIMIT:
        case VMX_GUEST_ES_ACCESS_RIGHTS:
        case VMX_GUEST_CS_ACCESS_RIGHTS:
        case VMX_GUEST_SS_ACCESS_RIGHTS:
        case VMX_GUEST_DS_ACCESS_RIGHTS:
        case VMX_GUEST_FS_ACCESS_RIGHTS:
        case VMX_GUEST_GS_ACCESS_RIGHTS:
        case VMX_GUEST_LDTR_ACCESS_RIGHTS:
        case VMX_GUEST_TR_ACCESS_RIGHTS:
        case VMX_GUEST_INTERRUPTABILITY:
        case VMX_GUEST_ACTIVITY:
        case VMX_GUEST_SMBASE:
        case VMX_GUEST_SYSENTER_CS:
        case VMX_GUEST_PREEMPTION_TIMER_VALUE:
        case VMX_GUEST_ES_BASE:
        case VMX_GUEST_CS_BASE:
        case VMX_GUEST_SS_BASE:
        case VMX_GUEST_DS_BASE:
        case VMX_GUEST_FS_BASE:
        case VMX_GUEST_GS_BASE:
        case VMX_GUEST_LDTR_BASE:
        case VMX_GUEST_TR_BASE:
        case VMX_GUEST_GDTR_BASE:
        case VMX_GUEST_IDTR_BASE:
        case VMX_GUEST_DR7:
        case VMX_GUEST_RFLAGS:
        case VMX_GUEST_PENDING_DEBUG_EXCEPTIONS:
        case VMX_GUEST_SYSENTER_ESP:
        case VMX_GUEST_SYSENTER_EIP:
        case VMX_CONTROL_CR0_MASK:
        case VMX_CONTROL_CR4_MASK:
        case VMX_CONTROL_CR0_READ_SHADOW:
        case VMX_CONTROL_CR4_READ_SHADOW:
        case VMX_DATA_INSTRUCTION_ERROR:
        case VMX_DATA_EXIT_INTERRUPT_INFO:
        case VMX_DATA_EXIT_INTERRUPT_ERROR:
        case VMX_DATA_IDT_VECTOR_INFO:
        case VMX_DATA_IDT_VECTOR_ERROR:
        case VMX_DATA_EXIT_INSTRUCTION_LENGTH:
        case VMX_DATA_EXIT_INSTRUCTION_INFO:
        case VMX_DATA_GUEST_PHYSICAL:
        case VMX_DATA_IO_RCX:
        case VMX_DATA_IO_RSI:
        case VMX_DATA_IO_RDI:
        case VMX_DATA_IO_RIP:
        case VMX_DATA_GUEST_LINEAR_ADDRESS:
        case VMX_CONTROL_ENTRY_INTERRUPTION_INFO:
        case VMX_CONTROL_PIN_EXECUTION_CONTROLS:
        case VMX_CONTROL_PRIMARY_PROCESSOR_CONTROLS:
        case VMX_CONTROL_EXCEPTION_BITMAP:
        case VMX_CONTROL_EXIT_CONTROLS:
        case VMX_GUEST_CR0:
        case VMX_GUEST_CR3:
        case VMX_GUEST_CR4:
            break;
        default:
            userError("VCPU ReadVMCS: Invalid field %x.", field);
            current_syscall_error.type = seL4_IllegalOperation;
            return EXCEPTION_SYSCALL_ERROR;
        }
        fields[i] = field;
    }
    return invokeReadVMCS(VCPU_PTR(cap_vcpu_cap_get_capVCPUPtr(cap)), num_fields, fields);
}
Esempio n. 13
0
File: vcpu.c Progetto: gapry/AOS
exception_t
decodeWriteVMCS(cap_t cap, unsigned int length, word_t* buffer)
{
    uint32_t fields[MAX_VMCS_FIELDS];
    uint32_t values[MAX_VMCS_FIELDS];
    int num_fields;
    int i;
    if (length > MAX_VMCS_FIELDS * 2) {
        userError("VCPU WriteVMCS: Too many arguments.");
        current_syscall_error.type = seL4_IllegalOperation;
        return EXCEPTION_SYSCALL_ERROR;
    }
    num_fields = length / 2;
    for (i = 0; i < num_fields; i++) {
        uint32_t field = getSyscallArg(i * 2 + 0, buffer);
        uint32_t value = getSyscallArg(i * 2 + 1, buffer);
        switch (field) {
        case VMX_GUEST_ES_SELECTOR:
        case VMX_GUEST_CS_SELECTOR:
        case VMX_GUEST_SS_SELECTOR:
        case VMX_GUEST_DS_SELECTOR:
        case VMX_GUEST_FS_SELECTOR:
        case VMX_GUEST_GS_SELECTOR:
        case VMX_GUEST_LDTR_SELECTOR:
        case VMX_GUEST_TR_SELECTOR:
        case VMX_GUEST_DEBUGCTRL:
        case VMX_GUEST_PAT:
        case VMX_GUEST_EFER:
        case VMX_GUEST_PERF_GLOBAL_CTRL:
        case VMX_GUEST_PDPTE0:
        case VMX_GUEST_PDPTE1:
        case VMX_GUEST_PDPTE2:
        case VMX_GUEST_PDPTE3:
        case VMX_GUEST_ES_LIMIT:
        case VMX_GUEST_CS_LIMIT:
        case VMX_GUEST_SS_LIMIT:
        case VMX_GUEST_DS_LIMIT:
        case VMX_GUEST_FS_LIMIT:
        case VMX_GUEST_GS_LIMIT:
        case VMX_GUEST_LDTR_LIMIT:
        case VMX_GUEST_TR_LIMIT:
        case VMX_GUEST_GDTR_LIMIT:
        case VMX_GUEST_IDTR_LIMIT:
        case VMX_GUEST_ES_ACCESS_RIGHTS:
        case VMX_GUEST_CS_ACCESS_RIGHTS:
        case VMX_GUEST_SS_ACCESS_RIGHTS:
        case VMX_GUEST_DS_ACCESS_RIGHTS:
        case VMX_GUEST_FS_ACCESS_RIGHTS:
        case VMX_GUEST_GS_ACCESS_RIGHTS:
        case VMX_GUEST_LDTR_ACCESS_RIGHTS:
        case VMX_GUEST_TR_ACCESS_RIGHTS:
        case VMX_GUEST_INTERRUPTABILITY:
        case VMX_GUEST_ACTIVITY:
        case VMX_GUEST_SMBASE:
        case VMX_GUEST_SYSENTER_CS:
        case VMX_GUEST_PREEMPTION_TIMER_VALUE:
        case VMX_GUEST_ES_BASE:
        case VMX_GUEST_CS_BASE:
        case VMX_GUEST_SS_BASE:
        case VMX_GUEST_DS_BASE:
        case VMX_GUEST_FS_BASE:
        case VMX_GUEST_GS_BASE:
        case VMX_GUEST_LDTR_BASE:
        case VMX_GUEST_TR_BASE:
        case VMX_GUEST_GDTR_BASE:
        case VMX_GUEST_IDTR_BASE:
        case VMX_GUEST_DR7:
        case VMX_GUEST_RFLAGS:
        case VMX_GUEST_PENDING_DEBUG_EXCEPTIONS:
        case VMX_GUEST_SYSENTER_ESP:
        case VMX_GUEST_SYSENTER_EIP:
        case VMX_CONTROL_CR0_MASK:
        case VMX_CONTROL_CR4_MASK:
        case VMX_CONTROL_CR0_READ_SHADOW:
        case VMX_CONTROL_CR4_READ_SHADOW:
        case VMX_GUEST_CR3:
        case VMX_CONTROL_EXCEPTION_BITMAP:
            break;
        case VMX_CONTROL_ENTRY_INTERRUPTION_INFO:
            value &= ~(MASK(31 - 12) << 12);
            break;
        case VMX_CONTROL_PIN_EXECUTION_CONTROLS:
            value = applyFixedBits(value, pin_control_high, pin_control_low);
            break;
        case VMX_CONTROL_PRIMARY_PROCESSOR_CONTROLS:
            value = applyFixedBits(value, primary_control_high, primary_control_low);
            break;
        case VMX_CONTROL_SECONDARY_PROCESSOR_CONTROLS:
            value = applyFixedBits(value, secondary_control_high, secondary_control_low);
            break;
        case VMX_CONTROL_EXIT_CONTROLS:
            value = applyFixedBits(value, exit_control_high, exit_control_low);
            break;
        case VMX_GUEST_CR0:
            value = applyFixedBits(value, cr0_high, cr0_low);
            break;
        case VMX_GUEST_CR4:
            value = applyFixedBits(value, cr4_high, cr4_low);
            break;
        default:
            userError("VCPU WriteVMCS: Invalid field %x.", field);
            current_syscall_error.type = seL4_IllegalOperation;
            return EXCEPTION_SYSCALL_ERROR;
        }
        fields[i] = field;
        values[i] = value;
    }
    setThreadState(ksCurThread, ThreadState_Restart);
    return invokeWriteVMCS(VCPU_PTR(cap_vcpu_cap_get_capVCPUPtr(cap)), num_fields, fields, values);
}
Esempio n. 14
0
exception_t
Arch_decodeIRQControlInvocation(word_t invLabel, word_t length, cte_t *srcSlot, extra_caps_t excaps, word_t *buffer)
{
    word_t index, depth;
    cte_t *destSlot;
    cap_t cnodeCap;
    lookupSlot_ret_t lu_ret;
    exception_t status;
    irq_t irq;
    word_t vector;

    if (!config_set(CONFIG_IRQ_IOAPIC)) {
        userError("IRQControl: Illegal operation.");
        current_syscall_error.type = seL4_IllegalOperation;
        return EXCEPTION_SYSCALL_ERROR;
    }

    /* check the common parameters */

    if (length < 7 || excaps.excaprefs[0] == NULL) {
        userError("IRQControl: Truncated message");
        current_syscall_error.type = seL4_TruncatedMessage;
        return EXCEPTION_SYSCALL_ERROR;
    }
    index = getSyscallArg(0, buffer);
    depth = getSyscallArg(1, buffer);
    cnodeCap = excaps.excaprefs[0]->cap;
    irq = getSyscallArg(6, buffer);
    if (irq > irq_user_max - irq_user_min) {
        userError("IRQControl: Invalid irq %ld should be between 0-%ld", (long)irq, (long)(irq_user_max - irq_user_min - 1));
        current_syscall_error.type = seL4_RangeError;
        current_syscall_error.rangeErrorMin = 0;
        current_syscall_error.rangeErrorMax = irq_user_max - irq_user_min;
        return EXCEPTION_SYSCALL_ERROR;
    }
    irq += irq_user_min;
    vector = (word_t)irq + IRQ_INT_OFFSET;

    lu_ret = lookupTargetSlot(cnodeCap, index, depth);
    if (lu_ret.status != EXCEPTION_NONE) {
        return lu_ret.status;
    }

    destSlot = lu_ret.slot;

    status = ensureEmptySlot(destSlot);
    if (status != EXCEPTION_NONE) {
        return status;
    }

    switch (invLabel) {
    case X86IRQIssueIRQHandlerIOAPIC: {
        word_t ioapic = getSyscallArg(2, buffer);
        word_t pin = getSyscallArg(3, buffer);
        word_t level = getSyscallArg(4, buffer);
        word_t polarity = getSyscallArg(5, buffer);


        if (isIRQActive(irq)) {
            userError("IOAPICGet: IRQ %d is already active.", (int)irq);
            current_syscall_error.type = seL4_RevokeFirst;
            return EXCEPTION_SYSCALL_ERROR;
        }

        status = ioapic_decode_map_pin_to_vector(ioapic, pin, level, polarity, vector);
        if (status != EXCEPTION_NONE) {
            return status;
        }

        setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
        return invokeIssueIRQHandlerIOAPIC(irq, ioapic, pin, level, polarity, vector, destSlot, srcSlot);
    }
    break;
    case X86IRQIssueIRQHandlerMSI: {
        word_t pci_bus = getSyscallArg(2, buffer);
        word_t pci_dev = getSyscallArg(3, buffer);
        word_t pci_func = getSyscallArg(4, buffer);
        word_t handle = getSyscallArg(5, buffer);
        x86_irq_state_t irqState;
        /* until we support msi interrupt remaping through vt-d we ignore the
         * vector and trust the user */
        (void)vector;
        if (isIRQActive(irq)) {
            current_syscall_error.type = seL4_RevokeFirst;
            return EXCEPTION_SYSCALL_ERROR;
        }

        if (pci_bus > PCI_BUS_MAX) {
            current_syscall_error.type = seL4_RangeError;
            current_syscall_error.rangeErrorMin = 0;
            current_syscall_error.rangeErrorMax = PCI_BUS_MAX;
            return EXCEPTION_SYSCALL_ERROR;
        }

        if (pci_dev > PCI_DEV_MAX) {
            current_syscall_error.type = seL4_RangeError;
            current_syscall_error.rangeErrorMin = 0;
            current_syscall_error.rangeErrorMax = PCI_DEV_MAX;
            return EXCEPTION_SYSCALL_ERROR;
        }

        if (pci_func > PCI_FUNC_MAX) {
            current_syscall_error.type = seL4_RangeError;
            current_syscall_error.rangeErrorMin = 0;
            current_syscall_error.rangeErrorMax = PCI_FUNC_MAX;
            return EXCEPTION_SYSCALL_ERROR;
        }

        irqState = x86_irq_state_irq_msi_new(pci_bus, pci_dev, pci_func, handle);

        setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
        return Arch_invokeIRQControl(irq, destSlot, srcSlot, irqState);
    }
    break;
    default:
        userError("IRQControl: Illegal operation.");
        current_syscall_error.type = seL4_IllegalOperation;
        return EXCEPTION_SYSCALL_ERROR;
    }
}