git: 89b4150af5b1 - stable/13 - riscv: Add pmap helper functions required by four-level page tables
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 14 Mar 2022 14:46:12 UTC
The branch stable/13 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=89b4150af5b169bf2db38a91d7bafc13b0bf28ea commit 89b4150af5b169bf2db38a91d7bafc13b0bf28ea Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2022-03-01 14:06:15 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2022-03-14 14:45:40 +0000 riscv: Add pmap helper functions required by four-level page tables No functional change intended. Reviewed by: jhb Sponsored by: The FreeBSD Foundation (cherry picked from commit 5cf3a8216e3adad06f1ab02c9a9b201cebcd4809) --- sys/riscv/riscv/pmap.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/sys/riscv/riscv/pmap.c b/sys/riscv/riscv/pmap.c index ac6b854ac3c3..74192a16341c 100644 --- a/sys/riscv/riscv/pmap.c +++ b/sys/riscv/riscv/pmap.c @@ -363,13 +363,45 @@ pagezero(void *p) #define L2PTE_TO_PHYS(l2) \ ((((l2) & ~PTE_HI_MASK) >> PTE_PPN1_S) << L2_SHIFT) +static __inline pd_entry_t * +pmap_l0(pmap_t pmap, vm_offset_t va) +{ + KASSERT(pmap_mode != PMAP_MODE_SV39, ("%s: in SV39 mode", __func__)); + KASSERT(VIRT_IS_VALID(va), + ("%s: malformed virtual address %#lx", __func__, va)); + return (&pmap->pm_top[pmap_l0_index(va)]); +} + +static __inline pd_entry_t * +pmap_l0_to_l1(pd_entry_t *l0, vm_offset_t va) +{ + vm_paddr_t phys; + pd_entry_t *l1; + + KASSERT(pmap_mode != PMAP_MODE_SV39, ("%s: in SV39 mode", __func__)); + phys = PTE_TO_PHYS(pmap_load(l0)); + l1 = (pd_entry_t *)PHYS_TO_DMAP(phys); + + return (&l1[pmap_l1_index(va)]); +} + static __inline pd_entry_t * pmap_l1(pmap_t pmap, vm_offset_t va) { + pd_entry_t *l0; KASSERT(VIRT_IS_VALID(va), ("%s: malformed virtual address %#lx", __func__, va)); - return (&pmap->pm_top[pmap_l1_index(va)]); + if (pmap_mode == PMAP_MODE_SV39) { + return (&pmap->pm_top[pmap_l1_index(va)]); + } else { + l0 = pmap_l0(pmap, va); + if ((pmap_load(l0) & PTE_V) == 0) + return (NULL); + if ((pmap_load(l0) & PTE_RX) != 0) + return (NULL); + return (pmap_l0_to_l1(l0, va)); + } } static __inline pd_entry_t * @@ -390,6 +422,8 @@ pmap_l2(pmap_t pmap, vm_offset_t va) pd_entry_t *l1; l1 = pmap_l1(pmap, va); + if (l1 == NULL) + return (NULL); if ((pmap_load(l1) & PTE_V) == 0) return (NULL); if ((pmap_load(l1) & PTE_RX) != 0)