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>
This commit is contained in:
parent
b24b1b63a3
commit
d4b0366484
1 changed files with 6 additions and 5 deletions
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue