mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-16 06:52:27 +00:00
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
This commit is contained in:
parent
de9c000ced
commit
8d0b41b058
|
@ -7034,6 +7034,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
|
||||
|
@ -7046,15 +7070,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);
|
||||
|
|
Loading…
Reference in a new issue