Skip to content

Commit 7f1f168

Browse files
Andrei Duleajoergroedel
authored andcommitted
iommu/amd: Introduce first_pte_l7() helper
Given an arbitrary pte that is part of a large mapping, this function returns the first pte of the series (and optionally the mapped size and number of PTEs) It will be re-used in a subsequent patch to replace an existing L7 mapping. Fixes: 6d568ef ("iommu/amd: Allow downgrading page-sizes in alloc_pte()") Signed-off-by: Andrei Dulea <[email protected]>
1 parent 6ccb72f commit 7f1f168

File tree

1 file changed

+29
-11
lines changed

1 file changed

+29
-11
lines changed

drivers/iommu/amd_iommu.c

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,29 @@ static void iommu_uninit_device(struct device *dev)
501501
*/
502502
}
503503

504+
/*
505+
* Helper function to get the first pte of a large mapping
506+
*/
507+
static u64 *first_pte_l7(u64 *pte, unsigned long *page_size,
508+
unsigned long *count)
509+
{
510+
unsigned long pte_mask, pg_size, cnt;
511+
u64 *fpte;
512+
513+
pg_size = PTE_PAGE_SIZE(*pte);
514+
cnt = PAGE_SIZE_PTE_COUNT(pg_size);
515+
pte_mask = ~((cnt << 3) - 1);
516+
fpte = (u64 *)(((unsigned long)pte) & pte_mask);
517+
518+
if (page_size)
519+
*page_size = pg_size;
520+
521+
if (count)
522+
*count = cnt;
523+
524+
return fpte;
525+
}
526+
504527
/****************************************************************************
505528
*
506529
* Interrupt handling functions
@@ -1567,17 +1590,12 @@ static u64 *fetch_pte(struct protection_domain *domain,
15671590
*page_size = PTE_LEVEL_PAGE_SIZE(level);
15681591
}
15691592

1570-
if (PM_PTE_LEVEL(*pte) == 0x07) {
1571-
unsigned long pte_mask;
1572-
1573-
/*
1574-
* If we have a series of large PTEs, make
1575-
* sure to return a pointer to the first one.
1576-
*/
1577-
*page_size = pte_mask = PTE_PAGE_SIZE(*pte);
1578-
pte_mask = ~((PAGE_SIZE_PTE_COUNT(pte_mask) << 3) - 1);
1579-
pte = (u64 *)(((unsigned long)pte) & pte_mask);
1580-
}
1593+
/*
1594+
* If we have a series of large PTEs, make
1595+
* sure to return a pointer to the first one.
1596+
*/
1597+
if (PM_PTE_LEVEL(*pte) == PAGE_MODE_7_LEVEL)
1598+
pte = first_pte_l7(pte, page_size, NULL);
15811599

15821600
return pte;
15831601
}

0 commit comments

Comments
 (0)