xen_swiotlb_{alloc,free}_coherent() allocate/free memory by order, but passed required size to range_straddles_page_boundary(), when first pages are physical continuous, range_straddles_page_boundary() returned true, then did not exchanged memory with Xen, later on free memory, it tried to exchanged non-contiguous memory with Xen, then kernel panic.
Signed-off-by: Joe Jin <joe....@oracle.com> Cc: Konrad Rzeszutek Wilk <konrad.w...@oracle.com> Cc: Boris Ostrovsky <boris.ostrov...@oracle.com> Cc: Christoph Helwig <h...@lst.de> Cc: Dongli Zhang <dongli.zh...@oracle.com> Cc: John Sobecki <john.sobe...@oracle.com> --- drivers/xen/swiotlb-xen.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index a6f9ba85dc4b..aa081f806728 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c @@ -303,6 +303,9 @@ xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size, */ 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 @@ -351,6 +354,9 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, * 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); -- 2.15.2 (Apple Git-101.1) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel