Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d4b03664 authored by Joerg Roedel's avatar Joerg Roedel
Browse files

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: default avatarSuravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent b24b1b63
Loading
Loading
Loading
Loading
+6 −5
Original line number Original line Diff line number Diff line
@@ -1390,11 +1390,12 @@ static int iommu_map_page(struct protection_domain *dom,
	u64 __pte, *pte;
	u64 __pte, *pte;
	int i, count;
	int i, count;


	BUG_ON(!IS_ALIGNED(bus_addr, page_size));
	BUG_ON(!IS_ALIGNED(phys_addr, page_size));

	if (!(prot & IOMMU_PROT_MASK))
	if (!(prot & IOMMU_PROT_MASK))
		return -EINVAL;
		return -EINVAL;


	bus_addr  = PAGE_ALIGN(bus_addr);
	phys_addr = PAGE_ALIGN(phys_addr);
	count = PAGE_SIZE_PTE_COUNT(page_size);
	count = PAGE_SIZE_PTE_COUNT(page_size);
	pte   = alloc_pte(dom, bus_addr, page_size, NULL, GFP_KERNEL);
	pte   = alloc_pte(dom, bus_addr, page_size, NULL, GFP_KERNEL);


@@ -1405,7 +1406,7 @@ static int iommu_map_page(struct protection_domain *dom,
		if (IOMMU_PTE_PRESENT(pte[i]))
		if (IOMMU_PTE_PRESENT(pte[i]))
			return -EBUSY;
			return -EBUSY;


	if (page_size > PAGE_SIZE) {
	if (count > 1) {
		__pte = PAGE_SIZE_PTE(phys_addr, page_size);
		__pte = PAGE_SIZE_PTE(phys_addr, page_size);
		__pte |= PM_LEVEL_ENC(7) | IOMMU_PTE_P | IOMMU_PTE_FC;
		__pte |= PM_LEVEL_ENC(7) | IOMMU_PTE_P | IOMMU_PTE_FC;
	} else
	} else