kern: fuck the KPolice^H^H^H^H^H^HPageGroups

This commit is contained in:
Michael Scire 2021-04-07 17:07:01 -07:00 committed by SciresM
parent dc7862882f
commit 96937a611d
8 changed files with 493 additions and 231 deletions

View file

@ -71,12 +71,11 @@ namespace ams::kern {
/* Lock the address space. */
KScopedLightLock lk(m_lock);
/* Lock the pages. */
KPageGroup pg(page_table->GetBlockInfoManager());
R_TRY(page_table->LockForDeviceAddressSpace(std::addressof(pg), process_address, size, ConvertToKMemoryPermission(device_perm), is_aligned));
/* Lock the page table to prevent concurrent device mapping operations. */
KScopedLightLock pt_lk = page_table->AcquireDeviceMapLock();
/* Close the pages we opened when we're done with them. */
ON_SCOPE_EXIT { pg.Close(); };
/* Lock the pages. */
R_TRY(page_table->LockForMapDeviceAddressSpace(process_address, size, ConvertToKMemoryPermission(device_perm), is_aligned));
/* Ensure that if we fail, we don't keep unmapped pages locked. */
auto unlock_guard = SCOPE_GUARD { MESOSPHERE_R_ABORT_UNLESS(page_table->UnlockForDeviceAddressSpace(process_address, size)); };
@ -87,7 +86,7 @@ namespace ams::kern {
auto mapped_size_guard = SCOPE_GUARD { *out_mapped_size = 0; };
/* Perform the mapping. */
R_TRY(m_table.Map(out_mapped_size, pg, device_address, device_perm, refresh_mappings));
R_TRY(m_table.Map(out_mapped_size, page_table, process_address, size, device_address, device_perm, refresh_mappings));
/* Ensure that we unmap the pages if we fail to update the protections. */
/* NOTE: Nintendo does not check the result of this unmap call. */
@ -113,19 +112,18 @@ namespace ams::kern {
/* Lock the address space. */
KScopedLightLock lk(m_lock);
/* Make and open a page group for the unmapped region. */
KPageGroup pg(page_table->GetBlockInfoManager());
R_TRY(page_table->MakePageGroupForUnmapDeviceAddressSpace(std::addressof(pg), process_address, size));
/* Lock the page table to prevent concurrent device mapping operations. */
KScopedLightLock pt_lk = page_table->AcquireDeviceMapLock();
/* Ensure the page group is closed on scope exit. */
ON_SCOPE_EXIT { pg.Close(); };
/* Lock the pages. */
R_TRY(page_table->LockForUnmapDeviceAddressSpace(process_address, size));
/* If we fail to unmap, we want to do a partial unlock. */
{
auto unlock_guard = SCOPE_GUARD { page_table->UnlockForDeviceAddressSpacePartialMap(process_address, size, size); };
/* Unmap. */
R_TRY(m_table.Unmap(pg, device_address));
R_TRY(m_table.Unmap(page_table, process_address, size, device_address));
unlock_guard.Cancel();
}