aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/amd_iommu.c
diff options
context:
space:
mode:
authorJoerg Roedel <jroedel@suse.de>2015-04-01 08:58:52 -0400
committerJoerg Roedel <jroedel@suse.de>2015-04-02 07:31:08 -0400
commitd4b036648402bb4ef6d4a0df51375a2fb705b6cc (patch)
tree9f464e5834439731cb8260f0883a65838a217c01 /drivers/iommu/amd_iommu.c
parentb24b1b63a37d05d61601d643ef30f95dd2452048 (diff)
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/amd_iommu.c')
-rw-r--r--drivers/iommu/amd_iommu.c11
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,
1390 u64 __pte, *pte; 1390 u64 __pte, *pte;
1391 int i, count; 1391 int i, count;
1392 1392
1393 BUG_ON(!IS_ALIGNED(bus_addr, page_size));
1394 BUG_ON(!IS_ALIGNED(phys_addr, page_size));
1395
1393 if (!(prot & IOMMU_PROT_MASK)) 1396 if (!(prot & IOMMU_PROT_MASK))
1394 return -EINVAL; 1397 return -EINVAL;
1395 1398
1396 bus_addr = PAGE_ALIGN(bus_addr); 1399 count = PAGE_SIZE_PTE_COUNT(page_size);
1397 phys_addr = PAGE_ALIGN(phys_addr); 1400 pte = alloc_pte(dom, bus_addr, page_size, NULL, GFP_KERNEL);
1398 count = PAGE_SIZE_PTE_COUNT(page_size);
1399 pte = alloc_pte(dom, bus_addr, page_size, NULL, GFP_KERNEL);
1400 1401
1401 if (!pte) 1402 if (!pte)
1402 return -ENOMEM; 1403 return -ENOMEM;
@@ -1405,7 +1406,7 @@ static int iommu_map_page(struct protection_domain *dom,
1405 if (IOMMU_PTE_PRESENT(pte[i])) 1406 if (IOMMU_PTE_PRESENT(pte[i]))
1406 return -EBUSY; 1407 return -EBUSY;
1407 1408
1408 if (page_size > PAGE_SIZE) { 1409 if (count > 1) {
1409 __pte = PAGE_SIZE_PTE(phys_addr, page_size); 1410 __pte = PAGE_SIZE_PTE(phys_addr, page_size);
1410 __pte |= PM_LEVEL_ENC(7) | IOMMU_PTE_P | IOMMU_PTE_FC; 1411 __pte |= PM_LEVEL_ENC(7) | IOMMU_PTE_P | IOMMU_PTE_FC;
1411 } else 1412 } else