kern: update for new ChangePermissions page table operation

This commit is contained in:
Michael Scire 2023-02-21 08:39:21 -07:00 committed by SciresM
parent bff61c68ab
commit 6e2dd791b2
4 changed files with 18 additions and 15 deletions

View file

@ -216,7 +216,7 @@ namespace ams::kern::arch::arm64 {
ALWAYS_INLINE Result SeparatePagesImpl(KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll); ALWAYS_INLINE Result SeparatePagesImpl(KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll);
Result SeparatePages(KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll); Result SeparatePages(KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll);
Result ChangePermissions(KProcessAddress virt_addr, size_t num_pages, PageTableEntry entry_template, DisableMergeAttribute disable_merge_attr, bool refresh_mapping, PageLinkedList *page_list, bool reuse_ll); Result ChangePermissions(KProcessAddress virt_addr, size_t num_pages, PageTableEntry entry_template, DisableMergeAttribute disable_merge_attr, bool refresh_mapping, bool flush_mapping, PageLinkedList *page_list, bool reuse_ll);
static ALWAYS_INLINE void PteDataMemoryBarrier() { static ALWAYS_INLINE void PteDataMemoryBarrier() {
cpu::DataMemoryBarrierInnerShareableStore(); cpu::DataMemoryBarrierInnerShareableStore();

View file

@ -72,13 +72,14 @@ namespace ams::kern {
}; };
enum OperationType { enum OperationType {
OperationType_Map = 0, OperationType_Map = 0,
OperationType_MapFirst = 1, OperationType_MapFirst = 1,
OperationType_MapGroup = 2, OperationType_MapGroup = 2,
OperationType_Unmap = 3, OperationType_Unmap = 3,
OperationType_ChangePermissions = 4, OperationType_ChangePermissions = 4,
OperationType_ChangePermissionsAndRefresh = 5, OperationType_ChangePermissionsAndRefresh = 5,
OperationType_Separate = 6, OperationType_ChangePermissionsAndRefreshAndFlush = 6,
OperationType_Separate = 7,
}; };
static constexpr size_t MaxPhysicalMapAlignment = 1_GB; static constexpr size_t MaxPhysicalMapAlignment = 1_GB;

View file

@ -378,9 +378,11 @@ namespace ams::kern::arch::arm64 {
case OperationType_MapFirst: case OperationType_MapFirst:
R_RETURN(this->MapContiguous(virt_addr, phys_addr, num_pages, entry_template, properties.disable_merge_attributes == DisableMergeAttribute_DisableHead, operation != OperationType_MapFirst, page_list, reuse_ll)); R_RETURN(this->MapContiguous(virt_addr, phys_addr, num_pages, entry_template, properties.disable_merge_attributes == DisableMergeAttribute_DisableHead, operation != OperationType_MapFirst, page_list, reuse_ll));
case OperationType_ChangePermissions: case OperationType_ChangePermissions:
R_RETURN(this->ChangePermissions(virt_addr, num_pages, entry_template, properties.disable_merge_attributes, false, page_list, reuse_ll)); R_RETURN(this->ChangePermissions(virt_addr, num_pages, entry_template, properties.disable_merge_attributes, false, false, page_list, reuse_ll));
case OperationType_ChangePermissionsAndRefresh: case OperationType_ChangePermissionsAndRefresh:
R_RETURN(this->ChangePermissions(virt_addr, num_pages, entry_template, properties.disable_merge_attributes, true, page_list, reuse_ll)); R_RETURN(this->ChangePermissions(virt_addr, num_pages, entry_template, properties.disable_merge_attributes, true, false, page_list, reuse_ll));
case OperationType_ChangePermissionsAndRefreshAndFlush:
R_RETURN(this->ChangePermissions(virt_addr, num_pages, entry_template, properties.disable_merge_attributes, true, true, page_list, reuse_ll));
MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); MESOSPHERE_UNREACHABLE_DEFAULT_CASE();
} }
} }
@ -1233,7 +1235,7 @@ namespace ams::kern::arch::arm64 {
R_RETURN(this->SeparatePagesImpl(virt_addr, block_size, page_list, reuse_ll)); R_RETURN(this->SeparatePagesImpl(virt_addr, block_size, page_list, reuse_ll));
} }
Result KPageTable::ChangePermissions(KProcessAddress virt_addr, size_t num_pages, PageTableEntry entry_template, DisableMergeAttribute disable_merge_attr, bool refresh_mapping, PageLinkedList *page_list, bool reuse_ll) { Result KPageTable::ChangePermissions(KProcessAddress virt_addr, size_t num_pages, PageTableEntry entry_template, DisableMergeAttribute disable_merge_attr, bool refresh_mapping, bool flush_mapping, PageLinkedList *page_list, bool reuse_ll) {
MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); MESOSPHERE_ASSERT(this->IsLockedByCurrentThread());
/* Separate pages before we change permissions. */ /* Separate pages before we change permissions. */
@ -1451,8 +1453,8 @@ namespace ams::kern::arch::arm64 {
KScopedSchedulerLock sl; KScopedSchedulerLock sl;
} }
/* Finally, apply the changes as directed, flushing the mappings before they're applied. */ /* Finally, apply the changes as directed, flushing the mappings before they're applied (if we should). */
ApplyEntryTemplate(entry_template, ApplyOption_FlushDataCache); ApplyEntryTemplate(entry_template, flush_mapping ? ApplyOption_FlushDataCache : ApplyOption_None);
} }
/* We've succeeded, now perform what coalescing we can. */ /* We've succeeded, now perform what coalescing we can. */

View file

@ -1600,7 +1600,7 @@ namespace ams::kern {
/* Perform mapping operation. */ /* Perform mapping operation. */
const KPageProperties properties = { new_perm, false, false, DisableMergeAttribute_None }; const KPageProperties properties = { new_perm, false, false, DisableMergeAttribute_None };
const auto operation = was_x ? OperationType_ChangePermissionsAndRefresh : OperationType_ChangePermissions; const auto operation = was_x ? OperationType_ChangePermissionsAndRefreshAndFlush : OperationType_ChangePermissions;
R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, Null<KPhysicalAddress>, false, properties, operation, false)); R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, Null<KPhysicalAddress>, false, properties, operation, false));
/* Update the blocks. */ /* Update the blocks. */
@ -1649,7 +1649,7 @@ namespace ams::kern {
/* Perform operation. */ /* Perform operation. */
const KPageProperties properties = { old_perm, false, (new_attr & KMemoryAttribute_Uncached) != 0, DisableMergeAttribute_None }; const KPageProperties properties = { old_perm, false, (new_attr & KMemoryAttribute_Uncached) != 0, DisableMergeAttribute_None };
R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, Null<KPhysicalAddress>, false, properties, OperationType_ChangePermissionsAndRefresh, false)); R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, Null<KPhysicalAddress>, false, properties, OperationType_ChangePermissionsAndRefreshAndFlush, false));
/* Update the blocks. */ /* Update the blocks. */
m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, old_state, old_perm, new_attr, KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_None); m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, old_state, old_perm, new_attr, KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_None);