aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hv/channel.c20
-rw-r--r--drivers/uio/uio_hv_generic.c5
-rw-r--r--include/linux/hyperv.h2
3 files changed, 13 insertions, 14 deletions
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index 33e6db02dbab..56ec0d96d876 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -91,11 +91,14 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
91 unsigned long flags; 91 unsigned long flags;
92 int ret, err = 0; 92 int ret, err = 0;
93 struct page *page; 93 struct page *page;
94 unsigned int order;
94 95
95 if (send_ringbuffer_size % PAGE_SIZE || 96 if (send_ringbuffer_size % PAGE_SIZE ||
96 recv_ringbuffer_size % PAGE_SIZE) 97 recv_ringbuffer_size % PAGE_SIZE)
97 return -EINVAL; 98 return -EINVAL;
98 99
100 order = get_order(send_ringbuffer_size + recv_ringbuffer_size);
101
99 spin_lock_irqsave(&newchannel->lock, flags); 102 spin_lock_irqsave(&newchannel->lock, flags);
100 if (newchannel->state == CHANNEL_OPEN_STATE) { 103 if (newchannel->state == CHANNEL_OPEN_STATE) {
101 newchannel->state = CHANNEL_OPENING_STATE; 104 newchannel->state = CHANNEL_OPENING_STATE;
@@ -110,21 +113,17 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
110 113
111 /* Allocate the ring buffer */ 114 /* Allocate the ring buffer */
112 page = alloc_pages_node(cpu_to_node(newchannel->target_cpu), 115 page = alloc_pages_node(cpu_to_node(newchannel->target_cpu),
113 GFP_KERNEL|__GFP_ZERO, 116 GFP_KERNEL|__GFP_ZERO, order);
114 get_order(send_ringbuffer_size +
115 recv_ringbuffer_size));
116 117
117 if (!page) 118 if (!page)
118 page = alloc_pages(GFP_KERNEL|__GFP_ZERO, 119 page = alloc_pages(GFP_KERNEL|__GFP_ZERO, order);
119 get_order(send_ringbuffer_size +
120 recv_ringbuffer_size));
121 120
122 if (!page) { 121 if (!page) {
123 err = -ENOMEM; 122 err = -ENOMEM;
124 goto error_set_chnstate; 123 goto error_set_chnstate;
125 } 124 }
126 125
127 newchannel->ringbuffer_pages = page_address(page); 126 newchannel->ringbuffer_page = page;
128 newchannel->ringbuffer_pagecount = (send_ringbuffer_size + 127 newchannel->ringbuffer_pagecount = (send_ringbuffer_size +
129 recv_ringbuffer_size) >> PAGE_SHIFT; 128 recv_ringbuffer_size) >> PAGE_SHIFT;
130 129
@@ -239,8 +238,7 @@ error_free_gpadl:
239error_free_pages: 238error_free_pages:
240 hv_ringbuffer_cleanup(&newchannel->outbound); 239 hv_ringbuffer_cleanup(&newchannel->outbound);
241 hv_ringbuffer_cleanup(&newchannel->inbound); 240 hv_ringbuffer_cleanup(&newchannel->inbound);
242 __free_pages(page, 241 __free_pages(page, order);
243 get_order(send_ringbuffer_size + recv_ringbuffer_size));
244error_set_chnstate: 242error_set_chnstate:
245 newchannel->state = CHANNEL_OPEN_STATE; 243 newchannel->state = CHANNEL_OPEN_STATE;
246 return err; 244 return err;
@@ -658,8 +656,8 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
658 hv_ringbuffer_cleanup(&channel->outbound); 656 hv_ringbuffer_cleanup(&channel->outbound);
659 hv_ringbuffer_cleanup(&channel->inbound); 657 hv_ringbuffer_cleanup(&channel->inbound);
660 658
661 free_pages((unsigned long)channel->ringbuffer_pages, 659 __free_pages(channel->ringbuffer_page,
662 get_order(channel->ringbuffer_pagecount * PAGE_SIZE)); 660 get_order(channel->ringbuffer_pagecount << PAGE_SHIFT));
663 661
664out: 662out:
665 return ret; 663 return ret;
diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c
index a08860260f55..ba67a5267557 100644
--- a/drivers/uio/uio_hv_generic.c
+++ b/drivers/uio/uio_hv_generic.c
@@ -130,11 +130,12 @@ static int hv_uio_ring_mmap(struct file *filp, struct kobject *kobj,
130 = container_of(kobj, struct vmbus_channel, kobj); 130 = container_of(kobj, struct vmbus_channel, kobj);
131 struct hv_device *dev = channel->primary_channel->device_obj; 131 struct hv_device *dev = channel->primary_channel->device_obj;
132 u16 q_idx = channel->offermsg.offer.sub_channel_index; 132 u16 q_idx = channel->offermsg.offer.sub_channel_index;
133 void *ring_buffer = page_address(channel->ringbuffer_page);
133 134
134 dev_dbg(&dev->device, "mmap channel %u pages %#lx at %#lx\n", 135 dev_dbg(&dev->device, "mmap channel %u pages %#lx at %#lx\n",
135 q_idx, vma_pages(vma), vma->vm_pgoff); 136 q_idx, vma_pages(vma), vma->vm_pgoff);
136 137
137 return vm_iomap_memory(vma, virt_to_phys(channel->ringbuffer_pages), 138 return vm_iomap_memory(vma, virt_to_phys(ring_buffer),
138 channel->ringbuffer_pagecount << PAGE_SHIFT); 139 channel->ringbuffer_pagecount << PAGE_SHIFT);
139} 140}
140 141
@@ -223,7 +224,7 @@ hv_uio_probe(struct hv_device *dev,
223 /* mem resources */ 224 /* mem resources */
224 pdata->info.mem[TXRX_RING_MAP].name = "txrx_rings"; 225 pdata->info.mem[TXRX_RING_MAP].name = "txrx_rings";
225 pdata->info.mem[TXRX_RING_MAP].addr 226 pdata->info.mem[TXRX_RING_MAP].addr
226 = (uintptr_t)dev->channel->ringbuffer_pages; 227 = (uintptr_t)page_address(dev->channel->ringbuffer_page);
227 pdata->info.mem[TXRX_RING_MAP].size 228 pdata->info.mem[TXRX_RING_MAP].size
228 = dev->channel->ringbuffer_pagecount << PAGE_SHIFT; 229 = dev->channel->ringbuffer_pagecount << PAGE_SHIFT;
229 pdata->info.mem[TXRX_RING_MAP].memtype = UIO_MEM_LOGICAL; 230 pdata->info.mem[TXRX_RING_MAP].memtype = UIO_MEM_LOGICAL;
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 6c4575c7f46b..a6c32d2d090b 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -739,7 +739,7 @@ struct vmbus_channel {
739 u32 ringbuffer_gpadlhandle; 739 u32 ringbuffer_gpadlhandle;
740 740
741 /* Allocated memory for ring buffer */ 741 /* Allocated memory for ring buffer */
742 void *ringbuffer_pages; 742 struct page *ringbuffer_page;
743 u32 ringbuffer_pagecount; 743 u32 ringbuffer_pagecount;
744 struct hv_ring_buffer_info outbound; /* send to parent */ 744 struct hv_ring_buffer_info outbound; /* send to parent */
745 struct hv_ring_buffer_info inbound; /* receive from parent */ 745 struct hv_ring_buffer_info inbound; /* receive from parent */