diff --git a/kernel/include/hfi1/hfi1_generated_devdata.h b/kernel/include/hfi1/hfi1_generated_devdata.h index e5eb2f05..605e7a9a 100644 --- a/kernel/include/hfi1/hfi1_generated_devdata.h +++ b/kernel/include/hfi1/hfi1_generated_devdata.h @@ -34,19 +34,31 @@ struct hfi1_devdata { void *rcvarray_wc; }; struct { - char padding8[3688]; + char padding8[3648]; + long unsigned int *events; + }; + struct { + char padding9[3684]; + u32 chip_rcv_contexts; + }; + struct { + char padding10[3688]; u32 chip_rcv_array_count; }; struct { - char padding9[6872]; + char padding11[6872]; struct hfi1_pportdata *pport; }; struct { - char padding10[6896]; + char padding12[6896]; u16 flags; }; struct { - char padding11[6920]; + char padding13[6899]; + u8 first_user_ctxt; + }; + struct { + char padding14[6920]; u64 sc2vl[4]; }; }; diff --git a/kernel/include/hfi1/hfi1_generated_filedata.h b/kernel/include/hfi1/hfi1_generated_filedata.h index 1177021e..3a2ce3d2 100644 --- a/kernel/include/hfi1/hfi1_generated_filedata.h +++ b/kernel/include/hfi1/hfi1_generated_filedata.h @@ -33,5 +33,17 @@ struct hfi1_filedata { char padding7[72]; u32 tid_used; }; + struct { + char padding8[80]; + u32 *invalid_tids; + }; + struct { + char padding9[88]; + u32 invalid_tid_idx; + }; + struct { + char padding10[92]; + spinlock_t invalid_lock; + }; }; }; diff --git a/kernel/include/process.h b/kernel/include/process.h index 89b39da8..add59923 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -582,6 +582,7 @@ struct process { void *hfi1_rcvarray_wc; size_t hfi1_rcvarray_wc_len; void *hfi1_cq_comps; + void *hfi1_events; size_t hfi1_cq_comps_len; ihk_spinlock_t hfi1_lock; }; diff --git a/kernel/script/regenerate_hfi1_header.sh b/kernel/script/regenerate_hfi1_header.sh index 2b1ec48e..d93a4d1c 100755 --- a/kernel/script/regenerate_hfi1_header.sh +++ b/kernel/script/regenerate_hfi1_header.sh @@ -37,8 +37,10 @@ HFI1_KO="${1-$(modinfo -n hfi1)}" || \ "$DES_BIN" "$HFI1_KO" hfi1_devdata \ per_sdma sdma_pad_phys sdma_map pport chip_rcv_array_count \ kregbase1 piobase physaddr rcvarray_wc default_desc1 flags \ - sc2vl > "${HDR_PREFIX}devdata.h" + sc2vl events first_user_ctxt chip_rcv_contexts \ + > "${HDR_PREFIX}devdata.h" "$DES_BIN" "$HFI1_KO" hfi1_filedata \ - uctxt pq cq dd subctxt entry_to_rb tid_lock tid_used \ + uctxt pq cq dd subctxt entry_to_rb tid_lock tid_used \ + invalid_tids invalid_tid_idx invalid_lock \ > "${HDR_PREFIX}filedata.h" diff --git a/kernel/user_sdma.c b/kernel/user_sdma.c index 4eba3ab8..485bcbcf 100644 --- a/kernel/user_sdma.c +++ b/kernel/user_sdma.c @@ -789,6 +789,60 @@ int hfi1_map_device_addresses(struct hfi1_filedata *fd) proc->hfi1_cq_comps_len = len; } + if (proc->hfi1_events != dd->events) { + void *hfi1_events = dd->events; + len = (dd->chip_rcv_contexts * HFI1_MAX_SHARED_CTXTS * + sizeof(*dd->events) + PAGE_SIZE - 1) & PAGE_MASK; + + /* + * Events are in Linux vmalloc area, we need to + * resolve physical addresses by looking at Linux + * page tables. + */ + for (virt = hfi1_events; virt < hfi1_events + len; + virt += PAGE_SIZE) { + + lptep = ihk_mc_pt_lookup_pte(ihk_mc_get_linux_kernel_pgt(), + virt, 0, 0, 0, 0); + if (!lptep && !pte_is_present(lptep)) { + kprintf("%s: ERROR: no mapping in Linux for events: 0x%lx?\n", + __FUNCTION__, virt); + ret = -1; + goto unlock_out; + } + + phys = pte_get_phys(lptep); + if (ihk_mc_pt_set_page(vm->address_space->page_table, + virt, phys, attr) < 0) { + kprintf("%s: ERROR: failed to map events: 0x%lx -> 0x%lx\n", + __FUNCTION__, virt, phys); + ret = -1; + goto unlock_out; + } + + ptep = ihk_mc_pt_lookup_pte(vm->address_space->page_table, + virt, 0, 0, 0, 0); + if (!ptep && !pte_is_present(ptep)) { + kprintf("%s: ERROR: no mapping in McKernel for events: 0x%lx?\n", + __FUNCTION__, virt); + ret = -1; + goto unlock_out; + } + + *ptep = *lptep; + } + + dkprintf("%s: hfi1_events: 0x%lx - 0x%lx\n", + __FUNCTION__, + hfi1_events, + hfi1_events + len); + //ihk_mc_pt_print_pte(vm->address_space->page_table, hfi1_events); + + proc->hfi1_events = hfi1_events; + } + + flush_tlb(); + unlock_out: ihk_mc_spinlock_unlock(&proc->hfi1_lock, irqstate);