|
@@ -2115,15 +2115,19 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
/* It is large page*/
|
|
/* It is large page*/
|
|
if (largepage_lvl > 1) {
|
|
if (largepage_lvl > 1) {
|
|
|
|
+ unsigned long nr_superpages, end_pfn;
|
|
|
|
+
|
|
pteval |= DMA_PTE_LARGE_PAGE;
|
|
pteval |= DMA_PTE_LARGE_PAGE;
|
|
lvl_pages = lvl_to_nr_pages(largepage_lvl);
|
|
lvl_pages = lvl_to_nr_pages(largepage_lvl);
|
|
|
|
+
|
|
|
|
+ nr_superpages = sg_res / lvl_pages;
|
|
|
|
+ end_pfn = iov_pfn + nr_superpages * lvl_pages - 1;
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Ensure that old small page tables are
|
|
* Ensure that old small page tables are
|
|
- * removed to make room for superpage,
|
|
|
|
- * if they exist.
|
|
|
|
|
|
+ * removed to make room for superpage(s).
|
|
*/
|
|
*/
|
|
- dma_pte_free_pagetable(domain, iov_pfn,
|
|
|
|
- iov_pfn + lvl_pages - 1);
|
|
|
|
|
|
+ dma_pte_free_pagetable(domain, iov_pfn, end_pfn);
|
|
} else {
|
|
} else {
|
|
pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
|
|
pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
|
|
}
|
|
}
|