Skip to content

Commit

Permalink
Merge pull request #447 from ved-rivos/1115
Browse files Browse the repository at this point in the history
Add missing check for debug trans
  • Loading branch information
ved-rivos authored Nov 16, 2024
2 parents c93cb6d + 3a597ca commit b58ee7f
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 40 deletions.
1 change: 1 addition & 0 deletions iommu_ref_model/libiommu/include/iommu_registers.h
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,7 @@ extern uint8_t offset_to_size[4096];
extern uint8_t g_max_iommu_mode;
extern uint8_t g_fill_ats_trans_in_ioatc;
extern uint32_t g_max_devid_mask;
extern uint8_t g_trans_for_debug;

extern void process_commands(void);
#endif //_IOMMU_REGS_H_
2 changes: 1 addition & 1 deletion iommu_ref_model/libiommu/src/iommu_process_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ locate_process_context(
is_read = 1;
is_write = is_exec = is_implicit = 0;
if ( ( gst_fault = second_stage_address_translation(a, 1, device_id, is_read, is_write,
is_exec, is_implicit, 1, process_id, 0, 0,
is_exec, is_implicit, 1, process_id, 0, 0,
((DC->iohgatp.MODE == IOHGATP_Bare) ? 0 : 1),
DC->iohgatp.GSCID, DC->iohgatp, DC->tc.GADE, DC->tc.SADE,
DC->tc.SXL, &a, &gst_page_sz, &g_pte) ) ) {
Expand Down
3 changes: 3 additions & 0 deletions iommu_ref_model/libiommu/src/iommu_reg.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ uint8_t g_max_iommu_mode;
uint8_t g_fill_ats_trans_in_ioatc;
uint32_t g_max_devid_mask;
extern uint8_t g_iofence_wait_pending_inv;
uint8_t g_trans_for_debug;

uint8_t
is_access_valid(
Expand Down Expand Up @@ -703,7 +704,9 @@ write_register(
req.tr.length = 1;
req.tr.read_writeAMO = (g_reg_file.tr_req_ctrl.NW == 1) ? READ : WRITE;

g_trans_for_debug = 1;
iommu_translate_iova(&req, &rsp);
g_trans_for_debug = 0;

// The value in PBMT, S< and PPN are UNSPECIFIED if
// fault is 1. Model sets them to 0.
Expand Down
8 changes: 8 additions & 0 deletions iommu_ref_model/libiommu/src/iommu_translate.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,14 @@ iommu_translate_iova(
if ( msi_address_translation(gpa, is_exec, &DC, &is_msi, &is_mrif, &mrif_nid, &dest_mrif_addr,
&cause, &iotval2, &pa, &gst_page_sz, &g_pte, check_access_perms) )
goto stop_and_report_fault;

// Chapter 5: If the IOVA is determined to be that of a virtual interrupt file
// (Section 3.1.3.6) and the corresponding MSI PTE is in MRIF mode, then the process
// stops and reports a "Transaction type disallowed" (cause = 260) fault.
if ( is_msi && is_mrif && g_trans_for_debug) {
cause = 260; // "Transaction type disallowed"
goto stop_and_report_fault;
}
if ( is_msi == 1 ) goto skip_gpa_trans;

// 19. Use the second-stage address translation process specified in Section
Expand Down
37 changes: 29 additions & 8 deletions iommu_ref_model/test/test_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ main(void) {
exp_msg.PAYLOAD = (0x1234UL << 48UL) | (RESPONSE_FAILURE << 44UL);
handle_page_request(&pr);
fail_if( ( exp_msg_received == 0 ) );
fail_if( ( check_msg_faults(256, pr.PV, pr.PID, pr.PRIV, 0x431234, PAGE_REQ_MSG_CODE) < 0 ) );
fail_if( ( check_faults(256, pr.PV, pr.PID, pr.PRIV, 0x431234, PAGE_REQ_MSG_CODE, PCIE_MESSAGE_REQUEST, 0) < 0 ) );
END_TEST();

START_TEST("Bare mode tests");
Expand Down Expand Up @@ -195,7 +195,7 @@ main(void) {
exp_msg.PAYLOAD = (0x1234UL << 48UL) | (INVALID_REQUEST << 44UL);
handle_page_request(&pr);
fail_if( ( exp_msg_received == 0 ) );
fail_if( ( check_msg_faults(260, pr.PV, pr.PID, pr.PRIV, 0x431234, PAGE_REQ_MSG_CODE) < 0 ) );
fail_if( ( check_faults(260, pr.PV, pr.PID, pr.PRIV, 0x431234, PAGE_REQ_MSG_CODE, PCIE_MESSAGE_REQUEST, 0) < 0 ) );
// Turn it off
fail_if( ( enable_iommu(Off) < 0 ) );
END_TEST();
Expand Down Expand Up @@ -227,7 +227,7 @@ main(void) {
exp_msg.PAYLOAD = (0x1234UL << 48UL) | (INVALID_REQUEST << 44UL);
handle_page_request(&pr);
fail_if( ( exp_msg_received == 0 ) );
fail_if( ( check_msg_faults(260, pr.PV, pr.PID, pr.PRIV, 0x431234, PAGE_REQ_MSG_CODE) < 0 ) );
fail_if( ( check_faults(260, pr.PV, pr.PID, pr.PRIV, 0x431234, PAGE_REQ_MSG_CODE, PCIE_MESSAGE_REQUEST, 0) < 0 ) );

fail_if( ( enable_iommu(DDT_2LVL) == 0 ) );
fail_if( ( enable_iommu(Off) < 0 ) );
Expand Down Expand Up @@ -258,7 +258,7 @@ main(void) {
exp_msg.PAYLOAD = (0x1234UL << 48UL) | (INVALID_REQUEST << 44UL);
handle_page_request(&pr);
fail_if( ( exp_msg_received == 0 ) );
fail_if( ( check_msg_faults(260, pr.PV, pr.PID, pr.PRIV, 0x431234, PAGE_REQ_MSG_CODE) < 0 ) );
fail_if( ( check_faults(260, pr.PV, pr.PID, pr.PRIV, 0x431234, PAGE_REQ_MSG_CODE, PCIE_MESSAGE_REQUEST, 0) < 0 ) );

// Change to MSI flat mode
g_reg_file.capabilities.msi_flat = 0;
Expand All @@ -284,7 +284,7 @@ main(void) {
exp_msg.PAYLOAD = (0x1234UL << 48UL) | (INVALID_REQUEST << 44UL);
handle_page_request(&pr);
fail_if( ( exp_msg_received == 0 ) );
fail_if( ( check_msg_faults(260, pr.PV, pr.PID, pr.PRIV, 0x431234, PAGE_REQ_MSG_CODE) < 0 ) );
fail_if( ( check_faults(260, pr.PV, pr.PID, pr.PRIV, 0x431234, PAGE_REQ_MSG_CODE, PCIE_MESSAGE_REQUEST, 0) < 0 ) );
g_reg_file.capabilities.msi_flat = 1;

END_TEST();
Expand Down Expand Up @@ -3024,7 +3024,7 @@ main(void) {
exp_msg.PAYLOAD = (0x1234UL << 48UL) | (RESPONSE_FAILURE << 44UL);
handle_page_request(&pr);
fail_if( ( exp_msg_received == 0 ) );
fail_if( ( check_msg_faults(258, pr.PV, pr.PID, pr.PRIV, 0x431234, PAGE_REQ_MSG_CODE) < 0 ) );
fail_if( ( check_faults(258, pr.PV, pr.PID, pr.PRIV, 0x431234, PAGE_REQ_MSG_CODE, PCIE_MESSAGE_REQUEST, 0) < 0 ) );

// ATS disabled
pr.RID = 0x2233;
Expand All @@ -3040,7 +3040,7 @@ main(void) {
exp_msg.PAYLOAD = (0x2233UL << 48UL) | (INVALID_REQUEST << 44UL);
handle_page_request(&pr);
fail_if( ( exp_msg_received == 0 ) );
fail_if( ( check_msg_faults(260, pr.PV, pr.PID, pr.PRIV, 0x112233, PAGE_REQ_MSG_CODE) < 0 ) );
fail_if( ( check_faults(260, pr.PV, pr.PID, pr.PRIV, 0x112233, PAGE_REQ_MSG_CODE, PCIE_MESSAGE_REQUEST, 0) < 0 ) );

// ATS enabled PRI disabled
pr.RID = 0x2233;
Expand All @@ -3056,7 +3056,7 @@ main(void) {
exp_msg.PAYLOAD = (0x2233UL << 48UL) | (INVALID_REQUEST << 44UL);
handle_page_request(&pr);
fail_if( ( exp_msg_received == 0 ) );
fail_if( ( check_msg_faults(260, pr.PV, pr.PID, pr.PRIV, 0x112233, PAGE_REQ_MSG_CODE) < 0 ) );
fail_if( ( check_faults(260, pr.PV, pr.PID, pr.PRIV, 0x112233, PAGE_REQ_MSG_CODE, PCIE_MESSAGE_REQUEST, 0) < 0 ) );


// ATS, PRI enabled - Page request queue disabled
Expand Down Expand Up @@ -3647,6 +3647,27 @@ main(void) {
fail_if( ( rsp.trsp.mrif_nid != 0x412 ) );
fail_if( ( rsp.trsp.dest_mrif_addr != (msipte.mrif.MRIF_ADDR_55_9 * 512)) );

req.device_id = 0x121679;
req.pid_valid = 0;
req.is_cxl_dev = 0;
req.tr.at = ADDR_TYPE_UNTRANSLATED;
req.tr.length = 64;
req.tr.read_writeAMO = READ;
req.tr.iova = gpa;

tr_req_ctrl.DID = 0x121679;
tr_req_ctrl.PV = 0;
tr_req_ctrl.PID = 0;
tr_req_ctrl.Priv = 0;
tr_req_ctrl.NW = 1;
tr_req_ctrl.go_busy = 1;
tr_req_iova.raw = gpa;
write_register(TR_REQ_IOVA_OFFSET, 8, tr_req_iova.raw);
write_register(TR_REQ_CTRL_OFFSET, 8, tr_req_ctrl.raw);
tr_response.raw = read_register(TR_RESPONSE_OFFSET, 8);
fail_if( ( tr_response.fault == 0 ) );
fail_if( ( check_faults(260, tr_req_ctrl.PV, tr_req_ctrl.PID, tr_req_ctrl.Priv, 0x121679, gpa, UNTRANSLATED_READ_TRANSACTION, 0) < 0 ) );

END_TEST();

START_TEST("Illegal commands and CQ mem faults");
Expand Down
4 changes: 2 additions & 2 deletions iommu_ref_model/test/test_app.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ extern void send_translation_request(uint32_t did, uint8_t pid_valid, uint32_t p
hb_to_iommu_req_t *req, iommu_to_hb_rsp_t *rsp);
extern int8_t check_rsp_and_faults(hb_to_iommu_req_t *req, iommu_to_hb_rsp_t *rsp, status_t status,
uint16_t cause, uint64_t exp_iotval2);
extern int8_t check_msg_faults(uint16_t cause, uint8_t exp_PV, uint32_t exp_PID,
uint8_t exp_PRIV, uint32_t exp_DID, uint64_t exp_iotval);
extern int8_t check_faults(uint16_t cause, uint8_t exp_PV, uint32_t exp_PID,
uint8_t exp_PRIV, uint32_t exp_DID, uint64_t exp_iotval, uint8_t ttyp, uint64_t exp_iotval2);
extern int8_t check_exp_pq_rec(uint32_t DID, uint32_t PID, uint8_t PV, uint8_t PRIV, uint8_t EXEC,
uint16_t reserved0, uint8_t reserved1, uint64_t PAYLOAD);
extern uint64_t get_free_gppn(uint64_t num_gppn, iohgatp_t iohgatp);
Expand Down
35 changes: 6 additions & 29 deletions iommu_ref_model/test/test_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,9 @@ check_exp_pq_rec(uint32_t DID, uint32_t PID, uint8_t PV, uint8_t PRIV, uint8_t E
return 0;
}
int8_t
check_msg_faults(
check_faults(
uint16_t cause, uint8_t exp_PV, uint32_t exp_PID, uint8_t exp_PRIV,
uint32_t exp_DID, uint64_t exp_iotval) {
uint32_t exp_DID, uint64_t exp_iotval, uint8_t ttyp, uint64_t exp_iotval2) {
fault_rec_t fault_rec;
fqb_t fqb;
fqh_t fqh;
Expand All @@ -233,8 +233,8 @@ check_msg_faults(

if ( fault_rec.CAUSE != cause || fault_rec.DID != exp_DID ||
fault_rec.iotval != exp_iotval ||
fault_rec.iotval2 != 0 ||
fault_rec.TTYP != PCIE_MESSAGE_REQUEST ||
fault_rec.iotval2 != exp_iotval2 ||
fault_rec.TTYP != ttyp ||
fault_rec.reserved != 0 ) {
printf("Bad fault record\n");
return -1;
Expand All @@ -255,8 +255,6 @@ check_rsp_and_faults(
uint16_t cause,
uint64_t exp_iotval2) {

fault_rec_t fault_rec;
fqb_t fqb;
fqh_t fqh;
uint8_t EXP_TTYP;

Expand Down Expand Up @@ -292,29 +290,8 @@ check_rsp_and_faults(
}

if ( cause == 0 ) return 0;

fqb.raw = read_register(FQB_OFFSET, 8);
read_memory(((fqb.ppn * PAGESIZE) | (fqh.index * FQ_ENTRY_SZ)), FQ_ENTRY_SZ, (char *)&fault_rec);

// pop the fault record
fqh.index++;
write_register(FQH_OFFSET, 4, fqh.raw);

if ( fault_rec.CAUSE != cause || fault_rec.DID != req->device_id ||
fault_rec.iotval != req->tr.iova ||
fault_rec.iotval2 != exp_iotval2 ||
fault_rec.TTYP != EXP_TTYP ||
fault_rec.reserved != 0 ) {
printf("Bad fault record\n");
return -1;
}
if ( (req->pid_valid != fault_rec.PV) ||
(req->pid_valid && ((fault_rec.PID != req->process_id) ||
(fault_rec.PRIV != req->priv_req))) ) {
printf("Bad fault record\n");
return -1;
}
return 0;
return check_faults(cause, req->pid_valid, req->process_id, req->priv_req,
req->device_id, req->tr.iova, EXP_TTYP, exp_iotval2);
}
uint64_t
add_device(uint32_t device_id, uint32_t gscid, uint8_t en_ats, uint8_t en_pri, uint8_t t2gpa,
Expand Down

0 comments on commit b58ee7f

Please sign in to comment.