From owner-svn-src-all@freebsd.org Mon May 27 15:21:27 2019 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 8DBB8159FE81; Mon, 27 May 2019 15:21:27 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 2CC4671540; Mon, 27 May 2019 15:21:27 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 060D74E34; Mon, 27 May 2019 15:21:27 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x4RFLQVH035757; Mon, 27 May 2019 15:21:26 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x4RFLQUX035756; Mon, 27 May 2019 15:21:26 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201905271521.x4RFLQUX035756@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Mon, 27 May 2019 15:21:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r348306 - head/sys/amd64/amd64 X-SVN-Group: head X-SVN-Commit-Author: kib X-SVN-Commit-Paths: head/sys/amd64/amd64 X-SVN-Commit-Revision: 348306 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 2CC4671540 X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.97 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.999,0]; NEURAL_HAM_SHORT(-0.97)[-0.966,0]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US] X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 27 May 2019 15:21:27 -0000 Author: kib Date: Mon May 27 15:21:26 2019 New Revision: 348306 URL: https://svnweb.freebsd.org/changeset/base/348306 Log: Correct some inconsistencies in the earliest created kernel page tables which affect demotion. The last last-level page table under 2M mappings below KERNend was only partially initialized. When that page was used as the hardware page table for demotion of the 2M mapping, the result was not consistent. Since pmap_demote_pde() is switched to use PG_PROMOTED as the test for the validity of the saved last level page table page, we can keep page table pages zero-initialized instead. Demotion would fill them as needed. Only map the created page tables beyond KERNend, there is no need to pre-promote PTmap after KERNend, because the extra mapping is not used. Only round up *firstaddr to 2M boundary when it is below rounded KERNend. Sometimes the allocpages() calls advance *firstaddr past the end of the last 2MB page mapping. In that case, this conditional avoids wasting an average of 1MB of physical memory. Update comments to explain action in more clean and direct language. Reported and tested by: pho In collaboration with: alc Sponsored by: The FreeBSD Foundation (kib) MFC after: 1 week Differential revision: https://reviews.freebsd.org/D20380 Modified: head/sys/amd64/amd64/pmap.c Modified: head/sys/amd64/amd64/pmap.c ============================================================================== --- head/sys/amd64/amd64/pmap.c Mon May 27 13:14:22 2019 (r348305) +++ head/sys/amd64/amd64/pmap.c Mon May 27 15:21:26 2019 (r348306) @@ -1338,7 +1338,6 @@ static void create_pagetables(vm_paddr_t *firstaddr) { int i, j, ndm1g, nkpdpe, nkdmpde; - pt_entry_t *pt_p; pd_entry_t *pd_p; pdp_entry_t *pdp_p; pml4_entry_t *p4_p; @@ -1399,20 +1398,21 @@ create_pagetables(vm_paddr_t *firstaddr) KPTphys = allocpages(firstaddr, nkpt); KPDphys = allocpages(firstaddr, nkpdpe); - /* Fill in the underlying page table pages */ - /* XXX not fully used, underneath 2M pages */ - pt_p = (pt_entry_t *)KPTphys; - for (i = 0; ptoa(i) < *firstaddr; i++) - pt_p[i] = ptoa(i) | X86_PG_V | pg_g | bootaddr_rwx(ptoa(i)); - - /* Now map the page tables at their location within PTmap */ + /* + * Connect the zero-filled PT pages to their PD entries. This + * implicitly maps the PT pages at their correct locations within + * the PTmap. + */ pd_p = (pd_entry_t *)KPDphys; for (i = 0; i < nkpt; i++) pd_p[i] = (KPTphys + ptoa(i)) | X86_PG_RW | X86_PG_V; - /* Map from zero to end of allocations under 2M pages */ - /* This replaces some of the KPTphys entries above */ - for (i = 0; (i << PDRSHIFT) < *firstaddr; i++) + /* + * Map from physical address zero to the end of loader preallocated + * memory using 2MB pages. This replaces some of the PD entries + * created above. + */ + for (i = 0; (i << PDRSHIFT) < KERNend; i++) /* Preset PG_M and PG_A because demotion expects it. */ pd_p[i] = (i << PDRSHIFT) | X86_PG_V | PG_PS | pg_g | X86_PG_M | X86_PG_A | bootaddr_rwx(i << PDRSHIFT); @@ -1422,7 +1422,8 @@ create_pagetables(vm_paddr_t *firstaddr) * to record the physical blocks we've actually mapped into kernel * virtual address space. */ - *firstaddr = round_2mpage(*firstaddr); + if (*firstaddr < round_2mpage(KERNend)) + *firstaddr = round_2mpage(KERNend); /* And connect up the PD to the PDP (leaving room for L4 pages) */ pdp_p = (pdp_entry_t *)(KPDPphys + ptoa(KPML4I - KPML4BASE)); @@ -1529,7 +1530,10 @@ pmap_bootstrap(vm_paddr_t *firstaddr) */ vm_phys_add_seg(KPTphys, KPTphys + ptoa(nkpt)); - virtual_avail = (vm_offset_t) KERNBASE + *firstaddr; + /* + * Account for the virtual addresses mapped by create_pagetables(). + */ + virtual_avail = (vm_offset_t)KERNBASE + round_2mpage(KERNend); virtual_end = VM_MAX_KERNEL_ADDRESS; /*