forked from suyu/suyu
k_page_table: remove HACK_OpenPages/ClosePages
This commit is contained in:
parent
3392fdac9b
commit
28d9c30861
3 changed files with 54 additions and 58 deletions
|
@ -14,6 +14,7 @@
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
class KBlockInfoManager;
|
class KBlockInfoManager;
|
||||||
|
class KernelCore;
|
||||||
class KPageGroup;
|
class KPageGroup;
|
||||||
|
|
||||||
class KBlockInfo {
|
class KBlockInfo {
|
||||||
|
|
|
@ -941,9 +941,6 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add
|
||||||
|
|
||||||
ON_RESULT_FAILURE {
|
ON_RESULT_FAILURE {
|
||||||
if (cur_mapped_addr != dst_addr) {
|
if (cur_mapped_addr != dst_addr) {
|
||||||
// HACK: Manually close the pages.
|
|
||||||
HACK_ClosePages(dst_addr, (cur_mapped_addr - dst_addr) / PageSize);
|
|
||||||
|
|
||||||
ASSERT(Operate(dst_addr, (cur_mapped_addr - dst_addr) / PageSize,
|
ASSERT(Operate(dst_addr, (cur_mapped_addr - dst_addr) / PageSize,
|
||||||
KMemoryPermission::None, OperationType::Unmap)
|
KMemoryPermission::None, OperationType::Unmap)
|
||||||
.IsSuccess());
|
.IsSuccess());
|
||||||
|
@ -1019,9 +1016,6 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add
|
||||||
// Map the page.
|
// Map the page.
|
||||||
R_TRY(Operate(cur_mapped_addr, 1, test_perm, OperationType::Map, start_partial_page));
|
R_TRY(Operate(cur_mapped_addr, 1, test_perm, OperationType::Map, start_partial_page));
|
||||||
|
|
||||||
// HACK: Manually open the pages.
|
|
||||||
HACK_OpenPages(start_partial_page, 1);
|
|
||||||
|
|
||||||
// Update tracking extents.
|
// Update tracking extents.
|
||||||
cur_mapped_addr += PageSize;
|
cur_mapped_addr += PageSize;
|
||||||
cur_block_addr += PageSize;
|
cur_block_addr += PageSize;
|
||||||
|
@ -1050,9 +1044,6 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add
|
||||||
R_TRY(Operate(cur_mapped_addr, cur_block_size / PageSize, test_perm, OperationType::Map,
|
R_TRY(Operate(cur_mapped_addr, cur_block_size / PageSize, test_perm, OperationType::Map,
|
||||||
cur_block_addr));
|
cur_block_addr));
|
||||||
|
|
||||||
// HACK: Manually open the pages.
|
|
||||||
HACK_OpenPages(cur_block_addr, cur_block_size / PageSize);
|
|
||||||
|
|
||||||
// Update tracking extents.
|
// Update tracking extents.
|
||||||
cur_mapped_addr += cur_block_size;
|
cur_mapped_addr += cur_block_size;
|
||||||
cur_block_addr = next_entry.phys_addr;
|
cur_block_addr = next_entry.phys_addr;
|
||||||
|
@ -1072,9 +1063,6 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add
|
||||||
R_TRY(Operate(cur_mapped_addr, last_block_size / PageSize, test_perm, OperationType::Map,
|
R_TRY(Operate(cur_mapped_addr, last_block_size / PageSize, test_perm, OperationType::Map,
|
||||||
cur_block_addr));
|
cur_block_addr));
|
||||||
|
|
||||||
// HACK: Manually open the pages.
|
|
||||||
HACK_OpenPages(cur_block_addr, last_block_size / PageSize);
|
|
||||||
|
|
||||||
// Update tracking extents.
|
// Update tracking extents.
|
||||||
cur_mapped_addr += last_block_size;
|
cur_mapped_addr += last_block_size;
|
||||||
cur_block_addr += last_block_size;
|
cur_block_addr += last_block_size;
|
||||||
|
@ -1106,9 +1094,6 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add
|
||||||
|
|
||||||
// Map the page.
|
// Map the page.
|
||||||
R_TRY(Operate(cur_mapped_addr, 1, test_perm, OperationType::Map, end_partial_page));
|
R_TRY(Operate(cur_mapped_addr, 1, test_perm, OperationType::Map, end_partial_page));
|
||||||
|
|
||||||
// HACK: Manually open the pages.
|
|
||||||
HACK_OpenPages(end_partial_page, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update memory blocks to reflect our changes
|
// Update memory blocks to reflect our changes
|
||||||
|
@ -1210,9 +1195,6 @@ Result KPageTable::CleanupForIpcServer(VAddr address, size_t size, KMemoryState
|
||||||
const size_t aligned_size = aligned_end - aligned_start;
|
const size_t aligned_size = aligned_end - aligned_start;
|
||||||
const size_t aligned_num_pages = aligned_size / PageSize;
|
const size_t aligned_num_pages = aligned_size / PageSize;
|
||||||
|
|
||||||
// HACK: Manually close the pages.
|
|
||||||
HACK_ClosePages(aligned_start, aligned_num_pages);
|
|
||||||
|
|
||||||
// Unmap the pages.
|
// Unmap the pages.
|
||||||
R_TRY(Operate(aligned_start, aligned_num_pages, KMemoryPermission::None, OperationType::Unmap));
|
R_TRY(Operate(aligned_start, aligned_num_pages, KMemoryPermission::None, OperationType::Unmap));
|
||||||
|
|
||||||
|
@ -1500,17 +1482,6 @@ void KPageTable::CleanupForIpcClientOnServerSetupFailure([[maybe_unused]] PageLi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KPageTable::HACK_OpenPages(PAddr phys_addr, size_t num_pages) {
|
|
||||||
m_system.Kernel().MemoryManager().OpenFirst(phys_addr, num_pages);
|
|
||||||
}
|
|
||||||
|
|
||||||
void KPageTable::HACK_ClosePages(VAddr virt_addr, size_t num_pages) {
|
|
||||||
for (size_t index = 0; index < num_pages; ++index) {
|
|
||||||
const auto paddr = GetPhysicalAddr(virt_addr + (index * PageSize));
|
|
||||||
m_system.Kernel().MemoryManager().Close(paddr, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) {
|
Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) {
|
||||||
// Lock the physical memory lock.
|
// Lock the physical memory lock.
|
||||||
KScopedLightLock phys_lk(m_map_physical_memory_lock);
|
KScopedLightLock phys_lk(m_map_physical_memory_lock);
|
||||||
|
@ -1679,9 +1650,6 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) {
|
||||||
last_unmap_address + 1 - cur_address) /
|
last_unmap_address + 1 - cur_address) /
|
||||||
PageSize;
|
PageSize;
|
||||||
|
|
||||||
// HACK: Manually close the pages.
|
|
||||||
HACK_ClosePages(cur_address, cur_pages);
|
|
||||||
|
|
||||||
// Unmap.
|
// Unmap.
|
||||||
ASSERT(Operate(cur_address, cur_pages, KMemoryPermission::None,
|
ASSERT(Operate(cur_address, cur_pages, KMemoryPermission::None,
|
||||||
OperationType::Unmap)
|
OperationType::Unmap)
|
||||||
|
@ -1741,10 +1709,7 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) {
|
||||||
// Map whatever we can.
|
// Map whatever we can.
|
||||||
const size_t cur_pages = std::min(pg_pages, map_pages);
|
const size_t cur_pages = std::min(pg_pages, map_pages);
|
||||||
R_TRY(Operate(cur_address, cur_pages, KMemoryPermission::UserReadWrite,
|
R_TRY(Operate(cur_address, cur_pages, KMemoryPermission::UserReadWrite,
|
||||||
OperationType::Map, pg_phys_addr));
|
OperationType::MapFirst, pg_phys_addr));
|
||||||
|
|
||||||
// HACK: Manually open the pages.
|
|
||||||
HACK_OpenPages(pg_phys_addr, cur_pages);
|
|
||||||
|
|
||||||
// Advance.
|
// Advance.
|
||||||
cur_address += cur_pages * PageSize;
|
cur_address += cur_pages * PageSize;
|
||||||
|
@ -1887,9 +1852,6 @@ Result KPageTable::UnmapPhysicalMemory(VAddr address, size_t size) {
|
||||||
last_address + 1 - cur_address) /
|
last_address + 1 - cur_address) /
|
||||||
PageSize;
|
PageSize;
|
||||||
|
|
||||||
// HACK: Manually close the pages.
|
|
||||||
HACK_ClosePages(cur_address, cur_pages);
|
|
||||||
|
|
||||||
// Unmap.
|
// Unmap.
|
||||||
ASSERT(Operate(cur_address, cur_pages, KMemoryPermission::None, OperationType::Unmap)
|
ASSERT(Operate(cur_address, cur_pages, KMemoryPermission::None, OperationType::Unmap)
|
||||||
.IsSuccess());
|
.IsSuccess());
|
||||||
|
@ -2609,11 +2571,23 @@ ResultVal<VAddr> KPageTable::AllocateAndMapMemory(size_t needed_num_pages, size_
|
||||||
if (is_map_only) {
|
if (is_map_only) {
|
||||||
R_TRY(Operate(addr, needed_num_pages, perm, OperationType::Map, map_addr));
|
R_TRY(Operate(addr, needed_num_pages, perm, OperationType::Map, map_addr));
|
||||||
} else {
|
} else {
|
||||||
KPageGroup page_group{m_kernel, m_block_info_manager};
|
// Create a page group tohold the pages we allocate.
|
||||||
R_TRY(m_system.Kernel().MemoryManager().AllocateForProcess(
|
KPageGroup pg{m_kernel, m_block_info_manager};
|
||||||
&page_group, needed_num_pages,
|
|
||||||
KMemoryManager::EncodeOption(m_memory_pool, m_allocation_option), 0, 0));
|
R_TRY(m_system.Kernel().MemoryManager().AllocateAndOpen(
|
||||||
R_TRY(Operate(addr, needed_num_pages, page_group, OperationType::MapGroup));
|
&pg, needed_num_pages,
|
||||||
|
KMemoryManager::EncodeOption(m_memory_pool, m_allocation_option)));
|
||||||
|
|
||||||
|
// Ensure that the page group is closed when we're done working with it.
|
||||||
|
SCOPE_EXIT({ pg.Close(); });
|
||||||
|
|
||||||
|
// Clear all pages.
|
||||||
|
for (const auto& it : pg) {
|
||||||
|
std::memset(m_system.DeviceMemory().GetPointer<void>(it.GetAddress()),
|
||||||
|
m_heap_fill_value, it.GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
R_TRY(Operate(addr, needed_num_pages, pg, OperationType::MapGroup));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the blocks.
|
// Update the blocks.
|
||||||
|
@ -2794,19 +2768,28 @@ Result KPageTable::Operate(VAddr addr, size_t num_pages, const KPageGroup& page_
|
||||||
ASSERT(num_pages > 0);
|
ASSERT(num_pages > 0);
|
||||||
ASSERT(num_pages == page_group.GetNumPages());
|
ASSERT(num_pages == page_group.GetNumPages());
|
||||||
|
|
||||||
for (const auto& node : page_group) {
|
switch (operation) {
|
||||||
const size_t size{node.GetNumPages() * PageSize};
|
case OperationType::MapGroup: {
|
||||||
|
// We want to maintain a new reference to every page in the group.
|
||||||
|
KScopedPageGroup spg(page_group);
|
||||||
|
|
||||||
switch (operation) {
|
for (const auto& node : page_group) {
|
||||||
case OperationType::MapGroup:
|
const size_t size{node.GetNumPages() * PageSize};
|
||||||
|
|
||||||
|
// Map the pages.
|
||||||
m_system.Memory().MapMemoryRegion(*m_page_table_impl, addr, size, node.GetAddress());
|
m_system.Memory().MapMemoryRegion(*m_page_table_impl, addr, size, node.GetAddress());
|
||||||
break;
|
|
||||||
default:
|
addr += size;
|
||||||
ASSERT(false);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addr += size;
|
// We succeeded! We want to persist the reference to the pages.
|
||||||
|
spg.CancelClose();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
ASSERT(false);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
|
@ -2821,13 +2804,29 @@ Result KPageTable::Operate(VAddr addr, size_t num_pages, KMemoryPermission perm,
|
||||||
ASSERT(ContainsPages(addr, num_pages));
|
ASSERT(ContainsPages(addr, num_pages));
|
||||||
|
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case OperationType::Unmap:
|
case OperationType::Unmap: {
|
||||||
|
// Ensure that any pages we track close on exit.
|
||||||
|
KPageGroup pages_to_close{m_kernel, this->GetBlockInfoManager()};
|
||||||
|
SCOPE_EXIT({ pages_to_close.CloseAndReset(); });
|
||||||
|
|
||||||
|
this->AddRegionToPages(addr, num_pages, pages_to_close);
|
||||||
m_system.Memory().UnmapRegion(*m_page_table_impl, addr, num_pages * PageSize);
|
m_system.Memory().UnmapRegion(*m_page_table_impl, addr, num_pages * PageSize);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case OperationType::MapFirst:
|
||||||
case OperationType::Map: {
|
case OperationType::Map: {
|
||||||
ASSERT(map_addr);
|
ASSERT(map_addr);
|
||||||
ASSERT(Common::IsAligned(map_addr, PageSize));
|
ASSERT(Common::IsAligned(map_addr, PageSize));
|
||||||
m_system.Memory().MapMemoryRegion(*m_page_table_impl, addr, num_pages * PageSize, map_addr);
|
m_system.Memory().MapMemoryRegion(*m_page_table_impl, addr, num_pages * PageSize, map_addr);
|
||||||
|
|
||||||
|
// Open references to pages, if we should.
|
||||||
|
if (IsHeapPhysicalAddress(m_kernel.MemoryLayout(), map_addr)) {
|
||||||
|
if (operation == OperationType::MapFirst) {
|
||||||
|
m_kernel.MemoryManager().OpenFirst(map_addr, num_pages);
|
||||||
|
} else {
|
||||||
|
m_kernel.MemoryManager().Open(map_addr, num_pages);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OperationType::Separate: {
|
case OperationType::Separate: {
|
||||||
|
|
|
@ -265,10 +265,6 @@ private:
|
||||||
void CleanupForIpcClientOnServerSetupFailure(PageLinkedList* page_list, VAddr address,
|
void CleanupForIpcClientOnServerSetupFailure(PageLinkedList* page_list, VAddr address,
|
||||||
size_t size, KMemoryPermission prot_perm);
|
size_t size, KMemoryPermission prot_perm);
|
||||||
|
|
||||||
// HACK: These will be removed once we automatically manage page reference counts.
|
|
||||||
void HACK_OpenPages(PAddr phys_addr, size_t num_pages);
|
|
||||||
void HACK_ClosePages(VAddr virt_addr, size_t num_pages);
|
|
||||||
|
|
||||||
mutable KLightLock m_general_lock;
|
mutable KLightLock m_general_lock;
|
||||||
mutable KLightLock m_map_physical_memory_lock;
|
mutable KLightLock m_map_physical_memory_lock;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue