Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/amd-iommu: Make amd_iommu_iova_to_phys aware of multiple page sizes

This patch extends the amd_iommu_iova_to_phys() function to
handle different page sizes correctly. It doesn't use
fetch_pte() anymore because we don't know (or care about)
the page_size used for mapping the given iova.

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>

+9 -4
+9 -4
arch/x86/kernel/amd_iommu.c
··· 2556 2556 unsigned long iova) 2557 2557 { 2558 2558 struct protection_domain *domain = dom->priv; 2559 - unsigned long offset = iova & ~PAGE_MASK; 2559 + unsigned long offset_mask; 2560 2560 phys_addr_t paddr; 2561 - u64 *pte; 2561 + u64 *pte, __pte; 2562 2562 2563 2563 pte = fetch_pte(domain, iova); 2564 2564 2565 2565 if (!pte || !IOMMU_PTE_PRESENT(*pte)) 2566 2566 return 0; 2567 2567 2568 - paddr = *pte & IOMMU_PAGE_MASK; 2569 - paddr |= offset; 2568 + if (PM_PTE_LEVEL(*pte) == 0) 2569 + offset_mask = PAGE_SIZE - 1; 2570 + else 2571 + offset_mask = PTE_PAGE_SIZE(*pte) - 1; 2572 + 2573 + __pte = *pte & PM_ADDR_MASK; 2574 + paddr = (__pte & ~offset_mask) | (iova & offset_mask); 2570 2575 2571 2576 return paddr; 2572 2577 }