diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 59e95341f9b1..4d319c50955e 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -965,12 +966,22 @@ static void netvsc_copy_to_send_buf(struct netvsc_device *net_device, } for (i = 0; i < page_count; i++) { - char *src = phys_to_virt(pb[i].pfn << HV_HYP_PAGE_SHIFT); - u32 offset = pb[i].offset; + phys_addr_t paddr = (pb[i].pfn << HV_HYP_PAGE_SHIFT) + + pb[i].offset; u32 len = pb[i].len; - memcpy(dest, (src + offset), len); - dest += len; + while (len) { + struct page *page = phys_to_page(paddr); + u32 off = offset_in_page(paddr); + u32 chunk = min_t(u32, len, PAGE_SIZE - off); + char *src = kmap_local_page(page); + + memcpy(dest, src + off, chunk); + kunmap_local(src); + dest += chunk; + paddr += chunk; + len -= chunk; + } } if (padding)