Date: Tue, 7 Sep 2021 12:09:45 GMT From: Jessica Clarke <jrtc27@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 2e3c6024a476 - stable/13 - riscv: Fix pmap_kextract racing with concurrent superpage promotion/demotion Message-ID: <202109071209.187C9ju2087329@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by jrtc27: URL: https://cgit.FreeBSD.org/src/commit/?id=2e3c6024a476f622e43e68243445168aa40a8d8e commit 2e3c6024a476f622e43e68243445168aa40a8d8e Author: Jessica Clarke <jrtc27@FreeBSD.org> AuthorDate: 2021-07-22 19:02:14 +0000 Commit: Jessica Clarke <jrtc27@FreeBSD.org> CommitDate: 2021-09-07 12:06:49 +0000 riscv: Fix pmap_kextract racing with concurrent superpage promotion/demotion This repeats amd64's cfcbf8c6fd3b (r180498) and i386's cf3508519c5e (r202894) but for riscv; pmap_kextract must be lock-free and so it can race with superpage promotion and demotion, thus the L2 entry must only be loaded once to avoid using inconsistent state. PR: 250866 Reviewed by: markj, mhorne Tested by: David Gilbert <dgilbert@daveg.ca> MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D31253 (cherry picked from commit 4a235049082ee1cb044873ad9aff12cf73d0fd3b) --- sys/riscv/riscv/pmap.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/sys/riscv/riscv/pmap.c b/sys/riscv/riscv/pmap.c index 93e9525963f7..075a2d4e84c8 100644 --- a/sys/riscv/riscv/pmap.c +++ b/sys/riscv/riscv/pmap.c @@ -872,7 +872,7 @@ pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot) vm_paddr_t pmap_kextract(vm_offset_t va) { - pd_entry_t *l2; + pd_entry_t *l2, l2e; pt_entry_t *l3; vm_paddr_t pa; @@ -882,14 +882,23 @@ pmap_kextract(vm_offset_t va) l2 = pmap_l2(kernel_pmap, va); if (l2 == NULL) panic("pmap_kextract: No l2"); - if ((pmap_load(l2) & PTE_RX) != 0) { + l2e = pmap_load(l2); + /* + * Beware of concurrent promotion and demotion! We must + * use l2e rather than loading from l2 multiple times to + * ensure we see a consistent state, including the + * implicit load in pmap_l2_to_l3. It is, however, safe + * to use an old l2e because the L3 page is preserved by + * promotion. + */ + if ((l2e & PTE_RX) != 0) { /* superpages */ - pa = L2PTE_TO_PHYS(pmap_load(l2)); + pa = L2PTE_TO_PHYS(l2e); pa |= (va & L2_OFFSET); return (pa); } - l3 = pmap_l2_to_l3(l2, va); + l3 = pmap_l2_to_l3(&l2e, va); if (l3 == NULL) panic("pmap_kextract: No l3..."); pa = PTE_TO_PHYS(pmap_load(l3));
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202109071209.187C9ju2087329>