From owner-dev-commits-src-branches@freebsd.org Tue Sep 7 12:09:35 2021 Return-Path: Delivered-To: dev-commits-src-branches@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id E790A662604; Tue, 7 Sep 2021 12:09:35 +0000 (UTC) (envelope-from git@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) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4H3kbM4nvNz4rgc; Tue, 7 Sep 2021 12:09:35 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 7B16612601; Tue, 7 Sep 2021 12:09:35 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 187C9ZkU087101; Tue, 7 Sep 2021 12:09:35 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 187C9ZeD087100; Tue, 7 Sep 2021 12:09:35 GMT (envelope-from git) Date: Tue, 7 Sep 2021 12:09:35 GMT Message-Id: <202109071209.187C9ZeD087100@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Jessica Clarke Subject: git: 3ac63c72714c - stable/13 - riscv: Fix pindex level confusion MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jrtc27 X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 3ac63c72714c96a775ecce37d4ed1a883f2117cb Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-branches@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commits to the stable branches of the FreeBSD src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 07 Sep 2021 12:09:36 -0000 The branch stable/13 has been updated by jrtc27: URL: https://cgit.FreeBSD.org/src/commit/?id=3ac63c72714c96a775ecce37d4ed1a883f2117cb commit 3ac63c72714c96a775ecce37d4ed1a883f2117cb Author: Jessica Clarke AuthorDate: 2021-07-21 01:47:01 +0000 Commit: Jessica Clarke CommitDate: 2021-09-07 12:06:46 +0000 riscv: Fix pindex level confusion The pindex values are assigned from the L3 leaves upwards, meaning there are NUL2E L3 tables and then NUL1E L2 tables (with a futher NUL0E L1 tables in future when we implement Sv48 support). Therefore anything below NUL2E is an L3 table's page and anything above or equal to NUL2E is an L2 table's page (with the threshold of NUL2E + NUL1E marking the start of the L1 tables' pages in Sv48). Thus all the comparisons and arithmetic operations must use NUL2E to handle the L3/L2 allocation (and thus L2/L1 entry) transition point, not NUL1E as all but pmap_alloc_l2 were doing. To make matters confusing, the NUL1E and NUL2E definitions in the RISC-V pmap are based on a 4-level page hierarchy but we currently use the 3-level Sv39 format (as that's the only required one, and hardware support for the 4-level Sv48 is not widespread). This means that, in effect, the above bug cancels out with the bloated NULxE definitions such that things "work" (but are still technically wrong, and thus would break when adding Sv48 support), with one exception. pmap_enter_l2 is currently the only function to use the correct constant, but since _pmap_alloc_l3 uses the incorrect constant, it will do complete nonsense when it needs to allocate a new L2 table (which is rather rare). In this instance, _pmap_alloc_l3, whilst it would correctly determine the pindex was for an L2 table, would only subtract NUL1E when computing l1index and thus go way out of bounds (by 511*512*512 bytes, or 127.75 GiB) of its own L1 table and, thanks to pmap_distribute_l1, of every other pmap's L1 table in the whole system. This has likely never been hit as it would presumably instantly fault and panic. Reviewed by: markj MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D31087 (cherry picked from commit ade2ea3c459ac1c2a7f44ce56b8999e6ffef08bf) --- sys/riscv/riscv/pmap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/riscv/riscv/pmap.c b/sys/riscv/riscv/pmap.c index 9fd66f093d5e..93e9525963f7 100644 --- a/sys/riscv/riscv/pmap.c +++ b/sys/riscv/riscv/pmap.c @@ -1132,7 +1132,7 @@ _pmap_unwire_ptp(pmap_t pmap, vm_offset_t va, vm_page_t m, struct spglist *free) vm_paddr_t phys; PMAP_LOCK_ASSERT(pmap, MA_OWNED); - if (m->pindex >= NUL1E) { + if (m->pindex >= NUL2E) { pd_entry_t *l1; l1 = pmap_l1(pmap, va); pmap_clear(l1); @@ -1143,7 +1143,7 @@ _pmap_unwire_ptp(pmap_t pmap, vm_offset_t va, vm_page_t m, struct spglist *free) pmap_clear(l2); } pmap_resident_count_dec(pmap, 1); - if (m->pindex < NUL1E) { + if (m->pindex < NUL2E) { pd_entry_t *l1; vm_page_t pdpg; @@ -1279,11 +1279,11 @@ _pmap_alloc_l3(pmap_t pmap, vm_pindex_t ptepindex, struct rwlock **lockp) * it isn't already there. */ - if (ptepindex >= NUL1E) { + if (ptepindex >= NUL2E) { pd_entry_t *l1; vm_pindex_t l1index; - l1index = ptepindex - NUL1E; + l1index = ptepindex - NUL2E; l1 = &pmap->pm_l1[l1index]; KASSERT((pmap_load(l1) & PTE_V) == 0, ("%s: L1 entry %#lx is valid", __func__, pmap_load(l1))); @@ -1301,7 +1301,7 @@ _pmap_alloc_l3(pmap_t pmap, vm_pindex_t ptepindex, struct rwlock **lockp) l1 = &pmap->pm_l1[l1index]; if (pmap_load(l1) == 0) { /* recurse for allocating page dir */ - if (_pmap_alloc_l3(pmap, NUL1E + l1index, + if (_pmap_alloc_l3(pmap, NUL2E + l1index, lockp) == NULL) { vm_page_unwire_noq(m); vm_page_free_zero(m);