k_page_table: add new CheckMemoryState helper
This commit is contained in:
		| @@ -3280,21 +3280,16 @@ Result KPageTable::CheckMemoryStateContiguous(size_t* out_blocks_needed, KProces | |||||||
|  |  | ||||||
| Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, | Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, | ||||||
|                                     KMemoryAttribute* out_attr, size_t* out_blocks_needed, |                                     KMemoryAttribute* out_attr, size_t* out_blocks_needed, | ||||||
|                                     KProcessAddress addr, size_t size, KMemoryState state_mask, |                                     KMemoryBlockManager::const_iterator it, | ||||||
|  |                                     KProcessAddress last_addr, KMemoryState state_mask, | ||||||
|                                     KMemoryState state, KMemoryPermission perm_mask, |                                     KMemoryState state, KMemoryPermission perm_mask, | ||||||
|                                     KMemoryPermission perm, KMemoryAttribute attr_mask, |                                     KMemoryPermission perm, KMemoryAttribute attr_mask, | ||||||
|                                     KMemoryAttribute attr, KMemoryAttribute ignore_attr) const { |                                     KMemoryAttribute attr, KMemoryAttribute ignore_attr) const { | ||||||
|     ASSERT(this->IsLockedByCurrentThread()); |     ASSERT(this->IsLockedByCurrentThread()); | ||||||
|  |  | ||||||
|     // Get information about the first block. |     // Get information about the first block. | ||||||
|     const KProcessAddress last_addr = addr + size - 1; |  | ||||||
|     KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(addr); |  | ||||||
|     KMemoryInfo info = it->GetMemoryInfo(); |     KMemoryInfo info = it->GetMemoryInfo(); | ||||||
|  |  | ||||||
|     // If the start address isn't aligned, we need a block. |  | ||||||
|     const size_t blocks_for_start_align = |  | ||||||
|         (Common::AlignDown(GetInteger(addr), PageSize) != info.GetAddress()) ? 1 : 0; |  | ||||||
|  |  | ||||||
|     // Validate all blocks in the range have correct state. |     // Validate all blocks in the range have correct state. | ||||||
|     const KMemoryState first_state = info.m_state; |     const KMemoryState first_state = info.m_state; | ||||||
|     const KMemoryPermission first_perm = info.m_permission; |     const KMemoryPermission first_perm = info.m_permission; | ||||||
| @@ -3320,10 +3315,6 @@ Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* | |||||||
|         info = it->GetMemoryInfo(); |         info = it->GetMemoryInfo(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // If the end address isn't aligned, we need a block. |  | ||||||
|     const size_t blocks_for_end_align = |  | ||||||
|         (Common::AlignUp(GetInteger(addr) + size, PageSize) != info.GetEndAddress()) ? 1 : 0; |  | ||||||
|  |  | ||||||
|     // Write output state. |     // Write output state. | ||||||
|     if (out_state != nullptr) { |     if (out_state != nullptr) { | ||||||
|         *out_state = first_state; |         *out_state = first_state; | ||||||
| @@ -3334,9 +3325,39 @@ Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* | |||||||
|     if (out_attr != nullptr) { |     if (out_attr != nullptr) { | ||||||
|         *out_attr = static_cast<KMemoryAttribute>(first_attr & ~ignore_attr); |         *out_attr = static_cast<KMemoryAttribute>(first_attr & ~ignore_attr); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // If the end address isn't aligned, we need a block. | ||||||
|     if (out_blocks_needed != nullptr) { |     if (out_blocks_needed != nullptr) { | ||||||
|         *out_blocks_needed = blocks_for_start_align + blocks_for_end_align; |         const size_t blocks_for_end_align = | ||||||
|  |             (Common::AlignDown(GetInteger(last_addr), PageSize) + PageSize != info.GetEndAddress()) | ||||||
|  |                 ? 1 | ||||||
|  |                 : 0; | ||||||
|  |         *out_blocks_needed = blocks_for_end_align; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, | ||||||
|  |                                     KMemoryAttribute* out_attr, size_t* out_blocks_needed, | ||||||
|  |                                     KProcessAddress addr, size_t size, KMemoryState state_mask, | ||||||
|  |                                     KMemoryState state, KMemoryPermission perm_mask, | ||||||
|  |                                     KMemoryPermission perm, KMemoryAttribute attr_mask, | ||||||
|  |                                     KMemoryAttribute attr, KMemoryAttribute ignore_attr) const { | ||||||
|  |     ASSERT(this->IsLockedByCurrentThread()); | ||||||
|  |  | ||||||
|  |     // Check memory state. | ||||||
|  |     const KProcessAddress last_addr = addr + size - 1; | ||||||
|  |     KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(addr); | ||||||
|  |     R_TRY(this->CheckMemoryState(out_state, out_perm, out_attr, out_blocks_needed, it, last_addr, | ||||||
|  |                                  state_mask, state, perm_mask, perm, attr_mask, attr, ignore_attr)); | ||||||
|  |  | ||||||
|  |     // If the start address isn't aligned, we need a block. | ||||||
|  |     if (out_blocks_needed != nullptr && | ||||||
|  |         Common::AlignDown(GetInteger(addr), PageSize) != it->GetAddress()) { | ||||||
|  |         ++(*out_blocks_needed); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     R_SUCCEED(); |     R_SUCCEED(); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -261,6 +261,13 @@ private: | |||||||
|     Result CheckMemoryState(const KMemoryInfo& info, KMemoryState state_mask, KMemoryState state, |     Result CheckMemoryState(const KMemoryInfo& info, KMemoryState state_mask, KMemoryState state, | ||||||
|                             KMemoryPermission perm_mask, KMemoryPermission perm, |                             KMemoryPermission perm_mask, KMemoryPermission perm, | ||||||
|                             KMemoryAttribute attr_mask, KMemoryAttribute attr) const; |                             KMemoryAttribute attr_mask, KMemoryAttribute attr) const; | ||||||
|  |     Result CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, | ||||||
|  |                             KMemoryAttribute* out_attr, size_t* out_blocks_needed, | ||||||
|  |                             KMemoryBlockManager::const_iterator it, KProcessAddress last_addr, | ||||||
|  |                             KMemoryState state_mask, KMemoryState state, | ||||||
|  |                             KMemoryPermission perm_mask, KMemoryPermission perm, | ||||||
|  |                             KMemoryAttribute attr_mask, KMemoryAttribute attr, | ||||||
|  |                             KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const; | ||||||
|     Result CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, |     Result CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, | ||||||
|                             KMemoryAttribute* out_attr, size_t* out_blocks_needed, |                             KMemoryAttribute* out_attr, size_t* out_blocks_needed, | ||||||
|                             KProcessAddress addr, size_t size, KMemoryState state_mask, |                             KProcessAddress addr, size_t size, KMemoryState state_mask, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user