git: eebdbe7f1975 - stable/14 - x86 iommu: move page level related functions to common utils
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 11 Sep 2024 08:44:31 UTC
The branch stable/14 has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=eebdbe7f1975bc3d605ee161ace7402037f279d8
commit eebdbe7f1975bc3d605ee161ace7402037f279d8
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-07-19 23:47:48 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-09-11 08:44:00 +0000
x86 iommu: move page level related functions to common utils
(cherry picked from commit 29e227047065c6b1d08fdb72a21f33560637332b)
---
sys/x86/iommu/intel_dmar.h | 2 --
sys/x86/iommu/intel_idpgtbl.c | 38 ++---------------------
sys/x86/iommu/intel_utils.c | 37 ----------------------
sys/x86/iommu/iommu_utils.c | 71 +++++++++++++++++++++++++++++++++++++++++++
sys/x86/iommu/x86_iommu.h | 5 +++
5 files changed, 78 insertions(+), 75 deletions(-)
diff --git a/sys/x86/iommu/intel_dmar.h b/sys/x86/iommu/intel_dmar.h
index edb152f42fe7..c1e6c8f06f64 100644
--- a/sys/x86/iommu/intel_dmar.h
+++ b/sys/x86/iommu/intel_dmar.h
@@ -175,9 +175,7 @@ bool dmar_pglvl_supported(struct dmar_unit *unit, int pglvl);
int domain_set_agaw(struct dmar_domain *domain, int mgaw);
int dmar_maxaddr2mgaw(struct dmar_unit *unit, iommu_gaddr_t maxaddr,
bool allow_less);
-vm_pindex_t pglvl_max_pages(int pglvl);
int domain_is_sp_lvl(struct dmar_domain *domain, int lvl);
-iommu_gaddr_t pglvl_page_size(int total_pglvl, int lvl);
iommu_gaddr_t domain_page_size(struct dmar_domain *domain, int lvl);
int calc_am(struct dmar_unit *unit, iommu_gaddr_t base, iommu_gaddr_t size,
iommu_gaddr_t *isizep);
diff --git a/sys/x86/iommu/intel_idpgtbl.c b/sys/x86/iommu/intel_idpgtbl.c
index 79e184035b23..850627a2defd 100644
--- a/sys/x86/iommu/intel_idpgtbl.c
+++ b/sys/x86/iommu/intel_idpgtbl.c
@@ -317,40 +317,6 @@ put_idmap_pgtbl(vm_object_t obj)
* address. Support superpages.
*/
-/*
- * Index of the pte for the guest address base in the page table at
- * the level lvl.
- */
-static int
-domain_pgtbl_pte_off(struct dmar_domain *domain, iommu_gaddr_t base, int lvl)
-{
-
- base >>= IOMMU_PAGE_SHIFT + (domain->pglvl - lvl - 1) *
- IOMMU_NPTEPGSHIFT;
- return (base & IOMMU_PTEMASK);
-}
-
-/*
- * Returns the page index of the page table page in the page table
- * object, which maps the given address base at the page table level
- * lvl.
- */
-static vm_pindex_t
-domain_pgtbl_get_pindex(struct dmar_domain *domain, iommu_gaddr_t base, int lvl)
-{
- vm_pindex_t idx, pidx;
- int i;
-
- KASSERT(lvl >= 0 && lvl < domain->pglvl,
- ("wrong lvl %p %d", domain, lvl));
-
- for (pidx = idx = 0, i = 0; i < lvl; i++, pidx = idx) {
- idx = domain_pgtbl_pte_off(domain, base, i) +
- pidx * IOMMU_NPTEPG + 1;
- }
- return (idx);
-}
-
static iommu_pte_t *
domain_pgtbl_map_pte(struct dmar_domain *domain, iommu_gaddr_t base, int lvl,
int flags, vm_pindex_t *idxp, struct sf_buf **sf)
@@ -363,7 +329,7 @@ domain_pgtbl_map_pte(struct dmar_domain *domain, iommu_gaddr_t base, int lvl,
DMAR_DOMAIN_ASSERT_PGLOCKED(domain);
KASSERT((flags & IOMMU_PGF_OBJL) != 0, ("lost PGF_OBJL"));
- idx = domain_pgtbl_get_pindex(domain, base, lvl);
+ idx = pglvl_pgtbl_get_pindex(domain->pglvl, base, lvl);
if (*sf != NULL && idx == *idxp) {
pte = (iommu_pte_t *)sf_buf_kva(*sf);
} else {
@@ -415,7 +381,7 @@ retry:
goto retry;
}
}
- pte += domain_pgtbl_pte_off(domain, base, lvl);
+ pte += pglvl_pgtbl_pte_off(domain->pglvl, base, lvl);
return (pte);
}
diff --git a/sys/x86/iommu/intel_utils.c b/sys/x86/iommu/intel_utils.c
index a66682b68a2b..7e15299c1bd3 100644
--- a/sys/x86/iommu/intel_utils.c
+++ b/sys/x86/iommu/intel_utils.c
@@ -173,23 +173,6 @@ dmar_maxaddr2mgaw(struct dmar_unit *unit, iommu_gaddr_t maxaddr, bool allow_less
return (-1);
}
-/*
- * Calculate the total amount of page table pages needed to map the
- * whole bus address space on the context with the selected agaw.
- */
-vm_pindex_t
-pglvl_max_pages(int pglvl)
-{
- vm_pindex_t res;
- int i;
-
- for (res = 0, i = pglvl; i > 0; i--) {
- res *= IOMMU_NPTEPG;
- res++;
- }
- return (res);
-}
-
/*
* Return true if the page table level lvl supports the superpage for
* the context ctx.
@@ -210,26 +193,6 @@ domain_is_sp_lvl(struct dmar_domain *domain, int lvl)
return (alvl < nitems(sagaw_sp) && (sagaw_sp[alvl] & cap_sps) != 0);
}
-iommu_gaddr_t
-pglvl_page_size(int total_pglvl, int lvl)
-{
- int rlvl;
- static const iommu_gaddr_t pg_sz[] = {
- (iommu_gaddr_t)IOMMU_PAGE_SIZE,
- (iommu_gaddr_t)IOMMU_PAGE_SIZE << IOMMU_NPTEPGSHIFT,
- (iommu_gaddr_t)IOMMU_PAGE_SIZE << (2 * IOMMU_NPTEPGSHIFT),
- (iommu_gaddr_t)IOMMU_PAGE_SIZE << (3 * IOMMU_NPTEPGSHIFT),
- (iommu_gaddr_t)IOMMU_PAGE_SIZE << (4 * IOMMU_NPTEPGSHIFT),
- (iommu_gaddr_t)IOMMU_PAGE_SIZE << (5 * IOMMU_NPTEPGSHIFT),
- };
-
- KASSERT(lvl >= 0 && lvl < total_pglvl,
- ("total %d lvl %d", total_pglvl, lvl));
- rlvl = total_pglvl - lvl - 1;
- KASSERT(rlvl < nitems(pg_sz), ("sizeof pg_sz lvl %d", lvl));
- return (pg_sz[rlvl]);
-}
-
iommu_gaddr_t
domain_page_size(struct dmar_domain *domain, int lvl)
{
diff --git a/sys/x86/iommu/iommu_utils.c b/sys/x86/iommu/iommu_utils.c
index 9c6cae5ff51f..645c7e15740a 100644
--- a/sys/x86/iommu/iommu_utils.c
+++ b/sys/x86/iommu/iommu_utils.c
@@ -619,3 +619,74 @@ iommu_domain_free_entry(struct iommu_map_entry *entry, bool free)
entry->flags = 0;
}
+/*
+ * Index of the pte for the guest address base in the page table at
+ * the level lvl.
+ */
+int
+pglvl_pgtbl_pte_off(int pglvl, iommu_gaddr_t base, int lvl)
+{
+
+ base >>= IOMMU_PAGE_SHIFT + (pglvl - lvl - 1) *
+ IOMMU_NPTEPGSHIFT;
+ return (base & IOMMU_PTEMASK);
+}
+
+/*
+ * Returns the page index of the page table page in the page table
+ * object, which maps the given address base at the page table level
+ * lvl.
+ */
+vm_pindex_t
+pglvl_pgtbl_get_pindex(int pglvl, iommu_gaddr_t base, int lvl)
+{
+ vm_pindex_t idx, pidx;
+ int i;
+
+ KASSERT(lvl >= 0 && lvl < pglvl,
+ ("wrong lvl %d %d", pglvl, lvl));
+
+ for (pidx = idx = 0, i = 0; i < lvl; i++, pidx = idx) {
+ idx = pglvl_pgtbl_pte_off(pglvl, base, i) +
+ pidx * IOMMU_NPTEPG + 1;
+ }
+ return (idx);
+}
+
+/*
+ * Calculate the total amount of page table pages needed to map the
+ * whole bus address space on the context with the selected agaw.
+ */
+vm_pindex_t
+pglvl_max_pages(int pglvl)
+{
+ vm_pindex_t res;
+ int i;
+
+ for (res = 0, i = pglvl; i > 0; i--) {
+ res *= IOMMU_NPTEPG;
+ res++;
+ }
+ return (res);
+}
+
+iommu_gaddr_t
+pglvl_page_size(int total_pglvl, int lvl)
+{
+ int rlvl;
+ static const iommu_gaddr_t pg_sz[] = {
+ (iommu_gaddr_t)IOMMU_PAGE_SIZE,
+ (iommu_gaddr_t)IOMMU_PAGE_SIZE << IOMMU_NPTEPGSHIFT,
+ (iommu_gaddr_t)IOMMU_PAGE_SIZE << (2 * IOMMU_NPTEPGSHIFT),
+ (iommu_gaddr_t)IOMMU_PAGE_SIZE << (3 * IOMMU_NPTEPGSHIFT),
+ (iommu_gaddr_t)IOMMU_PAGE_SIZE << (4 * IOMMU_NPTEPGSHIFT),
+ (iommu_gaddr_t)IOMMU_PAGE_SIZE << (5 * IOMMU_NPTEPGSHIFT),
+ (iommu_gaddr_t)IOMMU_PAGE_SIZE << (6 * IOMMU_NPTEPGSHIFT),
+ };
+
+ KASSERT(lvl >= 0 && lvl < total_pglvl,
+ ("total %d lvl %d", total_pglvl, lvl));
+ rlvl = total_pglvl - lvl - 1;
+ KASSERT(rlvl < nitems(pg_sz), ("sizeof pg_sz lvl %d", lvl));
+ return (pg_sz[rlvl]);
+}
diff --git a/sys/x86/iommu/x86_iommu.h b/sys/x86/iommu/x86_iommu.h
index 9e3a82283729..b2caed550e35 100644
--- a/sys/x86/iommu/x86_iommu.h
+++ b/sys/x86/iommu/x86_iommu.h
@@ -187,4 +187,9 @@ void iommu_release_intr(struct iommu_unit *unit, int idx);
void iommu_device_tag_init(struct iommu_ctx *ctx, device_t dev);
+int pglvl_pgtbl_pte_off(int pglvl, iommu_gaddr_t base, int lvl);
+vm_pindex_t pglvl_pgtbl_get_pindex(int pglvl, iommu_gaddr_t base, int lvl);
+vm_pindex_t pglvl_max_pages(int pglvl);
+iommu_gaddr_t pglvl_page_size(int total_pglvl, int lvl);
+
#endif