void IllegalCreateQs_r10b::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ // Lookup objs which were created in a prior test within group SharedACQPtr acq = CAST_TO_ACQ(gRsrcMngr->GetObj(ACQ_GROUP_ID)) SharedASQPtr asq = CAST_TO_ASQ(gRsrcMngr->GetObj(ASQ_GROUP_ID)) uint32_t numEntries = 2; uint8_t dword; uint32_t mask; uint32_t value; { LOG_NRM("Create IOCQ ID #%d but toxify its QID to 0", IOQ_ID); SharedIOCQPtr iocq = SharedIOCQPtr(new IOCQ(mFd)); iocq->Init(IOQ_ID, numEntries, true, 0); LOG_NRM("Form a Create IOCQ cmd"); SharedCreateIOCQPtr iocqCmd = SharedCreateIOCQPtr(new CreateIOCQ()); iocqCmd->Init(iocq); dword = 10; mask = 0xFFFF; value = 0; SendToxicCmd(asq, acq, iocqCmd, dword, mask, value, CESTAT_INVALID_QID); } { LOG_NRM("Create IOSQ ID #%d but toxify its QID to 0", IOQ_ID); SharedIOSQPtr iosq = SharedIOSQPtr(new IOSQ(mFd)); iosq->Init(IOQ_ID, numEntries, IOQ_ID, 0); LOG_NRM("Form a Create IOSQ cmd"); SharedCreateIOSQPtr iosqCmd = SharedCreateIOSQPtr(new CreateIOSQ()); iosqCmd->Init(iosq); dword = 10; mask = 0xFFFF; value = 0; SendToxicCmd(asq, acq, iosqCmd, dword, mask, value, CESTAT_INVALID_QID); } { LOG_NRM("Create IOSQ ID #%d but wrongly associate to ACQ", IOQ_ID); SharedIOSQPtr iosq = SharedIOSQPtr(new IOSQ(mFd)); iosq->Init(IOQ_ID, numEntries, IOQ_ID, 0); LOG_NRM("Form a Create IOSQ cmd"); SharedCreateIOSQPtr iosqCmd = SharedCreateIOSQPtr(new CreateIOSQ()); iosqCmd->Init(iosq); dword = 11; mask = 0xFFFF0000; value = 0; SendToxicCmd(asq, acq, iosqCmd, dword, mask, value, CESTAT_CQ_INVALID); } }
void InvalidQID_r10b::RunCoreTest() { /** \verbatim * Assumptions: * None. * \endverbatim */ string work; bool enableLog; uint64_t maxIOQEntries = 2; if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false) throw FrmwkEx(HERE); LOG_NRM("Create admin queues ACQ and ASQ"); SharedACQPtr acq = SharedACQPtr(new ACQ(gDutFd)); acq->Init(5); SharedASQPtr asq = SharedASQPtr(new ASQ(gDutFd)); asq->Init(5); // All queues will use identical IRQ vector IRQ::SetAnySchemeSpecifyNum(1); gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET); if (gCtrlrConfig->SetState(ST_ENABLE) == false) throw FrmwkEx(HERE); // Calc X, max no. of IOCQ's DUT supports. uint32_t X = gInformative->GetFeaturesNumOfIOCQs(); LOG_NRM("Maximum num of IOCQ's DUT will support = %d", X); LOG_NRM("Setup element size for the IOCQ"); gCtrlrConfig->SetIOCQES(gInformative->GetIdentifyCmdCtrlr()-> GetValue(IDCTRLRCAP_CQES) & 0xf); LOG_NRM("Issue CreateIOCQ cmds with QID's ranging from %d to %d", (X + 1), MAX_IOQ_ID); list<uint32_t> illegalQIDs = GetIllegalQIDs(X + 1); for (list<uint32_t>::iterator qId = illegalQIDs.begin(); qId != illegalQIDs.end(); qId++) { LOG_NRM("Process each CreateIOCQCmd with iocq id #%d", *qId); SharedIOCQPtr iocq = SharedIOCQPtr(new IOCQ(gDutFd)); iocq->Init(*qId, maxIOQEntries, true, 0); SharedCreateIOCQPtr createIOCQCmd = SharedCreateIOCQPtr(new CreateIOCQ()); createIOCQCmd->Init(iocq); work = str(boost::format("iocqId.%d") % *qId); enableLog = false; if ((*qId <= (X + 8)) || (*qId >= (MAX_IOQ_ID - 8))) enableLog = true; LOG_NRM("Send and reap cmd with CQ ID #%d", *qId); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, createIOCQCmd, work, enableLog, CESTAT_INVALID_QID); } }
void UnsupportRsvdFields_r10b::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ uint64_t maxIOQEntries = 2; // Lookup objs which were created in a prior test within group SharedASQPtr asq = CAST_TO_ASQ(gRsrcMngr->GetObj(ASQ_GROUP_ID)) SharedACQPtr acq = CAST_TO_ACQ(gRsrcMngr->GetObj(ACQ_GROUP_ID)) LOG_NRM("Setup element sizes for the IOQ's"); uint8_t iocqes = (gInformative->GetIdentifyCmdCtrlr()-> GetValue(IDCTRLRCAP_CQES) & 0xf); uint8_t iosqes = (gInformative->GetIdentifyCmdCtrlr()-> GetValue(IDCTRLRCAP_SQES) & 0xf); gCtrlrConfig->SetIOCQES(iocqes); gCtrlrConfig->SetIOSQES(iosqes); LOG_NRM("Create IOCQ"); SharedIOCQPtr iocq = SharedIOCQPtr(new IOCQ(gDutFd)); LOG_NRM("Allocate contiguous memory; IOCQ has ID=%d", IOQ_ID); iocq->Init(IOQ_ID, maxIOQEntries, true, 0); LOG_NRM("Form a Create IOCQ cmd to perform queue creation"); SharedCreateIOCQPtr createIOCQCmd = SharedCreateIOCQPtr(new CreateIOCQ()); createIOCQCmd->Init(iocq); LOG_NRM("Set all cmd's rsvd bits"); uint32_t work = createIOCQCmd->GetDword(0); work |= 0x0000fc00; // Set DW0_b15:10 bits createIOCQCmd->SetDword(work, 0); createIOCQCmd->SetDword(0xffffffff, 2); createIOCQCmd->SetDword(0xffffffff, 3); createIOCQCmd->SetDword(0xffffffff, 4); createIOCQCmd->SetDword(0xffffffff, 5); createIOCQCmd->SetDword(0xffffffff, 6); createIOCQCmd->SetDword(0xffffffff, 7); // DW11_b15:2 work = createIOCQCmd->GetDword(11); work |= 0x0000fffc; createIOCQCmd->SetDword(work, 11); createIOCQCmd->SetDword(0xffffffff, 12); createIOCQCmd->SetDword(0xffffffff, 13); createIOCQCmd->SetDword(0xffffffff, 14); createIOCQCmd->SetDword(0xffffffff, 15); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, createIOCQCmd, "", true); LOG_NRM("Create the assoc IOSQ"); SharedIOSQPtr iosq = Queues::CreateIOSQContigToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, IOQ_ID, maxIOQEntries, false, IOCQ_GROUP_ID, IOQ_ID, 0); WriteReadVerify(iosq, iocq); }
void InvalidMSIXIRQ_r10b::RunCoreTest() { /** \verbatim * Assumptions: * 1) Requires test createResources_r10b to execute 1st * \endverbatim */ bool capable; uint16_t numIrqSupport; // Only allowed to execute if DUT supports MSI-X IRQ's if (gCtrlrConfig->IsMSIXCapable(capable, numIrqSupport) == false) throw FrmwkEx(HERE); else if (capable == false) { LOG_NRM("DUT does not support MSI-X IRQ's; unable to execute test"); return; } if (gCtrlrConfig->SetState(ST_DISABLE) == false) throw FrmwkEx(HERE); LOG_NRM("Notify DUT we plan on using all IRQ's that it supports"); if (gCtrlrConfig->SetIrqScheme(INT_MSIX, numIrqSupport) == false) { throw FrmwkEx(HERE, "Unable to use %d IRQ's, but DUT reports it supports", numIrqSupport); } gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET); if (gCtrlrConfig->SetState(ST_ENABLE) == false) throw FrmwkEx(HERE); // Lookup objs which were created in a prior test within group SharedASQPtr asq = CAST_TO_ASQ(gRsrcMngr->GetObj(ASQ_GROUP_ID)) SharedACQPtr acq = CAST_TO_ACQ(gRsrcMngr->GetObj(ACQ_GROUP_ID)) LOG_NRM("Set legal IOCQ element size"); gCtrlrConfig->SetIOCQES(gInformative->GetIdentifyCmdCtrlr()-> GetValue(IDCTRLRCAP_CQES) & 0xf); // This test expects the DUT to reject the usage of illegal/unsupported // MSIX IRQ vectors, thus they should never be used. In order to safely fool // dnvme's safeguards, thus preventing a kernel crash, we need to issue a // legal cmd and allow dnvme to do it job. Then just before ringing the // doorbell inject a toxic illegal MSIX IRQ vector, the guts of this test. // So lets prepare that "legal" cmd here and then corrupt/toxify it later. LOG_NRM("Last supported MSIX IRQ vec = %d", (numIrqSupport - 1)); for (uint32_t i = numIrqSupport; i <= CtrlrConfig::MAX_MSIX_IRQ_VEC; i++) { // We must re-init the objects because a failed attempt at creating an // IOCQ forces dnvme to deconstruct the entire thing when it is reaped. LOG_NRM("Create the IOCQ and the cmd to issue to the DUT"); SharedIOCQPtr iocq = SharedIOCQPtr(new IOCQ(gDutFd)); LOG_NRM("Allocate contiguous memory; IOCQ has ID=%d", IOQ_ID); iocq->Init(IOQ_ID, NUM_IOQ_ENTRY, true, (numIrqSupport - 1)); SharedCreateIOCQPtr createIOCQCmd = SharedCreateIOCQPtr(new CreateIOCQ()); createIOCQCmd->Init(iocq); SendToxicCmd(asq, acq, createIOCQCmd, i); } }
void MaxQSizeExceed_r10b::RunCoreTest() { /** \verbatim * Assumptions: * None. * \endverbatim */ string work; bool enableLog; uint64_t ctrlCapReg; LOG_NRM("Determine the max IOQ entries supported"); if (gRegisters->Read(CTLSPC_CAP, ctrlCapReg) == false) throw FrmwkEx(HERE, "Unable to determine MQES"); uint32_t maxIOQEntries = (ctrlCapReg & CAP_MQES); maxIOQEntries += 1; // convert to 1 - based. if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false) throw FrmwkEx(HERE); LOG_NRM("Create admin queues ACQ and ASQ"); SharedACQPtr acq = SharedACQPtr(new ACQ(gDutFd)); acq->Init(5); SharedASQPtr asq = SharedASQPtr(new ASQ(gDutFd)); asq->Init(5); // All queues will use identical IRQ vector IRQ::SetAnySchemeSpecifyNum(1); gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET); if (gCtrlrConfig->SetState(ST_ENABLE) == false) throw FrmwkEx(HERE); LOG_NRM("Setup element size for the IOCQ"); gCtrlrConfig->SetIOCQES(gInformative->GetIdentifyCmdCtrlr()-> GetValue(IDCTRLRCAP_CQES) & 0xf); LOG_NRM("Create IOCQ with illegal Q entries ranging from 0x%04X to 0x10000", maxIOQEntries + 1); list<uint32_t> illegalQSizes = GetIllegalQSizes(maxIOQEntries); for (list<uint32_t>::iterator qSize = illegalQSizes.begin(); qSize != illegalQSizes.end(); qSize++) { LOG_NRM("Process CreateIOCQ Cmd with qSize #0x%04X", *qSize); SharedIOCQPtr iocq = SharedIOCQPtr(new IOCQ(gDutFd)); iocq->Init(IOQ_ID, *qSize, true, 0); SharedCreateIOCQPtr createIOCQCmd = SharedCreateIOCQPtr(new CreateIOCQ()); createIOCQCmd->Init(iocq); work = str(boost::format("qSize.%04Xh") % *qSize); enableLog = false; if ((*qSize <= (maxIOQEntries + 8)) || (*qSize >= (0xFFFF - 8))) enableLog = true; LOG_NRM("Send n reap ACQ for CreateIOCQCmd; qSize #0x%04X", *qSize); IO::SendAndReapCmd(mGrpName, mTestName, DEFAULT_CMD_WAIT_ms, asq, acq, createIOCQCmd, work, enableLog, CESTAT_MAX_Q_SIZE_EXCEED); } }