mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-10-30 23:49:01 -05:00 
			
		
		
		
	vm_manager: Add member function for checking a memory range adheres to certain attributes, permissions and states
This commit is contained in:
		| @@ -592,6 +592,66 @@ void VMManager::ClearPageTable() { | ||||
|               Memory::PageType::Unmapped); | ||||
| } | ||||
|  | ||||
| VMManager::CheckResults VMManager::CheckRangeState(VAddr address, u64 size, MemoryState state_mask, | ||||
|                                                    MemoryState state, VMAPermission permission_mask, | ||||
|                                                    VMAPermission permissions, | ||||
|                                                    MemoryAttribute attribute_mask, | ||||
|                                                    MemoryAttribute attribute, | ||||
|                                                    MemoryAttribute ignore_mask) const { | ||||
|     auto iter = FindVMA(address); | ||||
|  | ||||
|     // If we don't have a valid VMA handle at this point, then it means this is | ||||
|     // being called with an address outside of the address space, which is definitely | ||||
|     // indicative of a bug, as this function only operates on mapped memory regions. | ||||
|     DEBUG_ASSERT(IsValidHandle(iter)); | ||||
|  | ||||
|     const VAddr end_address = address + size - 1; | ||||
|     const MemoryAttribute initial_attributes = iter->second.attribute; | ||||
|     const VMAPermission initial_permissions = iter->second.permissions; | ||||
|     const MemoryState initial_state = iter->second.state; | ||||
|  | ||||
|     while (true) { | ||||
|         // The iterator should be valid throughout the traversal. Hitting the end of | ||||
|         // the mapped VMA regions is unquestionably indicative of a bug. | ||||
|         DEBUG_ASSERT(IsValidHandle(iter)); | ||||
|  | ||||
|         const auto& vma = iter->second; | ||||
|  | ||||
|         if (vma.state != initial_state) { | ||||
|             return ERR_INVALID_ADDRESS_STATE; | ||||
|         } | ||||
|  | ||||
|         if ((vma.state & state_mask) != state) { | ||||
|             return ERR_INVALID_ADDRESS_STATE; | ||||
|         } | ||||
|  | ||||
|         if (vma.permissions != initial_permissions) { | ||||
|             return ERR_INVALID_ADDRESS_STATE; | ||||
|         } | ||||
|  | ||||
|         if ((vma.permissions & permission_mask) != permissions) { | ||||
|             return ERR_INVALID_ADDRESS_STATE; | ||||
|         } | ||||
|  | ||||
|         if ((vma.attribute | ignore_mask) != (initial_attributes | ignore_mask)) { | ||||
|             return ERR_INVALID_ADDRESS_STATE; | ||||
|         } | ||||
|  | ||||
|         if ((vma.attribute & attribute_mask) != attribute) { | ||||
|             return ERR_INVALID_ADDRESS_STATE; | ||||
|         } | ||||
|  | ||||
|         if (end_address <= vma.EndAddress()) { | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|         ++iter; | ||||
|     } | ||||
|  | ||||
|     return MakeResult( | ||||
|         std::make_tuple(initial_state, initial_permissions, initial_attributes & ~ignore_mask)); | ||||
| } | ||||
|  | ||||
| u64 VMManager::GetTotalMemoryUsage() const { | ||||
|     LOG_WARNING(Kernel, "(STUBBED) called"); | ||||
|     return 0xF8000000; | ||||
|   | ||||
| @@ -6,6 +6,7 @@ | ||||
|  | ||||
| #include <map> | ||||
| #include <memory> | ||||
| #include <tuple> | ||||
| #include <vector> | ||||
| #include "common/common_types.h" | ||||
| #include "core/hle/result.h" | ||||
| @@ -256,6 +257,16 @@ struct PageInfo { | ||||
|  * also backed by a single host memory allocation. | ||||
|  */ | ||||
| struct VirtualMemoryArea { | ||||
|     /// Gets the starting (base) address of this VMA. | ||||
|     VAddr StartAddress() const { | ||||
|         return base; | ||||
|     } | ||||
|  | ||||
|     /// Gets the ending address of this VMA. | ||||
|     VAddr EndAddress() const { | ||||
|         return base + size - 1; | ||||
|     } | ||||
|  | ||||
|     /// Virtual base address of the region. | ||||
|     VAddr base = 0; | ||||
|     /// Size of the region. | ||||
| @@ -517,6 +528,35 @@ private: | ||||
|     /// Clears out the page table | ||||
|     void ClearPageTable(); | ||||
|  | ||||
|     using CheckResults = ResultVal<std::tuple<MemoryState, VMAPermission, MemoryAttribute>>; | ||||
|  | ||||
|     /// Checks if an address range adheres to the specified states provided. | ||||
|     /// | ||||
|     /// @param address         The starting address of the address range. | ||||
|     /// @param size            The size of the address range. | ||||
|     /// @param state_mask      The memory state mask. | ||||
|     /// @param state           The state to compare the individual VMA states against, | ||||
|     ///                        which is done in the form of: (vma.state & state_mask) != state. | ||||
|     /// @param permission_mask The memory permissions mask. | ||||
|     /// @param permissions     The permission to compare the individual VMA permissions against, | ||||
|     ///                        which is done in the form of: | ||||
|     ///                        (vma.permission & permission_mask) != permission. | ||||
|     /// @param attribute_mask  The memory attribute mask. | ||||
|     /// @param attribute       The memory attributes to compare the individual VMA attributes | ||||
|     ///                        against, which is done in the form of: | ||||
|     ///                        (vma.attributes & attribute_mask) != attribute. | ||||
|     /// @param ignore_mask     The memory attributes to ignore during the check. | ||||
|     /// | ||||
|     /// @returns If successful, returns a tuple containing the memory attributes | ||||
|     ///          (with ignored bits specified by ignore_mask unset), memory permissions, and | ||||
|     ///          memory state across the memory range. | ||||
|     /// @returns If not successful, returns ERR_INVALID_ADDRESS_STATE. | ||||
|     /// | ||||
|     CheckResults CheckRangeState(VAddr address, u64 size, MemoryState state_mask, MemoryState state, | ||||
|                                  VMAPermission permission_mask, VMAPermission permissions, | ||||
|                                  MemoryAttribute attribute_mask, MemoryAttribute attribute, | ||||
|                                  MemoryAttribute ignore_mask) const; | ||||
|  | ||||
|     /** | ||||
|      * A map covering the entirety of the managed address space, keyed by the `base` field of each | ||||
|      * VMA. It must always be modified by splitting or merging VMAs, so that the invariant | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Lioncash
					Lioncash