diff options
author | Mark Johnston <markj@FreeBSD.org> | 2021-06-06 20:40:45 +0000 |
---|---|---|
committer | Mark Johnston <markj@FreeBSD.org> | 2021-06-06 20:44:46 +0000 |
commit | 4e4035ef1fb5e2f9da6b658ffae8a54862b4d018 (patch) | |
tree | 8274ff8e70e56211bd2ed26f0bbd84674499cf69 | |
parent | a48f51b3d396664f9b0a91f016159f4e4324da85 (diff) | |
download | src-4e4035ef1fb5e2f9da6b658ffae8a54862b4d018.tar.gz src-4e4035ef1fb5e2f9da6b658ffae8a54862b4d018.zip |
arm64: Fix pmap_copy()'s handling of 2MB mappings
When copying mappings from parent to child, we clear the accessed and
dirty bits. This is done for both 4KB and 2MB PTEs. However,
pmap_demote_l2() asserts that writable superpages must be dirty. This
is to avoid races with the MMU setting the dirty bit during promotion
and demotion. pmap_copy() can create clean, writable superpage
mappings, so it violates this assertion.
Modify pmap_copy() to preserve the accessed and dirty bits when copying
2MB mappings, like we do on amd64.
Fixes: ca2cae0b4dd
Reported by: Jenkins via mhorne
Reviewed by: alc, kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D30643
-rw-r--r-- | sys/arm64/arm64/pmap.c | 7 |
1 files changed, 2 insertions, 5 deletions
diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c index c26c3d8fce17..ffc83be852bd 100644 --- a/sys/arm64/arm64/pmap.c +++ b/sys/arm64/arm64/pmap.c @@ -4573,11 +4573,8 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len, ((srcptepaddr & ATTR_SW_MANAGED) == 0 || pmap_pv_insert_l2(dst_pmap, addr, srcptepaddr, PMAP_ENTER_NORECLAIM, &lock))) { - mask = ATTR_AF | ATTR_SW_WIRED; - nbits = 0; - if ((srcptepaddr & ATTR_SW_DBM) != 0) - nbits |= ATTR_S1_AP_RW_BIT; - pmap_store(l2, (srcptepaddr & ~mask) | nbits); + mask = ATTR_SW_WIRED; + pmap_store(l2, srcptepaddr & ~mask); pmap_resident_count_inc(dst_pmap, L2_SIZE / PAGE_SIZE); atomic_add_long(&pmap_l2_mappings, 1); |