| From 7250f422da0480d8512b756640f131b9b893ccda Mon Sep 17 00:00:00 2001 |
| From: Joe Jin <joe.jin@oracle.com> |
| Date: Tue, 16 Oct 2018 15:21:16 -0700 |
| Subject: xen-swiotlb: use actually allocated size on check physical continuous |
| |
| From: Joe Jin <joe.jin@oracle.com> |
| |
| commit 7250f422da0480d8512b756640f131b9b893ccda upstream. |
| |
| xen_swiotlb_{alloc,free}_coherent() allocate/free memory based on the |
| order of the pages and not size argument (bytes). This is inconsistent with |
| range_straddles_page_boundary and memset which use the 'size' value, |
| which may lead to not exchanging memory with Xen (range_straddles_page_boundary() |
| returned true). And then the call to xen_swiotlb_free_coherent() would |
| actually try to exchange the memory with Xen, leading to the kernel |
| hitting an BUG (as the hypercall returned an error). |
| |
| This patch fixes it by making the 'size' variable be of the same size |
| as the amount of memory allocated. |
| |
| CC: stable@vger.kernel.org |
| Signed-off-by: Joe Jin <joe.jin@oracle.com> |
| Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> |
| Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com> |
| Cc: Christoph Helwig <hch@lst.de> |
| Cc: Dongli Zhang <dongli.zhang@oracle.com> |
| Cc: John Sobecki <john.sobecki@oracle.com> |
| Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/xen/swiotlb-xen.c | 6 ++++++ |
| 1 file changed, 6 insertions(+) |
| |
| --- a/drivers/xen/swiotlb-xen.c |
| +++ b/drivers/xen/swiotlb-xen.c |
| @@ -310,6 +310,9 @@ xen_swiotlb_alloc_coherent(struct device |
| */ |
| flags &= ~(__GFP_DMA | __GFP_HIGHMEM); |
| |
| + /* Convert the size to actually allocated. */ |
| + size = 1UL << (order + XEN_PAGE_SHIFT); |
| + |
| /* On ARM this function returns an ioremap'ped virtual address for |
| * which virt_to_phys doesn't return the corresponding physical |
| * address. In fact on ARM virt_to_phys only works for kernel direct |
| @@ -359,6 +362,9 @@ xen_swiotlb_free_coherent(struct device |
| * physical address */ |
| phys = xen_bus_to_phys(dev_addr); |
| |
| + /* Convert the size to actually allocated. */ |
| + size = 1UL << (order + XEN_PAGE_SHIFT); |
| + |
| if (((dev_addr + size - 1 <= dma_mask)) || |
| range_straddles_page_boundary(phys, size)) |
| xen_destroy_contiguous_region(phys, order); |