mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
kern: update UnmapIoRegion for new Mapping_Memory handling
This commit is contained in:
parent
c058376b3b
commit
8ffc177b44
4 changed files with 28 additions and 7 deletions
|
@ -98,8 +98,8 @@ namespace ams::kern::arch::arm64 {
|
||||||
R_RETURN(m_page_table.MapIoRegion(dst_address, phys_addr, size, mapping, perm));
|
R_RETURN(m_page_table.MapIoRegion(dst_address, phys_addr, size, mapping, perm));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result UnmapIoRegion(KProcessAddress dst_address, KPhysicalAddress phys_addr, size_t size) {
|
Result UnmapIoRegion(KProcessAddress dst_address, KPhysicalAddress phys_addr, size_t size, ams::svc::MemoryMapping mapping) {
|
||||||
R_RETURN(m_page_table.UnmapIoRegion(dst_address, phys_addr, size));
|
R_RETURN(m_page_table.UnmapIoRegion(dst_address, phys_addr, size, mapping));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result MapStatic(KPhysicalAddress phys_addr, size_t size, KMemoryPermission perm) {
|
Result MapStatic(KPhysicalAddress phys_addr, size_t size, KMemoryPermission perm) {
|
||||||
|
|
|
@ -363,7 +363,7 @@ namespace ams::kern {
|
||||||
Result UnmapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size);
|
Result UnmapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size);
|
||||||
Result MapIo(KPhysicalAddress phys_addr, size_t size, KMemoryPermission perm);
|
Result MapIo(KPhysicalAddress phys_addr, size_t size, KMemoryPermission perm);
|
||||||
Result MapIoRegion(KProcessAddress dst_address, KPhysicalAddress phys_addr, size_t size, ams::svc::MemoryMapping mapping, ams::svc::MemoryPermission perm);
|
Result MapIoRegion(KProcessAddress dst_address, KPhysicalAddress phys_addr, size_t size, ams::svc::MemoryMapping mapping, ams::svc::MemoryPermission perm);
|
||||||
Result UnmapIoRegion(KProcessAddress dst_address, KPhysicalAddress phys_addr, size_t size);
|
Result UnmapIoRegion(KProcessAddress dst_address, KPhysicalAddress phys_addr, size_t size, ams::svc::MemoryMapping mapping);
|
||||||
Result MapStatic(KPhysicalAddress phys_addr, size_t size, KMemoryPermission perm);
|
Result MapStatic(KPhysicalAddress phys_addr, size_t size, KMemoryPermission perm);
|
||||||
Result MapRegion(KMemoryRegionType region_type, KMemoryPermission perm);
|
Result MapRegion(KMemoryRegionType region_type, KMemoryPermission perm);
|
||||||
Result MapInsecureMemory(KProcessAddress address, size_t size);
|
Result MapInsecureMemory(KProcessAddress address, size_t size);
|
||||||
|
|
|
@ -85,7 +85,7 @@ namespace ams::kern {
|
||||||
KScopedLightLock lk(m_lock);
|
KScopedLightLock lk(m_lock);
|
||||||
|
|
||||||
/* Unmap ourselves. */
|
/* Unmap ourselves. */
|
||||||
R_TRY(GetCurrentProcess().GetPageTable().UnmapIoRegion(address, m_physical_address, size));
|
R_TRY(GetCurrentProcess().GetPageTable().UnmapIoRegion(address, m_physical_address, size, m_mapping));
|
||||||
|
|
||||||
/* Remove ourselves from the current process. */
|
/* Remove ourselves from the current process. */
|
||||||
GetCurrentProcess().RemoveIoRegion(this);
|
GetCurrentProcess().RemoveIoRegion(this);
|
||||||
|
|
|
@ -2019,15 +2019,22 @@ namespace ams::kern {
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KPageTableBase::UnmapIoRegion(KProcessAddress dst_address, KPhysicalAddress phys_addr, size_t size) {
|
Result KPageTableBase::UnmapIoRegion(KProcessAddress dst_address, KPhysicalAddress phys_addr, size_t size, ams::svc::MemoryMapping mapping) {
|
||||||
const size_t num_pages = size / PageSize;
|
const size_t num_pages = size / PageSize;
|
||||||
|
|
||||||
/* Lock the table. */
|
/* Lock the table. */
|
||||||
KScopedLightLock lk(m_general_lock);
|
KScopedLightLock lk(m_general_lock);
|
||||||
|
|
||||||
/* Validate the memory state. */
|
/* Validate the memory state. */
|
||||||
|
KMemoryState old_state;
|
||||||
|
KMemoryPermission old_perm;
|
||||||
|
KMemoryAttribute old_attr;
|
||||||
size_t num_allocator_blocks;
|
size_t num_allocator_blocks;
|
||||||
R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), dst_address, size, KMemoryState_All, KMemoryState_Io, KMemoryPermission_None, KMemoryPermission_None, KMemoryAttribute_All, KMemoryAttribute_Locked));
|
R_TRY(this->CheckMemoryState(std::addressof(old_state), std::addressof(old_perm), std::addressof(old_attr), std::addressof(num_allocator_blocks),
|
||||||
|
dst_address, size,
|
||||||
|
KMemoryState_All, KMemoryState_Io,
|
||||||
|
KMemoryPermission_None, KMemoryPermission_None,
|
||||||
|
KMemoryAttribute_All, KMemoryAttribute_Locked));
|
||||||
|
|
||||||
/* Validate that the region being unmapped corresponds to the physical range described. */
|
/* Validate that the region being unmapped corresponds to the physical range described. */
|
||||||
{
|
{
|
||||||
|
@ -2060,9 +2067,23 @@ namespace ams::kern {
|
||||||
/* We're going to perform an update, so create a helper. */
|
/* We're going to perform an update, so create a helper. */
|
||||||
KScopedPageTableUpdater updater(this);
|
KScopedPageTableUpdater updater(this);
|
||||||
|
|
||||||
|
/* If the region being unmapped is Memory, synchronize. */
|
||||||
|
if (mapping == ams::svc::MemoryMapping_Memory) {
|
||||||
|
/* Change the region to be uncached. */
|
||||||
|
const KPageProperties properties = { old_perm, false, true, DisableMergeAttribute_None };
|
||||||
|
MESOSPHERE_R_ABORT_UNLESS(this->Operate(updater.GetPageList(), dst_address, num_pages, Null<KPhysicalAddress>, false, properties, OperationType_ChangePermissionsAndRefresh, false));
|
||||||
|
|
||||||
|
/* Temporarily unlock ourselves, so that other operations can occur while we flush the region. */
|
||||||
|
m_general_lock.Unlock();
|
||||||
|
ON_SCOPE_EXIT { m_general_lock.Lock(); };
|
||||||
|
|
||||||
|
/* Flush the region. */
|
||||||
|
MESOSPHERE_R_ABORT_UNLESS(cpu::FlushDataCache(GetVoidPointer(dst_address), size));
|
||||||
|
}
|
||||||
|
|
||||||
/* Perform the unmap. */
|
/* Perform the unmap. */
|
||||||
const KPageProperties unmap_properties = { KMemoryPermission_None, false, false, DisableMergeAttribute_None };
|
const KPageProperties unmap_properties = { KMemoryPermission_None, false, false, DisableMergeAttribute_None };
|
||||||
R_TRY(this->Operate(updater.GetPageList(), dst_address, num_pages, Null<KPhysicalAddress>, false, unmap_properties, OperationType_Unmap, false));
|
MESOSPHERE_R_ABORT_UNLESS(this->Operate(updater.GetPageList(), dst_address, num_pages, Null<KPhysicalAddress>, false, unmap_properties, OperationType_Unmap, false));
|
||||||
|
|
||||||
/* Update the blocks. */
|
/* Update the blocks. */
|
||||||
m_memory_block_manager.Update(std::addressof(allocator), dst_address, num_pages, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None, KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_Normal);
|
m_memory_block_manager.Update(std::addressof(allocator), dst_address, num_pages, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None, KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_Normal);
|
||||||
|
|
Loading…
Reference in a new issue