|
@@ -1827,10 +1827,17 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
|
|
|
if (!pte)
|
|
|
return -ENOMEM;
|
|
|
/* It is large page*/
|
|
|
- if (largepage_lvl > 1)
|
|
|
+ if (largepage_lvl > 1) {
|
|
|
pteval |= DMA_PTE_LARGE_PAGE;
|
|
|
- else
|
|
|
+ /* Ensure that old small page tables are removed to make room
|
|
|
+ for superpage, if they exist. */
|
|
|
+ dma_pte_clear_range(domain, iov_pfn,
|
|
|
+ iov_pfn + lvl_to_nr_pages(largepage_lvl) - 1);
|
|
|
+ dma_pte_free_pagetable(domain, iov_pfn,
|
|
|
+ iov_pfn + lvl_to_nr_pages(largepage_lvl) - 1);
|
|
|
+ } else {
|
|
|
pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
/* We don't need lock here, nobody else
|