From 847ab36bf22766020077f06f6a8d278f8b081655 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Wed, 2 Sep 2020 18:16:43 +0000 Subject: [PATCH] Include the psind in data returned by mincore(2). Currently we use a single bit to indicate whether the virtual page is part of a superpage. To support a forthcoming implementation of non-transparent 1GB superpages, it is useful to provide more detailed information about large page sizes. The change converts MINCORE_SUPER into a mask for MINCORE_PSIND(psind) values, indicating a mapping of size psind, where psind is an index into the pagesizes array returned by getpagesizes(3), which in turn comes from the hw.pagesizes sysctl. MINCORE_PSIND(1) is equal to the old value of MINCORE_SUPER. For now, two bits are used to record the page size, permitting values of MAXPAGESIZES up to 4. Reviewed by: alc, kib Sponsored by: Juniper Networks, Inc. Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D26238 --- lib/libc/sys/mincore.2 | 28 +++++++++++++++++++++++++--- sys/amd64/amd64/pmap.c | 2 +- sys/arm/arm/pmap-v6.c | 2 +- sys/arm64/arm64/pmap.c | 2 +- sys/i386/i386/pmap.c | 2 +- sys/powerpc/aim/mmu_radix.c | 2 +- sys/riscv/riscv/pmap.c | 2 +- sys/sys/mman.h | 3 ++- sys/vm/vm_mmap.c | 2 ++ 9 files changed, 35 insertions(+), 10 deletions(-) diff --git a/lib/libc/sys/mincore.2 b/lib/libc/sys/mincore.2 index 4c8dd6795e5..3b248e77816 100644 --- a/lib/libc/sys/mincore.2 +++ b/lib/libc/sys/mincore.2 @@ -28,7 +28,7 @@ .\" @(#)mincore.2 8.1 (Berkeley) 6/9/93 .\" $FreeBSD$ .\" -.Dd January 7, 2019 +.Dd August 23, 2020 .Dt MINCORE 2 .Os .Sh NAME @@ -73,9 +73,19 @@ Page has been modified by us. Page has been referenced. .It Dv MINCORE_MODIFIED_OTHER Page has been modified. -.It Dv MINCORE_SUPER +.It Dv MINCORE_PSIND(i) Page is part of a large .Pq Dq super +page with size given by index +.Dv i +in the array returned by +.Xr getpagesizes 3 . +.It Dv MINCORE_SUPER +A mask of the valid +.Dv MINCORE_PSIND() +values. +If any bits in this mask are set, the page is part of a large +.Pq Dq super page. .El .Pp @@ -98,6 +108,17 @@ and statuses. Otherwise, if the sysctl value is zero, all resident pages backing the specified address range are examined, regardless of the mapping state. +.Sh IMPLEMENTATION NOTES +Prior to the introduction of +.Dv MINCORE_PSIND() +in +.Fx 13.0 , +.Dv MINCORE_SUPER +consisted of a single bit equal to +.Dv MINCORE_PSIND(1) . +In particular, applications compiled using the old value of +.Dv MINCORE_SUPER +will not identify large pages with size index 2 as being large pages. .Sh RETURN VALUES .Rv -std mincore .Sh ERRORS @@ -122,7 +143,8 @@ argument points to an illegal address. .Xr mprotect 2 , .Xr msync 2 , .Xr munmap 2 , -.Xr getpagesize 3 +.Xr getpagesize 3 , +.Xr getpagesizes 3 .Sh HISTORY The .Fn mincore diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 33c5f256419..0ef96a29dd8 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -9149,7 +9149,7 @@ pmap_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *pap) /* Compute the physical address of the 4KB page. */ pa = ((*pdep & PG_PS_FRAME) | (addr & PDRMASK)) & PG_FRAME; - val = MINCORE_SUPER; + val = MINCORE_PSIND(1); } else { pte = *pmap_pde_to_pte(pdep, addr); pa = pte & PG_FRAME; diff --git a/sys/arm/arm/pmap-v6.c b/sys/arm/arm/pmap-v6.c index 8ee677f7da7..c9b939f6ce3 100644 --- a/sys/arm/arm/pmap-v6.c +++ b/sys/arm/arm/pmap-v6.c @@ -6235,7 +6235,7 @@ pmap_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *pap) if (pte1_is_section(pte1)) { pa = trunc_page(pte1_pa(pte1) | (addr & PTE1_OFFSET)); managed = pte1_is_managed(pte1); - val = MINCORE_SUPER | MINCORE_INCORE; + val = MINCORE_PSIND(1) | MINCORE_INCORE; if (pte1_is_dirty(pte1)) val |= MINCORE_MODIFIED | MINCORE_MODIFIED_OTHER; if (pte1 & PTE1_A) diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c index c66874bbd7b..df160cc0501 100644 --- a/sys/arm64/arm64/pmap.c +++ b/sys/arm64/arm64/pmap.c @@ -5956,7 +5956,7 @@ pmap_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *pap) managed = (tpte & ATTR_SW_MANAGED) != 0; val = MINCORE_INCORE; if (lvl != 3) - val |= MINCORE_SUPER; + val |= MINCORE_PSIND(3 - lvl); if ((managed && pmap_pte_dirty(pmap, tpte)) || (!managed && (tpte & ATTR_S1_AP_RW_BIT) == ATTR_S1_AP(ATTR_S1_AP_RW))) val |= MINCORE_MODIFIED | MINCORE_MODIFIED_OTHER; diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index e63a24b8da7..bc650cf378e 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -5755,7 +5755,7 @@ __CONCAT(PMTYPE, mincore)(pmap_t pmap, vm_offset_t addr, vm_paddr_t *pap) /* Compute the physical address of the 4KB page. */ pa = ((pde & PG_PS_FRAME) | (addr & PDRMASK)) & PG_FRAME; - val = MINCORE_SUPER; + val = MINCORE_PSIND(1); } else { pte = pmap_pte_ufast(pmap, addr, pde); pa = pte & PG_FRAME; diff --git a/sys/powerpc/aim/mmu_radix.c b/sys/powerpc/aim/mmu_radix.c index e2deb68705c..608d17e1a55 100644 --- a/sys/powerpc/aim/mmu_radix.c +++ b/sys/powerpc/aim/mmu_radix.c @@ -5689,7 +5689,7 @@ mmu_radix_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *locked_pa) /* Compute the physical address of the 4KB page. */ pa = ((*l3ep & PG_PS_FRAME) | (addr & L3_PAGE_MASK)) & PG_FRAME; - val = MINCORE_SUPER; + val = MINCORE_PSIND(1); } else { pte = *pmap_l3e_to_pte(l3ep, addr); pa = pte & PG_FRAME; diff --git a/sys/riscv/riscv/pmap.c b/sys/riscv/riscv/pmap.c index f8f57bb59bf..7b403834c9d 100644 --- a/sys/riscv/riscv/pmap.c +++ b/sys/riscv/riscv/pmap.c @@ -4217,7 +4217,7 @@ pmap_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *pap) if (l2 != NULL && ((tpte = pmap_load(l2)) & PTE_V) != 0) { if ((tpte & PTE_RWX) != 0) { pa = PTE_TO_PHYS(tpte) | (addr & L2_OFFSET); - val = MINCORE_INCORE | MINCORE_SUPER; + val = MINCORE_INCORE | MINCORE_PSIND(1); } else { l3 = pmap_l2_to_l3(l2, addr); tpte = pmap_load(l3); diff --git a/sys/sys/mman.h b/sys/sys/mman.h index 2148026473a..5af3a463a0f 100644 --- a/sys/sys/mman.h +++ b/sys/sys/mman.h @@ -179,7 +179,8 @@ #define MINCORE_MODIFIED 0x4 /* Page has been modified by us */ #define MINCORE_REFERENCED_OTHER 0x8 /* Page has been referenced */ #define MINCORE_MODIFIED_OTHER 0x10 /* Page has been modified */ -#define MINCORE_SUPER 0x20 /* Page is a "super" page */ +#define MINCORE_SUPER 0x60 /* Page is a "super" page */ +#define MINCORE_PSIND(i) (((i) << 5) & MINCORE_SUPER) /* Page size */ /* * Anonymous object constant for shm_open(). diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index 2f0f55f3cf8..03f236aac13 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -112,6 +112,8 @@ SYSCTL_INT(_vm, OID_AUTO, imply_prot_max, CTLFLAG_RWTUN, &imply_prot_max, 0, #define MAP_32BIT_MAX_ADDR ((vm_offset_t)1 << 31) #endif +_Static_assert(MAXPAGESIZES <= 4, "MINCORE_SUPER too narrow"); + #ifndef _SYS_SYSPROTO_H_ struct sbrk_args { int incr; -- 2.45.0