Inter-revision diff: patch 10

Comparing v3 (message) to v4 (message)

--- v3
+++ v4
@@ -11,10 +11,10 @@
 Signed-off-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
 ---
  drivers/net/hyperv/hyperv_net.h   |   6 ++
- drivers/net/hyperv/netvsc.c       | 125 ++++++++++++++++++++++++++++--
- drivers/net/hyperv/rndis_filter.c |   3 +
+ drivers/net/hyperv/netvsc.c       | 144 +++++++++++++++++++++++++++++-
+ drivers/net/hyperv/rndis_filter.c |   2 +
  include/linux/hyperv.h            |   5 ++
- 4 files changed, 133 insertions(+), 6 deletions(-)
+ 4 files changed, 154 insertions(+), 3 deletions(-)
 
 diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
 index b11aa68b44ec..c2fbb9d4df2c 100644
@@ -53,7 +53,7 @@
 +		      struct hv_netvsc_packet *packet);
  #endif /* _HYPERV_NET_H */
 diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
-index 7bd935412853..a01740c6c6b8 100644
+index 7bd935412853..fc312e5db4d5 100644
 --- a/drivers/net/hyperv/netvsc.c
 +++ b/drivers/net/hyperv/netvsc.c
 @@ -153,8 +153,21 @@ static void free_netvsc_device(struct rcu_head *head)
@@ -80,32 +80,51 @@
  	kfree(nvdev->send_section_map);
  
  	for (i = 0; i < VRSS_CHANNEL_MAX; i++) {
-@@ -338,8 +351,10 @@ static int netvsc_init_buf(struct hv_device *device,
- 	struct net_device *ndev = hv_get_drvdata(device);
- 	struct nvsp_message *init_packet;
+@@ -330,6 +343,27 @@ int netvsc_alloc_recv_comp_ring(struct netvsc_device *net_device, u32 q_idx)
+ 	return nvchan->mrc.slots ? 0 : -ENOMEM;
+ }
+ 
++static void *netvsc_remap_buf(void *buf, unsigned long size)
++{
++	unsigned long *pfns;
++	void *vaddr;
++	int i;
++
++	pfns = kcalloc(size / HV_HYP_PAGE_SIZE, sizeof(unsigned long),
++		       GFP_KERNEL);
++	if (!pfns)
++		return NULL;
++
++	for (i = 0; i < size / HV_HYP_PAGE_SIZE; i++)
++		pfns[i] = virt_to_hvpfn(buf + i * HV_HYP_PAGE_SIZE)
++			+ (ms_hyperv.shared_gpa_boundary >> HV_HYP_PAGE_SHIFT);
++
++	vaddr = vmap_pfn(pfns, size / HV_HYP_PAGE_SIZE, PAGE_KERNEL_IO);
++	kfree(pfns);
++
++	return vaddr;
++}
++
+ static int netvsc_init_buf(struct hv_device *device,
+ 			   struct netvsc_device *net_device,
+ 			   const struct netvsc_device_info *device_info)
+@@ -340,6 +374,7 @@ static int netvsc_init_buf(struct hv_device *device,
  	unsigned int buf_size;
-+	unsigned long *pfns;
  	size_t map_words;
  	int i, ret = 0;
 +	void *vaddr;
  
  	/* Get receive buffer area. */
  	buf_size = device_info->recv_sections * device_info->recv_section_size;
-@@ -375,6 +390,21 @@ static int netvsc_init_buf(struct hv_device *device,
+@@ -375,6 +410,15 @@ static int netvsc_init_buf(struct hv_device *device,
  		goto cleanup;
  	}
  
 +	if (hv_isolation_type_snp()) {
-+		pfns = kcalloc(buf_size / HV_HYP_PAGE_SIZE, sizeof(unsigned long),
-+			       GFP_KERNEL);
-+		for (i = 0; i < buf_size / HV_HYP_PAGE_SIZE; i++)
-+			pfns[i] = virt_to_hvpfn(net_device->recv_buf + i * HV_HYP_PAGE_SIZE) +
-+				(ms_hyperv.shared_gpa_boundary >> HV_HYP_PAGE_SHIFT);
-+
-+		vaddr = vmap_pfn(pfns, buf_size / HV_HYP_PAGE_SIZE, PAGE_KERNEL_IO);
-+		kfree(pfns);
++		vaddr = netvsc_remap_buf(net_device->recv_buf, buf_size);
 +		if (!vaddr)
 +			goto cleanup;
++
 +		net_device->recv_original_buf = net_device->recv_buf;
 +		net_device->recv_buf = vaddr;
 +	}
@@ -113,20 +132,12 @@
  	/* Notify the NetVsp of the gpadl handle */
  	init_packet = &net_device->channel_init_pkt;
  	memset(init_packet, 0, sizeof(struct nvsp_message));
-@@ -477,6 +507,23 @@ static int netvsc_init_buf(struct hv_device *device,
+@@ -477,6 +521,15 @@ static int netvsc_init_buf(struct hv_device *device,
  		goto cleanup;
  	}
  
 +	if (hv_isolation_type_snp()) {
-+		pfns = kcalloc(buf_size / HV_HYP_PAGE_SIZE, sizeof(unsigned long),
-+			       GFP_KERNEL);
-+
-+		for (i = 0; i < buf_size / HV_HYP_PAGE_SIZE; i++)
-+			pfns[i] = virt_to_hvpfn(net_device->send_buf + i * HV_HYP_PAGE_SIZE)
-+				+ (ms_hyperv.shared_gpa_boundary >> HV_HYP_PAGE_SHIFT);
-+
-+		vaddr = vmap_pfn(pfns, buf_size / HV_HYP_PAGE_SIZE, PAGE_KERNEL_IO);
-+		kfree(pfns);
++		vaddr = netvsc_remap_buf(net_device->send_buf, buf_size);
 +		if (!vaddr)
 +			goto cleanup;
 +
@@ -137,7 +148,7 @@
  	/* Notify the NetVsp of the gpadl handle */
  	init_packet = &net_device->channel_init_pkt;
  	memset(init_packet, 0, sizeof(struct nvsp_message));
-@@ -767,7 +814,7 @@ static void netvsc_send_tx_complete(struct net_device *ndev,
+@@ -767,7 +820,7 @@ static void netvsc_send_tx_complete(struct net_device *ndev,
  
  	/* Notify the layer above us */
  	if (likely(skb)) {
@@ -146,7 +157,7 @@
  			= (struct hv_netvsc_packet *)skb->cb;
  		u32 send_index = packet->send_buf_index;
  		struct netvsc_stats *tx_stats;
-@@ -783,6 +830,7 @@ static void netvsc_send_tx_complete(struct net_device *ndev,
+@@ -783,6 +836,7 @@ static void netvsc_send_tx_complete(struct net_device *ndev,
  		tx_stats->bytes += packet->total_bytes;
  		u64_stats_update_end(&tx_stats->syncp);
  
@@ -154,7 +165,7 @@
  		napi_consume_skb(skb, budget);
  	}
  
-@@ -947,6 +995,63 @@ static void netvsc_copy_to_send_buf(struct netvsc_device *net_device,
+@@ -947,6 +1001,82 @@ static void netvsc_copy_to_send_buf(struct netvsc_device *net_device,
  		memset(dest, 0, padding);
  }
  
@@ -166,6 +177,9 @@
 +		packet->page_buf_cnt;
 +	int i;
 +
++	if (!hv_is_isolation_supported())
++		return;
++
 +	if (!packet->dma_range)
 +		return;
 +
@@ -177,6 +191,19 @@
 +	kfree(packet->dma_range);
 +}
 +
++/* netvsc_dma_map - Map swiotlb bounce buffer with data page of
++ * packet sent by vmbus_sendpacket_pagebuffer() in the Isolation
++ * VM.
++ *
++ * In isolation VM, netvsc send buffer has been marked visible to
++ * host and so the data copied to send buffer doesn't need to use
++ * bounce buffer. The data pages handled by vmbus_sendpacket_pagebuffer()
++ * may not be copied to send buffer and so these pages need to be
++ * mapped with swiotlb bounce buffer. netvsc_dma_map() is to do
++ * that. The pfns in the struct hv_page_buffer need to be converted
++ * to bounce buffer's pfn. The loop here is necessary and so not
++ * use dma_map_sg() here.
++ */
 +int netvsc_dma_map(struct hv_device *hv_dev,
 +		   struct hv_netvsc_packet *packet,
 +		   struct hv_page_buffer *pb)
@@ -187,6 +214,9 @@
 +	dma_addr_t dma;
 +	int i;
 +
++	if (!hv_is_isolation_supported())
++		return 0;
++
 +	packet->dma_range = kcalloc(page_count,
 +				    sizeof(*packet->dma_range),
 +				    GFP_KERNEL);
@@ -218,7 +248,7 @@
  static inline int netvsc_send_pkt(
  	struct hv_device *device,
  	struct hv_netvsc_packet *packet,
-@@ -987,14 +1092,22 @@ static inline int netvsc_send_pkt(
+@@ -987,14 +1117,22 @@ static inline int netvsc_send_pkt(
  
  	trace_nvsp_send_pkt(ndev, out_channel, rpkt);
  
@@ -232,12 +262,9 @@
 +			return ret;
 +
  		ret = vmbus_sendpacket_pagebuffer(out_channel,
--						  pb, packet->page_buf_cnt,
--						  &nvmsg, sizeof(nvmsg),
--						  req_id);
-+					  pb, packet->page_buf_cnt,
-+					  &nvmsg, sizeof(nvmsg),
-+					  req_id);
+ 						  pb, packet->page_buf_cnt,
+ 						  &nvmsg, sizeof(nvmsg),
+ 						  req_id);
 +
 +		if (ret)
 +			netvsc_dma_unmap(ndev_ctx->device_ctx, packet);
@@ -245,23 +272,15 @@
  		ret = vmbus_sendpacket(out_channel,
  				       &nvmsg, sizeof(nvmsg),
 diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
-index 983bf362466a..448c1ee39246 100644
+index 983bf362466a..9425fee85aa0 100644
 --- a/drivers/net/hyperv/rndis_filter.c
 +++ b/drivers/net/hyperv/rndis_filter.c
-@@ -293,6 +293,8 @@ static void rndis_filter_receive_response(struct net_device *ndev,
- 	u32 *req_id = &resp->msg.init_complete.req_id;
- 	struct rndis_device *dev = nvdev->extension;
- 	struct rndis_request *request = NULL;
-+	struct hv_device *hv_dev = ((struct net_device_context *)
-+			netdev_priv(ndev))->device_ctx;
- 	bool found = false;
- 	unsigned long flags;
- 
-@@ -361,6 +363,7 @@ static void rndis_filter_receive_response(struct net_device *ndev,
+@@ -361,6 +361,8 @@ static void rndis_filter_receive_response(struct net_device *ndev,
  			}
  		}
  
-+		netvsc_dma_unmap(hv_dev, &request->pkt);
++		netvsc_dma_unmap(((struct net_device_context *)
++			netdev_priv(ndev))->device_ctx, &request->pkt);
  		complete(&request->wait_event);
  	} else {
  		netdev_err(ndev,
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help