From: Juerg Haefliger <juerg.haefliger@xxxxxxxxxxxxx> XPFO can unmap a bounce buffer. Check for this and map it back in if needed. Signed-off-by: Juerg Haefliger <juerg.haefliger@xxxxxxxxxxxxx> Signed-off-by: Tycho Andersen <tycho@xxxxxxxx> Signed-off-by: Khalid Aziz <khalid.aziz@xxxxxxxxxx> Cc: Khalid Aziz <khalid@xxxxxxxxxxxxxx> Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> --- v9: * Added a generic check for whether a page is mapped or not (suggested by Chris Hellwig) v6: * guard against lookup_xpfo() returning NULL include/linux/highmem.h | 7 +++++++ kernel/dma/swiotlb.c | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 59a1a5fa598d..cf21f023dff4 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h @@ -77,6 +77,13 @@ static inline struct page *kmap_to_page(void *addr) } static inline unsigned long totalhigh_pages(void) { return 0UL; } +static inline bool page_is_unmapped(struct page *page) +{ + if (PageHighMem(page) || PageXpfoUnmapped(page)) + return true; + else + return false; +} #endif /* CONFIG_HIGHMEM */ diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index 1fb6fd68b9c7..90a1a3709b55 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -392,8 +392,9 @@ static void swiotlb_bounce(phys_addr_t orig_addr, phys_addr_t tlb_addr, { unsigned long pfn = PFN_DOWN(orig_addr); unsigned char *vaddr = phys_to_virt(tlb_addr); + struct page *page = pfn_to_page(pfn); - if (PageHighMem(pfn_to_page(pfn))) { + if (page_is_unmapped(page)) { /* The buffer does not have a mapping. Map it in and copy */ unsigned int offset = orig_addr & ~PAGE_MASK; char *buffer; -- 2.17.1