예제 #1
0
void
AdminQRollChkDiff_r10b::VerifyQPointers(SharedACQPtr acq, SharedASQPtr asq)
{
    union CE ce;
    struct nvme_gen_cq acqMetrics = acq->GetQMetrics();
    struct nvme_gen_sq asqMetrics = asq->GetQMetrics();

    // The CQ's metrics after reaping holds head_ptr plus 1 needed. Also Take
    // Q roll over into account.
    if (acqMetrics.head_ptr == 0) {
        ce = acq->PeekCE(acq->GetNumEntries() - 1);
    } else {
        ce = acq->PeekCE(acqMetrics.head_ptr - 1);
    }

    uint16_t expectedVal = (2 + MAX(acq->GetNumEntries(),
        asq->GetNumEntries())) % acq->GetNumEntries();
    if (acqMetrics.head_ptr != expectedVal) {
        acq->Dump(
            FileSystem::PrepDumpFile(mGrpName, mTestName, "acq", "head_ptr"),
            "CQ Metrics Head Pointer Inconsistent");
        throw FrmwkEx(HERE, "Expected ACQ.head_ptr = 0x%04X but actual "
            "ACQ.head_ptr = 0x%04X", expectedVal, acqMetrics.head_ptr);
    }

    expectedVal = (2 + MAX(acq->GetNumEntries(), asq->GetNumEntries())) %
        asq->GetNumEntries();
    if (asqMetrics.tail_ptr != expectedVal) {
        asq->Dump(
            FileSystem::PrepDumpFile(mGrpName, mTestName, "asq", "tail_ptr"),
            "SQ Metrics Tail Pointer Inconsistent");
        throw FrmwkEx(HERE, "Expected  ASQ.tail_ptr = 0x%04X but actual "
            "ASQ.tail_ptr  = 0x%04X", expectedVal, asqMetrics.tail_ptr);
    }

    if (ce.n.SQHD != expectedVal) {
        acq->Dump(
            FileSystem::PrepDumpFile(mGrpName, mTestName, "acq", "CE.SQHD"),
            "CE SQ Head Pointer Inconsistent");
        throw FrmwkEx(HERE, "Expected CE.SQHD = 0x%04X in ACQ completion entry but actual "
            "CE.SQHD  = 0x%04X", expectedVal, ce.n.SQHD);
    }
}
예제 #2
0
void
InvalidMSIXIRQ_r10b::ASQCmdToxify(SharedASQPtr asq, uint16_t illegalIrqVec)
{
    struct backdoor_inject inject;
    struct nvme_gen_sq asqMetrics = asq->GetQMetrics();


    LOG_NRM("Attempt to utilize illegal IRQ vec %d", illegalIrqVec);
    if (asqMetrics.tail_ptr_virt)
        inject.cmd_ptr = (asqMetrics.tail_ptr_virt - 1);
    else
        inject.cmd_ptr = (asq->GetNumEntries() - 1);

    inject.q_id = asq->GetQId();
    inject.dword = 11;
    inject.value_mask = 0xFFFF0000;
    inject.value = (illegalIrqVec << 16);

    LOG_NRM("Inject toxic parameters: (qId, cmd_ptr, dword, mask, val) = "
        "(%d, %d, %d, %d, %d)", inject.q_id, inject.cmd_ptr, inject.dword,
        inject.value_mask, inject.value);

    asq->SetToxicCmdValue(inject);
}
예제 #3
0
void
IllegalCreateQs_r10b::ASQCmdToxify(SharedASQPtr asq, uint8_t dw, uint32_t mask,
    uint32_t val)
{
    struct nvme_gen_sq asqMetrics = asq->GetQMetrics();
    struct backdoor_inject inject;

    inject.q_id = asq->GetQId();

    if (asqMetrics.tail_ptr_virt)
        inject.cmd_ptr = asqMetrics.tail_ptr_virt - 1;
    else
        inject.cmd_ptr = asq->GetNumEntries() - 1;

    inject.dword = dw;
    inject.value_mask = mask;
    inject.value = val;

    LOG_NRM("Inject toxic parameters: (qId, cmd_ptr, dword, mask, val) = "
        "(%d, %d, %d, %d, %d)", inject.q_id, inject.cmd_ptr, inject.dword,
        inject.value_mask, inject.value);

    asq->SetToxicCmdValue(inject);
}
예제 #4
0
void
AdminQRollChkDiff_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) none.
     *  \endverbatim
     */
    uint16_t mACQSize = MIN_ADMIN_Q_SIZE; // Start ACQ with min size.
    uint16_t mASQSize = MAX_ADMIN_Q_SIZE;
    uint16_t loopCnt = 0;

    if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false)
        throw FrmwkEx(HERE);

    while (1) {
        LOG_NRM("(ASQSize, ACQSize, Loop Cnt) = (%d, %d, %d)",
            mASQSize, mACQSize, loopCnt++);
        // Issue cntl'r disable completely for every iteration.
        if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false)
            throw FrmwkEx(HERE);

        // Create ACQ and ASQ objects which have test life time
        SharedACQPtr acq = CAST_TO_ACQ(SharedACQPtr(new ACQ(gDutFd)))
        acq->Init(mACQSize);

        SharedASQPtr asq = CAST_TO_ASQ(SharedASQPtr(new ASQ(gDutFd)))
        asq->Init(mASQSize);

        gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET);
        if (gCtrlrConfig->SetState(ST_ENABLE) == false)
            throw FrmwkEx(HERE);

        LOG_NRM("Create identify cmd and assoc some buffer memory");
        SharedIdentifyPtr idCmdCap = SharedIdentifyPtr(new Identify());
        LOG_NRM("Force identify to request ctrlr capabilities struct");
        idCmdCap->SetCNS(true);
        SharedMemBufferPtr idMemCap = SharedMemBufferPtr(new MemBuffer());
        idMemCap->InitAlignment(Identify::IDEAL_DATA_SIZE, PRP_BUFFER_ALIGNMENT,
            false, 0);
        send_64b_bitmask idPrpCap =
            (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE);
        idCmdCap->SetPrpBuffer(idPrpCap, idMemCap);

        LOG_NRM("Submit Idtfy cmds to fill & roll over the Q (Q_SIZE plus 2).");
        for (uint16_t nsubmitTimes = 0; nsubmitTimes <
            MAX(asq->GetNumEntries(), acq->GetNumEntries()) + 2;
            nsubmitTimes++) {
            LOG_NRM("Sending #%d times of %d", (nsubmitTimes + 1),
                (acq->GetNumEntries() + 2));
            IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1),
                asq, acq, idCmdCap, "AdminQRollChkDiff", false);
            VerifyCESQValues(acq, (nsubmitTimes + 1) % asq->GetNumEntries());
        }
        // Verify final Q pointers after all the cmds are submitted and reaped
        VerifyQPointers(acq, asq);

        if (mACQSize >= MAX_ADMIN_Q_SIZE) {
            break;
        }
        // If the test requires incremental sizes then edit here.
        mACQSize = MAX_ADMIN_Q_SIZE; // Assign MAX Q Size of ACQ.
        mASQSize = MIN_ADMIN_Q_SIZE;
    }
}