From: Juerg Haefliger <juerg.haefli...@canonical.com>

XPFO can unmap a bounce buffer. Check for this and map it back in if
needed.

Signed-off-by: Juerg Haefliger <juerg.haefli...@canonical.com>
Signed-off-by: Tycho Andersen <ty...@tycho.ws>
Signed-off-by: Khalid Aziz <khalid.a...@oracle.com>
Cc: Khalid Aziz <kha...@gonehiking.org>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.w...@oracle.com>
---
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

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to