diff options
author | Joerg Roedel <jroedel@suse.de> | 2015-04-01 15:58:52 +0300 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2015-04-02 14:31:08 +0300 |
commit | d4b036648402bb4ef6d4a0df51375a2fb705b6cc (patch) | |
tree | 9f464e5834439731cb8260f0883a65838a217c01 /drivers/iommu | |
parent | b24b1b63a37d05d61601d643ef30f95dd2452048 (diff) | |
download | linux-d4b036648402bb4ef6d4a0df51375a2fb705b6cc.tar.xz |
iommu/amd: Correctly encode huge pages in iommu page tables
When a default page-size for given level should be mapped,
the level encoding must be 0 rather than 7. This fixes an
issue seen on IOMMUv2 hardware, where this encoding is
enforced.
Tested-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu')
-rw-r--r-- | drivers/iommu/amd_iommu.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 7a00e5d40eb6..aa710b095f1a 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -1390,13 +1390,14 @@ static int iommu_map_page(struct protection_domain *dom, u64 __pte, *pte; int i, count; + BUG_ON(!IS_ALIGNED(bus_addr, page_size)); + BUG_ON(!IS_ALIGNED(phys_addr, page_size)); + if (!(prot & IOMMU_PROT_MASK)) return -EINVAL; - bus_addr = PAGE_ALIGN(bus_addr); - phys_addr = PAGE_ALIGN(phys_addr); - count = PAGE_SIZE_PTE_COUNT(page_size); - pte = alloc_pte(dom, bus_addr, page_size, NULL, GFP_KERNEL); + count = PAGE_SIZE_PTE_COUNT(page_size); + pte = alloc_pte(dom, bus_addr, page_size, NULL, GFP_KERNEL); if (!pte) return -ENOMEM; @@ -1405,7 +1406,7 @@ static int iommu_map_page(struct protection_domain *dom, if (IOMMU_PTE_PRESENT(pte[i])) return -EBUSY; - if (page_size > PAGE_SIZE) { + if (count > 1) { __pte = PAGE_SIZE_PTE(phys_addr, page_size); __pte |= PM_LEVEL_ENC(7) | IOMMU_PTE_P | IOMMU_PTE_FC; } else |