From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <zhouyates@gmail.com>
Received: from mail-pf1-f194.google.com (mail-pf1-f194.google.com
 [209.85.210.194]) by dpdk.org (Postfix) with ESMTP id 2214E1B144
 for <dev@dpdk.org>; Thu, 28 Feb 2019 08:31:14 +0100 (CET)
Received: by mail-pf1-f194.google.com with SMTP id a3so9284152pff.11
 for <dev@dpdk.org>; Wed, 27 Feb 2019 23:31:14 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=from:to:cc:subject:date:message-id:mime-version
 :content-transfer-encoding;
 bh=it8EHW7omzkUZo7h84MTpjLxuQGabDm1aIm2vQvtEO8=;
 b=J5/yDsK3DaWrvyo/NU9r6haerQ2PJGQEIbTP1gyLia7hvVH2MaLVhi9Ln0pKWSbcv+
 i7eHExuPrdNF+Rq2S9xa0J04p5cwDavvIMGSa26IVlOaup8kKtJCMlUJQdTDbb08JRFy
 G8MJ4hx3rnc3RvCJ/4WPB7fJ4hgfbcOKal50CAj547R7a12AjVDhy5mV68AIYDmPkyPH
 iY1Bx+TAFLvaPsfLEHDV1kklqoq1WPi7LfygWVwde4flxMIAtV5pRwIQOIXe2Y4YHenr
 J/ISLvsYbnYa4OMPSB+vFS7zxFQ4UPoIqVKkkWgH60UOJyEuo4l7zxLMRNAEotN6ommi
 yiOg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version
 :content-transfer-encoding;
 bh=it8EHW7omzkUZo7h84MTpjLxuQGabDm1aIm2vQvtEO8=;
 b=gJ+oAhSp6Z4bxmWDwOT0LyjVFJDK501fQJ2nj22Ht/vEQca3OFtSCV1ib9CtUM3Otq
 fpfEufFvHmASrbQxesCdCDoKPAvvFR3r+OoBJXvsii+BN1CbZwFUixKLCmBf8FgHqaKd
 b5i3pIG1Qge+SHnydjal7jjdRKY8JiTu6kvOxaSU5Qh5bWRbKv9Lu/8qzbxDUXOIPIXN
 CuFgGui8i2rWBakEv8TbRt3MoB/m45qXmnPpdOBYFr2aTZcd9PixJhqIPuDu1QADzeIR
 udXM3WwJ4Sj7I/e5I+4muecED4uvifng/DXl4EfaoFEU+HHRN8v1/O4glPTnLarPyU2X
 PreQ==
X-Gm-Message-State: APjAAAUACjS0MSB97LpoSUTvfRQnbn/R0S4wXVIJttrPrFZwXZvAIPJQ
 MPMIQhM0c7OFeOXZ61Kqzm5yPTTz0zOPXA==
X-Google-Smtp-Source: AHgI3IZdlnqrGd4DfdgfxlkES77nvcmvIIVmDniOf+bi72G79z67qCmbdQ8wjjViVB/Xn8/LSB6Krw==
X-Received: by 2002:a62:5959:: with SMTP id n86mr875940pfb.237.1551339072953; 
 Wed, 27 Feb 2019 23:31:12 -0800 (PST)
Received: from yateszhou-PC0.tencent.com ([203.205.141.47])
 by smtp.gmail.com with ESMTPSA id l184sm24990176pfc.41.2019.02.27.23.31.11
 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
 Wed, 27 Feb 2019 23:31:12 -0800 (PST)
From: Yangchao Zhou <zhouyates@gmail.com>
To: dev@dpdk.org
Cc: ferruh.yigit@intel.com
Date: Thu, 28 Feb 2019 15:30:10 +0800
Message-Id: <20190228073010.49716-1-zhouyates@gmail.com>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Subject: [dpdk-dev] [PATCH] kni: fix possible kernel crash with va2pa
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
X-List-Received-Date: Thu, 28 Feb 2019 07:31:14 -0000

va2pa depends on the physical address and virtual address offset of
current mbuf. It may get the wrong physical address of next mbuf which
allocated in another hugepage segment.

Signed-off-by: Yangchao Zhou <zhouyates@gmail.com>
---
 kernel/linux/kni/kni_net.c                       | 16 ++--------------
 .../eal/include/exec-env/rte_kni_common.h        |  4 ++++
 lib/librte_kni/rte_kni.c                         | 15 ++++++++++++++-
 3 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/kernel/linux/kni/kni_net.c b/kernel/linux/kni/kni_net.c
index 7371b6d58..caef8754f 100644
--- a/kernel/linux/kni/kni_net.c
+++ b/kernel/linux/kni/kni_net.c
@@ -61,18 +61,6 @@ kva2data_kva(struct rte_kni_mbuf *m)
 	return phys_to_virt(m->buf_physaddr + m->data_off);
 }
 
-/* virtual address to physical address */
-static void *
-va2pa(void *va, struct rte_kni_mbuf *m)
-{
-	void *pa;
-
-	pa = (void *)((unsigned long)va -
-			((unsigned long)m->buf_addr -
-			 (unsigned long)m->buf_physaddr));
-	return pa;
-}
-
 /*
  * It can be called to process the request.
  */
@@ -363,7 +351,7 @@ kni_net_rx_normal(struct kni_dev *kni)
 				if (!kva->next)
 					break;
 
-				kva = pa2kva(va2pa(kva->next, kva));
+				kva = pa2kva(kva->next_pa);
 				data_kva = kva2data_kva(kva);
 			}
 		}
@@ -545,7 +533,7 @@ kni_net_rx_lo_fifo_skb(struct kni_dev *kni)
 				if (!kva->next)
 					break;
 
-				kva = pa2kva(va2pa(kva->next, kva));
+				kva = pa2kva(kva->next_pa);
 				data_kva = kva2data_kva(kva);
 			}
 		}
diff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
index 5afa08713..608f5c13f 100644
--- a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
+++ b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
@@ -87,6 +87,10 @@ struct rte_kni_mbuf {
 	char pad3[8] __attribute__((__aligned__(RTE_CACHE_LINE_MIN_SIZE)));
 	void *pool;
 	void *next;
+	union {
+		uint64_t tx_offload;
+		void *next_pa;      /**< Physical address of next mbuf. */
+	};
 };
 
 /*
diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c
index 73aeccccf..1aaebcfa1 100644
--- a/lib/librte_kni/rte_kni.c
+++ b/lib/librte_kni/rte_kni.c
@@ -353,6 +353,17 @@ va2pa(struct rte_mbuf *m)
 			 (unsigned long)m->buf_iova));
 }
 
+static void *
+va2pa_all(struct rte_mbuf *m)
+{
+	struct rte_kni_mbuf *mbuf = (struct rte_kni_mbuf *)m;
+	while (mbuf->next) {
+		mbuf->next_pa = va2pa(mbuf->next);
+		mbuf = mbuf->next;
+	}
+	return va2pa(m);
+}
+
 static void
 obj_free(struct rte_mempool *mp __rte_unused, void *opaque, void *obj,
 		unsigned obj_idx __rte_unused)
@@ -550,7 +561,7 @@ rte_kni_tx_burst(struct rte_kni *kni, struct rte_mbuf **mbufs, unsigned num)
 	unsigned int i;
 
 	for (i = 0; i < num; i++)
-		phy_mbufs[i] = va2pa(mbufs[i]);
+		phy_mbufs[i] = va2pa_all(mbufs[i]);
 
 	ret = kni_fifo_put(kni->rx_q, phy_mbufs, num);
 
@@ -607,6 +618,8 @@ kni_allocate_mbufs(struct rte_kni *kni)
 			 offsetof(struct rte_kni_mbuf, pkt_len));
 	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, ol_flags) !=
 			 offsetof(struct rte_kni_mbuf, ol_flags));
+	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, tx_offload) !=
+			 offsetof(struct rte_kni_mbuf, tx_offload));
 
 	/* Check if pktmbuf pool has been configured */
 	if (kni->pktmbuf_pool == NULL) {
-- 
2.19.1.windows.1