Commit b3315e6c authored by Junxian Huang's avatar Junxian Huang Committed by Zihao Xue
Browse files

RDMA/hns: Fix incorrect iteration number of DCA umem sg entries

driver inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I9FAYN



------------------------------------

RDMA uses sg list to describe umem buffer. While mapping IOVA in IOMMU,
an sg entry may be concatenated with the previous entry if certain length
and boundary conditions are met. IOMMU will always return the number of
sg entries after the concatenation, and the dma address of a concatenated
entry defaults to DMA_MAPPING_ERROR (0xFFFFFFFFFFFFFFFF).

But currently in DCA mode, hns RoCE driver still use the originally
allocated number of the sg entries to iterate sg list. This causes
that the driver may access the concatenated sg entries and fill
DMA_MAPPING_ERROR to HW, triggering SMMU translation fault and RAS.

Use the entry number returned by IOMMU to set the maximum iteration
number of DCA umem sg entries to fix this problem, instead of the
originally allocated number.

Fixes: 12aa71f8 ("RDMA/hns: Add DCA support for kernel space")
Fixes: f44a2f97 ("RDMA/hns: Introduce DCA for RC QP")
Signed-off-by: default avatarJunxian Huang <huangjunxian6@hisilicon.com>
Signed-off-by: default avatarZihao Xue <xuezihao@huawei.com>
parent c62ceef8
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -175,8 +175,7 @@ static void init_dca_umem_states(struct hns_dca_page_state *states, int count,
	int i = 0;

	pre_addr = 0;
	rdma_for_each_block(umem->sg_head.sgl, &biter,
			    umem->sg_head.nents, HNS_HW_PAGE_SIZE) {
	rdma_umem_for_each_dma_block(umem, &biter, HNS_HW_PAGE_SIZE) {
		cur_addr = rdma_block_iter_dma_address(&biter);
		if (i < count) {
			if (cur_addr - pre_addr != HNS_HW_PAGE_SIZE)
@@ -276,8 +275,7 @@ static int get_alloced_umem_proc(struct dca_mem *mem, int index, void *param)
	struct ib_block_iter biter;
	u32 i = 0;

	rdma_for_each_block(umem->sg_head.sgl, &biter,
			    umem->sg_head.nents, HNS_HW_PAGE_SIZE) {
	rdma_umem_for_each_dma_block(umem, &biter, HNS_HW_PAGE_SIZE) {
		if (dca_page_is_allocated(&states[i], attr->buf_id)) {
			attr->pages[attr->total++] =
					rdma_block_iter_dma_address(&biter);