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: 6d568ef9a6
("iommu/amd: Allow downgrading page-sizes in alloc_pte()")
Signed-off-by: Andrei Dulea <adulea@amazon.de>
This commit is contained in:
parent
6ccb72f837
commit
7f1f1683c1
1 changed files with 29 additions and 11 deletions
|
@ -501,6 +501,29 @@ static void iommu_uninit_device(struct device *dev)
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper function to get the first pte of a large mapping
|
||||||
|
*/
|
||||||
|
static u64 *first_pte_l7(u64 *pte, unsigned long *page_size,
|
||||||
|
unsigned long *count)
|
||||||
|
{
|
||||||
|
unsigned long pte_mask, pg_size, cnt;
|
||||||
|
u64 *fpte;
|
||||||
|
|
||||||
|
pg_size = PTE_PAGE_SIZE(*pte);
|
||||||
|
cnt = PAGE_SIZE_PTE_COUNT(pg_size);
|
||||||
|
pte_mask = ~((cnt << 3) - 1);
|
||||||
|
fpte = (u64 *)(((unsigned long)pte) & pte_mask);
|
||||||
|
|
||||||
|
if (page_size)
|
||||||
|
*page_size = pg_size;
|
||||||
|
|
||||||
|
if (count)
|
||||||
|
*count = cnt;
|
||||||
|
|
||||||
|
return fpte;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
*
|
*
|
||||||
* Interrupt handling functions
|
* Interrupt handling functions
|
||||||
|
@ -1567,17 +1590,12 @@ static u64 *fetch_pte(struct protection_domain *domain,
|
||||||
*page_size = PTE_LEVEL_PAGE_SIZE(level);
|
*page_size = PTE_LEVEL_PAGE_SIZE(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PM_PTE_LEVEL(*pte) == 0x07) {
|
/*
|
||||||
unsigned long pte_mask;
|
* If we have a series of large PTEs, make
|
||||||
|
* sure to return a pointer to the first one.
|
||||||
/*
|
*/
|
||||||
* If we have a series of large PTEs, make
|
if (PM_PTE_LEVEL(*pte) == PAGE_MODE_7_LEVEL)
|
||||||
* sure to return a pointer to the first one.
|
pte = first_pte_l7(pte, page_size, NULL);
|
||||||
*/
|
|
||||||
*page_size = pte_mask = PTE_PAGE_SIZE(*pte);
|
|
||||||
pte_mask = ~((PAGE_SIZE_PTE_COUNT(pte_mask) << 3) - 1);
|
|
||||||
pte = (u64 *)(((unsigned long)pte) & pte_mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pte;
|
return pte;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue