git: 886190fa267e - stable/13 - Handle table attributes in the arm64 kernel map
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 29 Dec 2021 10:39:52 UTC
The branch stable/13 has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=886190fa267ecae634481982efd4a85688b7e6fe commit 886190fa267ecae634481982efd4a85688b7e6fe Author: Andrew Turner <andrew@FreeBSD.org> AuthorDate: 2021-12-07 14:23:13 +0000 Commit: Andrew Turner <andrew@FreeBSD.org> CommitDate: 2021-12-29 10:05:59 +0000 Handle table attributes in the arm64 kernel map When getting the arm64 kernel maps sysctl we should look at the table attributes as well as the block/page attributes. These attributes are different to the last level attributes so need to be translated. The previous code assumed the table and block/page attributes are identical, however this is not the case. Handle the difference by extracting the code into new helper functions & calling them as needed based on the entry type being checked. Reviewed by: markj Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D33321 (cherry picked from commit 8d0b41b058795dcb0270ca0abcbf92289563c3ed) --- sys/arm64/arm64/pmap.c | 47 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c index 17e76c0d5a41..d4cebf6a8956 100644 --- a/sys/arm64/arm64/pmap.c +++ b/sys/arm64/arm64/pmap.c @@ -7215,6 +7215,30 @@ sysctl_kmaps_reinit(struct pmap_kernel_map_range *range, vm_offset_t va, range->attrs = attrs; } +/* Get the block/page attributes that correspond to the table attributes */ +static pt_entry_t +sysctl_kmaps_table_attrs(pd_entry_t table) +{ + pt_entry_t attrs; + + attrs = 0; + if ((table & TATTR_UXN_TABLE) != 0) + attrs |= ATTR_S1_UXN; + if ((table & TATTR_PXN_TABLE) != 0) + attrs |= ATTR_S1_PXN; + if ((table & TATTR_AP_TABLE_RO) != 0) + attrs |= ATTR_S1_AP(ATTR_S1_AP_RO); + + return (attrs); +} + +/* Read the block/page attributes we care about */ +static pt_entry_t +sysctl_kmaps_block_attrs(pt_entry_t block) +{ + return (block & (ATTR_S1_AP_MASK | ATTR_S1_XN | ATTR_S1_IDX_MASK)); +} + /* * Given a leaf PTE, derive the mapping's attributes. If they do not match * those of the current run, dump the address range and its attributes, and @@ -7227,15 +7251,22 @@ sysctl_kmaps_check(struct sbuf *sb, struct pmap_kernel_map_range *range, { pt_entry_t attrs; - attrs = l0e & (ATTR_S1_AP_MASK | ATTR_S1_XN); - attrs |= l1e & (ATTR_S1_AP_MASK | ATTR_S1_XN); - if ((l1e & ATTR_DESCR_MASK) == L1_BLOCK) - attrs |= l1e & ATTR_S1_IDX_MASK; - attrs |= l2e & (ATTR_S1_AP_MASK | ATTR_S1_XN); - if ((l2e & ATTR_DESCR_MASK) == L2_BLOCK) - attrs |= l2e & ATTR_S1_IDX_MASK; - attrs |= l3e & (ATTR_S1_AP_MASK | ATTR_S1_XN | ATTR_S1_IDX_MASK); + attrs = sysctl_kmaps_table_attrs(l0e); + + if ((l1e & ATTR_DESCR_TYPE_MASK) == ATTR_DESCR_TYPE_BLOCK) { + attrs |= sysctl_kmaps_block_attrs(l1e); + goto done; + } + attrs |= sysctl_kmaps_table_attrs(l1e); + + if ((l2e & ATTR_DESCR_TYPE_MASK) == ATTR_DESCR_TYPE_BLOCK) { + attrs |= sysctl_kmaps_block_attrs(l2e); + goto done; + } + attrs |= sysctl_kmaps_table_attrs(l2e); + attrs |= sysctl_kmaps_block_attrs(l3e); +done: if (range->sva > va || !sysctl_kmaps_match(range, attrs)) { sysctl_kmaps_dump(sb, range, va); sysctl_kmaps_reinit(range, va, attrs);